When I started building wordpress themes PHP and most of the advanced wordpress functions went over my head. I’ve learned quite a bit since then, but one step taught me a lot about wordpress and PHP. While I was coding my premium wordpress theme I decided to make a very simple related posts widget. There are plenty of plugins that do this but I wanted to learn about writing widgets and further my PHP and I had a pretty good idea on how to do it, so I did it.

Functions.php

I suspect most people creating themes never even create a functions file, much less know what it does. Used correctly it can be a very powerful tool. This is how advanced theme authors create theme options, custom wordpress theme tags, widgets and more. I won’t go into too much detail on the functions.php file for now as that can be a tutorial in itself. There are a few resources for learning what can be done with the file, and I’ll be writing much more about it on this blog in the future.

Making a widget

First you need to create a functions.php file in your theme directory. The file must start with <?php and end with ?> with no empty lines before or after. Now we are going to create a new function which will become our related posts widget.

<?php
//Super Simple Related Posts Widget
//Gets posts from the first category of the current post
function widget_ch_related_posts() {
}
if ( function_exists('register_sidebar_widget') )
register_sidebar_widget(__('CH Related Posts'), 'widget_ch_related_posts');
?>

This is the beginning of our widget. I like to put comments at the top to identify what the widget is and does but this isn’t necessary. First we declare a function called widget_ch_related_posts(); try to create a unique name, you don’t want it clashing with any other widgets or function names.

The if statement simply registers the sidebar widget with wordpress and gives it a more pleasant name. The ‘CH Related Posts‘ is what you will see in the widgets section of wordpress, so give it a name you will recognize.

To learn more about exactly what that code is doin, here is the documentation from Automattic. Essentially we are widgetizing a plugin, we just haven’t created the plugin, yet.

Next up, a plugin!

Now we have a widget, but it doesn’t do anything. We need to stuff some cornbread in our widget (I like cornbread). In most of my themes I alter the sidebars to use divs for the containers and h3 for the headers, but by default widgets use list items for containers and h2 for the headings. I tell you this because you need to know what scheme your theme is using for your code to work right. You can learn more about this at another Automattic page. I’ll use the default way for this example, below is the example of our plugin.


<li class="ch_related_posts">
<h2>Related Posts</h2>
<?php
//get post categories and set $cat to first category
$cat = get_the_category(); $cat = $cat[0];
//set arguments for the get_posts function more options found at wordpress codex
$args = array(
'numberposts' => '5',
'offset' => '1',
'category' => $cat->cat_ID //calls category ID number
);  ?>
<ul>
<?php
global $post;
$myposts = get_posts($args); //gets arguments from array above
foreach($myposts as $post) : //loops through posts
setup_postdata($post); //sets up posts
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
</li>

I’ll break this down MC Hammer style for you. The list item is contained in our themes sidebar(which should be a unordered list, hence no <ul> tag). You can dump the class=”ch_related_posts” if you don’t need to style it individually. The h2 header is the title of your widget, so far pretty basic html.

The php is where we get to start having fun. First thing I do is create a variable called $cat, I then use get_the_category to get all the categories the current post belongs to. Now $cat is holding an array, I set $cat to the first category using $cat = $cat[0] (arrays in php start with zero not 1). But hold one a sec! This is a good place to experiment with the plugin, I made it very simple but you could get posts from all the categories, certain categories, get tags instead of categories. You have plenty of options, and I encourage everyone to play around and see what happens.

For the next trick I’ll create $args tada, args stands for arguments. Arguments for what? For get_posts but more on that later. I create an array and input the arguments that I want to pass along to get_posts further down in the code. This is just an easy clean way that I like to pass the arguments, it makes for easy changes and readable code.

<?php 'category' => $cat->cat_ID //calls category ID number

This little line of code sets the category argument to the ID of the current posts first category…I think that makes sense. See $cat is holding a lot of information about the category and all we want is the ID.

Output something already!

OK! Now we need to list all the posts, pretty normal wordpress stuff now.

<ul>
 <?php
   global $post;
   $myposts = get_posts($args); //gets arguments from array above
   foreach($myposts as $post) : //loops through posts
   setup_postdata($post); //sets up posts
  ?>
     	<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
  	<?php endforeach; ?>
</ul>

I set up the posts using global $post then set $myposts using get_posts and the arguments we just specified. We loop through the posts and output them into nice little happy list items. We end the loop and close the list out and we are done! Sorta.

That was easy.

Ok so now you got your widget, you got your plugin, now you need to put them together. This is really easy, copy your plugin code and paste it right smack in the middle of the widget code like so:

<?php
//Super Simple Related Posts Widget
//Gets posts from the first category of the current post
function widget_ch_related_posts() {
	<li class="ch_related_posts">
		<h2>Related Posts</h2>
		<?php
		//get post categories and set $cat to first category
		$cat = get_the_category(); $cat = $cat[0];
		//set arguments for the get_posts function more options found at wordpress codex
		$args = array(
				'numberposts' => '5',
				'offset' => '1',
				'category' => $cat->cat_ID //calls category ID number
				);  ?>
		<ul>
	 	<?php
	 		global $post;
	 		$myposts = get_posts($args); //gets arguments from array above
	 		foreach($myposts as $post) : //loops through posts
	 		setup_postdata($post); //sets up posts
	 	?>
	    		<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
	 		<?php endforeach; ?>
	 	</ul>
	</li>
}
if ( function_exists('register_sidebar_widget') )
	register_sidebar_widget(__('CH Related Posts'), 'widget_ch_related_posts');
?>

And there it is, save your functions.php and check to see if everything works. If it doesn’t it is probably my fault, but you should try to fix it, cause that will help you learn, at least that is my excuse. This is just a itty bitty taste of what you can do with functions.php file.
To read more about how to create widgets and plugins visit Automattic’s page for the complete API.