It’s been one of those bucket list trips to get up to Alaska to go snowboarding and although it was behind the lens and we didn’t quite get to do everything we wanted to with the world starting go crazy I am really happy to release “Passage”.


Explore Passage

While talking to Amanda who’s website I build over at Authentic Alignment Wellness we discussed how it would be nice to show off upcoming events with as little effort as possible on her end.

This requires a few steps

  • Easy event setup on the wordpress backend
  • Only the next event upcoming is shown off
  • If no events are upcoming show a default placeholder

Custom Post Type

I didn’t want events to be posts I wanted them to be events so I dropped in a custom post type into my functions.php file

function wporg_custom_post_type()
{
  register_post_type('flaxen_event',
    array(
      'labels'		=> array(
        'name'			=> __('Events'),
        'singular_name'	=> __('Events'),
      ),
      'public'			=> true,
      'has_archive'	=> true,
      'rewrite'		=> array( 'slug' => 'events' ),
    )
  );
}
add_action('init', 'wporg_custom_post_type');

Meta Dates

Custom post types are still using the classic wordpress editor so I had to add meta boxes the old way, this is a pretty big block of code so I’ll break it up into manageable chunks but this all goes into the functions.php file or a required file from it

Register the Meta Boxes

function event_date_add_post_meta_boxes() {

  add_meta_box(
    'event-date', // Unique ID
    'Event Date', // Title
    'event_date_render_metabox', // Callback function
    'flaxen_event', // post
    'normal', // Context
    'default' // Priority
  );
}
add_action( 'add_meta_boxes', 'event_date_add_post_meta_boxes' );

Defaults

function event_date_defaults() {
  return array(
    'start_date_m'	=> 'default',
    'start_date_d'	=> 'default',
    'start_date_o'	=> 'default',
    'end_date_m'	=> 'default',
    'end_date_d'	=> 'default',
    'end_date_o'	=> 'default',
  );
}

Render the meta box

