WordPress theme mods

Just a quick one: In re-creating my blog I had to go through one of my least favourite ordeals, choosing a theme. Given time I’d create my own (but, also given time, I’d probably just write my own bare bones CMS) but that’s not an option, so I usually look for simple, clean themes that I can perhaps customize a little bit and be done with. This theme is called Greyville, by the way, it’s rather pretty I think.

I actually set this blog up locally using Xampp first so I could import a few posts, do those theme mods and make sure everything worked before it went live. I was using the Greyville theme for a while, and had gotten used to it, when I realized it didn’t support a proper menu bar. So I decided I’d add one, how hard could it be?

Fairly simple it turns out, if you have the WordPress API imprinted on your mind. I spent most of my time looking up functions and then trying to chase their dependencies around the internet to find out why they weren’t working right. But I got there eventually, and I thought posting this information could help someone else who just wants to add a menu bar, or wonders why none of his custom php works…


Themes are stored in <wordpress_dir>/wp-content/themes/, and in Greyville’s folder the couple of files we’re interested in are index.php (template for every page, including the blog main view) and single.php (template for viewing a single blog post). Obviously, where exactly you want to insert your code depends on the theme, but here those header bars are within a “post” div which also contains the page/post content and things like comment count, post date etc etc. I simple create a new post div at the start of the content column, create my modified header code in there and close the div with no more content. In practice, to reduce redundancy, I’ve just created a new php file called menu_bar which is require_once’d in both files, and the code it includes is this:

 

<div class="post" style="width:100%;">
  <h1>
  <?php
  $pages = get_pages(array( 
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order,post_title',
    'post_type' => 'page',
    'post_status' => 'publish'
  ));
  global $post;
  $width = floor(100 / count($pages));
  $rem = 100 % count($pages);
  $pid = get_the_id();
  $i = 0;

  foreach ($pages as $post) {
    setup_postdata($post);
    $i++; 
    echo "<div class='menu-wrap' style='width:";
    if ($i == count($pages)) {
      echo ($width+$rem)."%;";
    }else echo $width."%;";
    echo "'><div class='menu-inner'>";
    echo "<a href=\"".get_permalink($post->ID)."\" rel='bookmark'";
    if ($pid == $post->ID || ((is_home() || is_single()) && (get_the_title($post->ID) == "Blog"))){echo " style='color:#c6c6c6;'";}
    echo ">".get_the_title($post->ID).".</a>";
    echo "</div></div>";
  }

  wp_reset_postdata();

  ?>
  </h1>
</div>
<div class="clear"></div>

 

First we use get_pages which returns an array of all the pages in the system. Internally, pages and blog posts are the same thing, just with different properties, so we pass an array as a parameter which contains information to narrow down the results: We specify the post’s returned must be of type “page”, have been published publicly and ordered by their menu_order index. There are a lot more parameters you can pass in this array, all listed on the WP Codex page. Now we create a few vars, calculating the width of each menu item, as well as defining an int which contains the current page ID. Important note: In order to use get_pages the variable you’re passing in MUST be called $post, and you MUST make it global before using it.

Now we get to the interesting stuff, actually looping the pages and echoing some menu. The first thing we do is call setup_postdata with the $post object we got from get_pages. This is essential: WordPress runs in one giant loop, and it’s my understanding that this function basically modifies all the loops values so it is as if you were loading the specified post, which allows you to use all the standard functions to get the posts data (such as get_permalink, and get_the_id, which is why we stored that value before the loop began.)

Moving down there’s nothing unexpected. The last interesting thing is in the page detection. You’ll notice if you visit any of the pages linked in the menu bar that there entry in the menu will lighten, and above you can see I’m just comparing the current post ID with each of the ID’s we’re putting in the menu to see if they match ($pid == $post->ID). That works really well, except that the blog list page doesn’t report a unique ID, it gives you the ID of the first blog post on the page. To find out if you’re on the blog list page then, you use is_home, and there are many other similar commands such as is_front_page (if you’re using a front page which is NOT your blog page, very useful,) or is_single (for individual blog posts,) which you can read at the WP Codex.

The last thing we do is run wp_reset_postdata, which returns the main loop to the state it should be (and was originally) in so the page can continue loading.

I hope someone finds that useful, God knows I’ll be referring to it next time I have to set up WordPress…
– B