Category Archives: Plugins

Plugins used and their purpose

Members Plugin

I needed to figure out how to control who could add the different types of content to the site. The information in the WordPress codex on Roles and Capabilities isn’t too complete at the moment. It took a few readings to understand the system, but there was still not much clue on how to write code to customize it.

After trying a couple of different plugins, I finally found that the Members plugin by Justin Tadlock does what I want. This plugin can be used to manage roles and then assign them capabilities. It can also do other things like limit content from certain users, but I only want to control the types of content which the different roles can post.

My plan is to have a blogger role who will only post normal WordPress posts. These will appear on the blog page. Another role will take on the role of content manager. This role will be given control over the sermons and newsletters, but not the blog posts. The primary intention of all this is to make the admin interface less complex for the end users and only show them the things they can edit.

The blogger role is currently fulfilled by the default author role. By adding the ‘capability_type’ key to the custom post types, the default author can no longer see them.

Using the plugin, it was a simple task to add the role of content manager. I then gave it capabilities to edit and publish sermons and newsletters. The necessary capabilities are edit_sermons, edit_others_sermons, edit_published_sermons, publish_sermons, delete_sermons, delete_others_sermons for sermons. Replace ‘sermons’ with ‘newsletters’ and all all the capabilities for control over newsletters.

It is also necessary to grant manage_categories so category and taxonomy terms can be added and managed. To allow the role to assign terms in custom taxonomies, the key-value pair 'capabilities' => array('assign_terms' => 'edit_sermons') is needed when registering the custom taxonomy. Once again, replace ‘sermon’ with whatever capability_type you want.

To allow media to be managed, the edit_posts and *_posts capabilities also had to be added. * is a wildcard for all the other functions. This actually allows the content manager control over the blogger’s posts, but the problem is mitigated somewhat by hiding the posts menu from the interface.

While the author role currently fulfills the blogger role, it would be better to separate them. The default author role will then be given the combined capabilities of church_cm and blogger.

Add from Server plugin

Uploads through the admin interface go into the uploads folder with the structure year/month. This is usually fine, but what if I want to upload lots of past content? If I upload a lot of past content now, it’ll all end up in the 2011/03 folder, regardless of when the content was produced. This will be messy. The better solution is to upload each to its own year/month folder, a much neater solution.

However, manually placing the files into the desired folder structure does not cause them to show up in the admin interface. It turns out that WordPress doesn’t check the folders to see if anything is inside. A database entry is needed. This can be accomplished with the Add from Server plugin, which scans the directories and adds the required database entry.

This allows the files on the server to be added to the database and hence show up in the media library. The file will attach itself to the post which is currently being written, unless the checkbox “Do not add to current post gallery” is selected.

Custom Post Type Archives Part 4

Phew, custom post type archives are causing lots of problems. Three separate posts about them already, and the plugin was the one which broke WordPress 3.1. Well the updated version doesn’t. However, this led to a thought. Since it’s supposed to be built in, could I do it without using the plugin? After all, I was just after some very basic functionality. The answer turns out to be yes, well, almost.

Enabling the Feature

There is an attribute has_archive in the register_post_type() function which activates the archives feature, but it defaults to false. I added the code in to set this to true. This information was from Mark McWilliams, the same post also gave some hints on how the permalinks would look like.

Disabling the Plugin

The next step was to disable the plugin and see what stops working. Looks like the sidebar has some problems, which also prevents the admin bar from loading properly. The month listing from the custom widget wasn’t appearing at all.

Fixing the Widget

The widget depends on the custom get_post_type_archives() function, explained in Part 2, to do its magic.

Using a debug echo statement and commenting out suspect lines, I found the problem in one of the custom functions provided by the plugin. It returns the permalink of the post type. This can actually be generalized as

get_bloginfo('url') . '/' . $post_type . '/';

Now I get output with a link to the archives by date, but it wasn’t showing the correct number of months. Why??

Filter getarchives_where