function event_date_render_metabox() {
  // Variables
  global $post; // Get the current post data
  $saved = get_post_meta( $post->ID, 'event_date', true ); // Get the saved values
  $defaults = event_date_defaults(); // Get the default values
  $event_date = wp_parse_args( $saved, $defaults ); // Merge the two in case any fields don't exist in the saved data
  ?>

Create the inputs

Start with an opening and a variable for the current month

<fieldset>
    <div class="wrap">
      <?php $em = date("m"); ?> <!-- used with an if this month is -->

      <p>When does this event start.</p>

The Month

<select id="event_date[start_date_m]" name="event_date[start_date_m]">
				<!-- check if there has been a month set and its this month else if month has not been set but its currently this month then its also selected -->
				<option value="01" <?php if ( $event_date['start_date_m'] == '01' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 1) { echo "selected"; } ?>>01-Jan</option> 
				<option value="02" <?php if ( $event_date['start_date_m'] == '02' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 2) { echo "selected"; } ?>>02-Feb</option>
				<option value="03" <?php if ( $event_date['start_date_m'] == '03' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 3) { echo "selected"; } ?>>03-Mar</option>
				<option value="04" <?php if ( $event_date['start_date_m'] == '04' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 4) { echo "selected"; } ?>>04-Apr</option>
				<option value="05" <?php if ( $event_date['start_date_m'] == '05' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 5) { echo "selected"; } ?>>05-May</option>
				<option value="06" <?php if ( $event_date['start_date_m'] == '06' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 6) { echo "selected"; } ?>>06-Jun</option>
				<option value="07" <?php if ( $event_date['start_date_m'] == '07' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 7) { echo "selected"; } ?>>07-Jul</option>
				<option value="08" <?php if ( $event_date['start_date_m'] == '08' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 8) { echo "selected"; } ?>>08-Aug</option>
				<option value="09" <?php if ( $event_date['start_date_m'] == '09' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 9) { echo "selected"; } ?>>09-Sep</option>
				<option value="10" <?php if ( $event_date['start_date_m'] == '10' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 10) { echo "selected"; } ?>>10-Oct</option>
				<option value="11" <?php if ( $event_date['start_date_m'] == '11' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 11) { echo "selected"; } ?>>11-Nov</option>
				<option value="12" <?php if ( $event_date['start_date_m'] == '12' ) { echo "selected"; } elseif ( $event_date['start_date_m'] == 'default ' && $em == 12) { echo "selected"; } ?>>12-Dec</option>
			</select>

The Day and Year

<input id="event_date[start_date_d]" name="event_date[start_date_d]" type="text" size="2" maxlength="2" autocomplete="off" value="<?php if ($event_date['start_date_d'] != 'default') { echo $event_date['start_date_d']; } else { echo date("d"); } ?>">
      ,
      <input id="event_date[start_date_o]" name="event_date[start_date_o]" type="text" size="4" maxlength="4" autocomplete="off" value="<?php if ($event_date['start_date_o'] != 'default') { echo $event_date['start_date_o']; } else { echo date("o"); } ?>">
    </div>

Repeat for end dates

But then also close up with a nonce for security

<div class="wrap">
      <?php $tomorrow = date("d") + 1; ?>

      <p>When does this event finish.</p>
      <select id="event_date[end_date_m]" name="event_date[end_date_m]">
        <option value="01" <?php if ( $event_date['end_date_m'] == '01' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 1) { echo "selected"; } ?>>01-Jan</option> 
        <option value="02" <?php if ( $event_date['end_date_m'] == '02' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 2) { echo "selected"; } ?>>02-Feb</option>
        <option value="03" <?php if ( $event_date['end_date_m'] == '03' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 3) { echo "selected"; } ?>>03-Mar</option>
        <option value="04" <?php if ( $event_date['end_date_m'] == '04' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 4) { echo "selected"; } ?>>04-Apr</option>
        <option value="05" <?php if ( $event_date['end_date_m'] == '05' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 5) { echo "selected"; } ?>>05-May</option>
        <option value="06" <?php if ( $event_date['end_date_m'] == '06' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 6) { echo "selected"; } ?>>06-Jun</option>
        <option value="07" <?php if ( $event_date['end_date_m'] == '07' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 7) { echo "selected"; } ?>>07-Jul</option>
        <option value="08" <?php if ( $event_date['end_date_m'] == '08' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 8) { echo "selected"; } ?>>08-Aug</option>
        <option value="09" <?php if ( $event_date['end_date_m'] == '09' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 9) { echo "selected"; } ?>>09-Sep</option>
        <option value="10" <?php if ( $event_date['end_date_m'] == '10' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 10) { echo "selected"; } ?>>10-Oct</option>
        <option value="11" <?php if ( $event_date['end_date_m'] == '11' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 11) { echo "selected"; } ?>>11-Nov</option>
        <option value="12" <?php if ( $event_date['end_date_m'] == '12' ) { echo "selected"; } elseif ( $event_date['end_date_m'] == 'default ' && $em == 12) { echo "selected"; } ?>>12-Dec</option>
      </select>

      <input id="event_date[end_date_d]" name="event_date[end_date_d]" type="text" size="2" maxlength="2" autocomplete="off" value="<?php if ($event_date['end_date_d'] != 'default') { echo $event_date['end_date_d']; } else { echo $tomorrow; } ?>">
      ,
      <input id="event_date[end_date_o]" name="event_date[end_date_o]" type="text" size="4" maxlength="4" autocomplete="off" value="<?php if ($event_date['end_date_o'] != 'default') { echo $event_date['end_date_o']; } else { echo date("o"); } ?>">
    </div>
  </fieldset>

  ?php
  // This validates that submission came from the actual dashboard and not the front end or a remote server.
  wp_nonce_field( 'event_date_metabox_nonce', 'event_date_metabox_process' );
}

Save the Metabox

function event_date_save_metabox( $post_id, $post ) {
  // Verify that our security field exists. If not, bail.
  if ( !isset( $_POST['event_date_metabox_process'] ) ) return;
  // Verify data came from edit/dashboard screen
  if ( !wp_verify_nonce( $_POST['event_date_metabox_process'], 'event_date_metabox_nonce' ) ) {
    return $post->ID;
  }

  if ( !isset( $_POST['event_date'] ) ) {
    return $post->ID;
  }

  // Verify user has permission to edit post
  if ( !current_user_can( 'edit_post', $post->ID )) {
    return $post->ID;
  }

  $sanitized = array();
  // Loop through each of our fields
  foreach ( $_POST['event_date'] as $key => $date ) {
    // Sanitize the data and push it to our new array
    // `wp_filter_post_kses` strips our dangerous server values
    // and allows through anything you can include a post.
    $sanitized[$key] = wp_filter_post_kses( $date );
  }
  // Save our submissions to the database
  update_post_meta( $post->ID, 'event_date', $sanitized );
}
add_action( 'save_post', 'event_date_save_metabox', 1, 2 );

By this point we have a custom post type on the backend where we can add start and end dates to the custom meta boxes that will save and we can return to them

Create an array with IDs and dates

Now I loop the latest ten events and build an array with that info but I don’t write anything to the page so I suggest putting this right above where it will be implemented, in my case the header.php file.

<?php
$date_now = new DateTime(); // current time date, note this cant be used with an echo $date_now needs print_r($date_now);

$stack = array(); // build an empty array to add event dates to

