Uncategorized

Events

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

Register Post Meta and Gutenberg Plugin conflict

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
graphic design on a fire extinguisher

I needed a business card that was going to stand.

This piece comes from talking to a local design studio being open to me coming back in with a portfolio if I was ever looking for work.

The idea starts from Massimo Vignelli talking about Lella being the brakes to his work and Michael Bierut talking about how that took a long time to understand why it was as important, so somehow that became a fire extinguisher as I have always liked design with everyday objects being used out of context as long as they still mean something.

The quote is adapted from the Rolling Stones “Play with Fire” the studio I was talking as many others do have an affinity for music so I wanted something to reflect that.

If any of that context got through I don’t know but they seemed to like it so hopefully I’m working with them more in the future.


Explore Fire
earnest overalls working on a land rover

Taking some of the most neglected clothing in the fashion game and upping the level as well as being technical and functional in a way you didn’t know people we’re thinking about.


Explore Earnest
drone snowboard photo

Always nice to see a new shot in print as that hasn’t been my focus for a while and this one was in the SNOWBOARD magazine exposure competition, it was a finalist for the abstract section and just one of those shots that turned out. This was a plan B after hiking up Squaw in the late summer, I had to get my twelve calendar months and Garrett Cygan is just always keen to ride. We we’re making a short video for Snowledge when I figured this would like better as a still and well I’m really happy that it did and really happy with how well the DJI Mavic Pro turns out in print.


Explore ABSTRACT Finalist