Even the plugin just let the built in WordPress function wp_get_archives() do the hard work, so why did it work with the plugin activated? A closer look at the function itself, and the way it was used by the plugin, revealed that wp_get_archives() was insufficient to get archives by post type. It applies a filter to get the correct SQL Where clause. This was used by the plugin.

Since I only want that function, I copied the entire thing over to my own functions.php file.

function pta_wp_get_archives_filter($where, $options) {
	if(!isset($options['post_type'])) return $where; // OK - this is regular wp_get_archives call - don't do anything
	
	global $wpdb; // get the DB engine
	
	$post_type = $wpdb->escape($options['post_type']); // escape the passed value to be SQL safe
	if($post_type == 'all') $post_type = ''; // if we want to have archives for all post types
	else $post_type = "post_type = '$post_type' AND"; // otherwise just for specific one
	
	$where = str_replace('post_type = \'post\' AND', $post_type, $where);
	
	return $where;
}
add_filter('getarchives_where', 'pta_wp_get_archives_filter', 10, 2);

Now the archive links work and the correct number of links are displayed, depending on what the post type is!

Archive Templates

This approach led to my custom post types being displayed incorrectly as they now use the archive.php template file. It only displays the excerpts for archives, so the shortcodes and meta data no longer show up. As each post will be very short in length, I want the full content and meta data to show up, just like it does on the main page listings.

The solution to this was simply to copy archive.php to the child theme, rename it archive-{post-type}.php, and change the function call to the loop so that it calls my previously written custom loops.

Page Templates

{post-type}-template.php were previously used for both the display of the full listing as well as the archive pages. With WordPress 3.1, archives are handled by the archive template pages. Thus, the if-else conditions which handled query_posts() can be removed. The page templates will be used just for display of all the custom posts.

Conclusion

With all these changes, I can now use one less plugin and use more of the functionality available in WordPress Core.

Custom Post Type Archives Part 5

Custom Meta Box (Easy)

The task is to create a custom meta box to ask the user for the scripture text verse reference for each sermon. Of course, this can be done easily with custom fields, but expecting normal users to always type in the right key value might be problematic. Also, to the normal user, ‘custom fields’ sounds like something which shouldn’t be touched and might cause the whole system to implode.

Thus, I wanted a simple text field in the interface which is clearly labelled and only requires the data to be typed in.

The easy way is to use the More Fields plugin.

The plugin is very flexible and provides a nice graphical interface for creating meta boxes, customizing the fields which go into them as well as which post types they should appear on. However, it also seemed like way too much code and functionality for the simple task I wanted to do.

Custom Post Type Archives

In addition to getting sermons by speaker, I would also like to be able to access them by month. Unfortunately, there’s currently no built in method to do so. A bit of poking around revealed the Custom Post Type Archives Plugin.

Setting up the plugin was easy enough. Unzip the file into the plugin folder and activate it, then go to the settings page and select the Sermon type. Go to the Permalinks settings page to flush the rewrite rules.

Keeping the other settings at their default values, sermons can now be accessed at domain/site/post-type/year/month (substitute the names with their proper values). However, speakers no longer show up. I realized that it’s using one of the default template files, so I changed the template pattern setting to {POST_TYPE}-template.php. This causes it to look for sermon-template.php, which will run the custom sermon loop.

Unfortunately, this caused the undesired side effect of overwriting the query with the custom query for normal sermon display. Thus the year and month information is lost. The code for sermon-template.php had to be changed.

When accessing the normal page, the query comes with the page name. This value isn’t wanted, but I could use it to differentiate between the listings page and the archives.

global $wp_query;
$existing = $wp_query->query;

if(isset($existing['pagename']))
    $args = array('post_type'=>'sermon','posts_per_page'=>5,'paged'=>get_query_var('paged'));
else
    $args = array_merge($wp_query->query,array('post_type'=>'sermon','paged'=>get_query_var('paged')));
query_posts($args);

The missing posts_per_page argument in the else clause is by design. There shouldn’t be more than 5 sermons in each month anyway. Also, despite what the documentation says, paging doesn’t work in the plugin.

Custom Post Type Archives Part 2