// query for events
$args = [
  'post_type'			=> 'flaxen_event',
  'posts_per_page'	=> 10,
];

// run the events in a loop this doesnt print anything just builds an array
$loop = new WP_Query($args);
while ($loop->have_posts()) {
  $loop->the_post();

  $meta = get_post_meta( $post->ID, 'event_date', false ); // grab the dates meta
  $data = $meta[0]; // this ends up as an array in an array it might be possible to remove this step but for now its needed

  // create variables for the date portions
  $mon = $data['start_date_m'];
  $da = $data['start_date_d'];
  $yea = $data['start_date_o'];

  // create a date with the variables as one
  $eventdate = new DateTime("$mon/$da/$yea"); // runs month / day / year 13/12/2016 

  $event_id = get_the_id();
  
  $stack[$event_id] = $eventdate; // add the dates as a value to the array with the ID as the key
  
} // while have events

Sort the stack

There are a number of ways of sorting arrays in php the one I am using here is sort as it orders the values without resetting the keys

asort($stack); // ascending sort is oldest to newest and doesnt alter the keys

Print the next event

At this point we have everything in order we just need to print the title of the upcoming event

foreach ( $stack as $key => $value ) {
  if ($date_now < $value) {
    $title = get_post($key)->post_title; // the events title
    ?>
    <p><?php echo $title; ?></p>
    <?php break; // stop looping once we find something in the future
  } // if the events in the future
} // loop of all events

If no upcoming events

We need to have the fallback incase we don’t have an event coming up

$last = array_key_last ($stack);

if ($date_now > $stack[$last]) { ?>
  <p>Start With a Free Discovery Session</p>
<?php } ?>

Explore Events

I was working through a site doing some updates and I needed to add so meta to a post, Working through the documentation on https://developer.wordpress.org/block-editor/tutorials/metabox/meta-block-1-intro/

I started running into some issues, it’s a pretty straightforward process with only a few steps that I had working, but then it broke the next time I was working on it, after way too much time and effort it appears to be a conflict between doing this and the Gutenberg plugin


Explore Register Post Meta and Gutenberg Plugin conflict

Another year of footage all cut up and pulled together with the Snowledge crew nothing particularly planned other than to get out in the mountains and make “something” happen so it feels good to make it into a singular thing that encapsulates a lot of what I did through the winter and who I got to be out there with.


Explore Snowledge Team Edit 18 // 19

As the winter is starting to ramp up I got out at Alpine Meadows to shoot a weekly piece they do know as the shred report, it often focuses on new terrain so this week we got on Roundhouse with a few buddies and we lapped around with a GoPro.

The new shipment of cameras hasn’t come in yet so it’ll be interesting to see how the 8 do against shooting this on the 7 with the karma grip but we have plans to do a few more of these as the season progresses.


Explore Squaw Shred Report

For a major rebuild of the one page New Zealand Tour Guide site I focused on speed and built a snappy little site with the basics of HTML, CSS, and JS producing a site that loads dramatically faster and consumes far fewer resources than what was there before.

(more…)

Explore NZ Tour Guide

Over a quiet weekend I knocked up a quick pitch piece of a product page for Mons Royale, I’ve always been a big fan of their pieces and have worked with them on media projects over the years but never in as much of a design role.

I took what Mons is already doing with product and graphic design and just pushed it to a web design, using the strong colors and angles, being a quick weekend piece the site works as a mockup but isn’t truly function, there’s no hover states, only enough header tags for the page to load, javascript only powers the webpack build, there are problems with the design at certain sizes or adaptions so it would need significat work to be production ready.

The design is layers on layers of CSS grid and I’m really looking forward to the implementation of sub-grid as it comes down the pipeline, almost all of the color is either background filled grids of SVG shapes, including the promo piece (green background) halfway down which involved layering and building shapes in a way I hadn’t pushed as far before so that’s something I want to continue explore and create some dynamic and responsive designs that are super performant.

https://mons.rileybathurst.com

(more…)

Explore Mons Royale Product Page Pitch

I enjoy freelancing but sometimes it comes with limitations and one of those I was running into was how to promote myself online, with such a spread out portfolio there are days I struggle to explain what I do to someone on the street so I wanted to put up a front that was simple even if it doesn’t cover half of what I can do.

Tahoe Web Shop


Explore Tahoe Web Shop

A very long time ago I was helping Ben out to build a snowboard site, so between 2010 and 2014 it was a functional site but it’s been left to hang out and languish, so we threw together something a little more exciting for a landing page. It’s really just a fun little usage of the CurtainJS tech but maybe someday we will continue to build on this and do something exciting.

The screenshot really does no justice of what this is so check it out over at BenComber.com


Explore Ben Comber Landing Page