Category Archives: Plugins

Plugins used and their purpose

Public Cannot View Scheduled Posts

A user going by the name of drober started a thread on the Announcements Ticker forum complaining that non admin users were unable to view the full text of announcements by using the “Read All” link. On his site, they would be prompted to login, but non admin accounts still could not see the content.

This is because the plugin sees future posts as active announcements. This is by design so the announcement can automatically when expire when it reaches the scheduled date. However, WordPress does not allow non admin users to view future posts. This never showed up in testing because I always used a logged in admin account.

The fix was to hook into the one of the save_post actions and change the post status from future to publish if an announcement is saved. I also had to take out the condition that the plugin only selects future posts for display.

For the full discussion, see the forum support thread.

Custom Post Type Permalinks

After creating the custom post type in my plugin, I tried visiting, but got a 404 error page instead.

I came across a blog post by Kovshenin which explains how to get permalinks working with custom post types. The key thing is to specify the slug with the ‘rewrite’ parameter when registering the CPT. After that, remember to reset the permalinks by visiting the permalinks settings page in Settings -> Permalinks. Quite a lot of 404 grief can be solved by doing so.

It makes sense to automate this in the plugin. To do so, I added flush_rewrite_rules() to the activation and deactivation hooks. This would ensure that the permalinks are reset only when the CPT becomes active or inactive.

Do not let the function run on every page load. It is very resource intensive and will slow your site down.


I’m creating custom post type in a plugin for the first time. So far, it’s been done directly in the child theme. Not the best place as functionality should be separate from display.

The first thing was to copy, edit and paste one of the register_post_type() calls I had written before. Right away something was strange. The CPT showed up on my development site, but not on a blank install. After much commenting out of various lines, I found that the problem lay with the ‘capability_type’ argument.

My development site is multisite, and it looks like network admins have much more capabilities than normal site admins, or perhaps it was the role management plugin magically granting it rights. I looked into the code for the role management plugin (Members by Justin Tadlock) and discovered that it added some extra capabilities upon plugin activation. Sounds like just what I needed.

register_activation_hook( __FILE__, 'mbpc_feba_cpt_install' );

// Start by giving the administrator role access to the CPT
function prefix_cpt_install() {
	/* Get the administrator role. */
	$role =& get_role( 'administrator' );

	/* If the administrator role exists, add required capabilities for the plugin. */
	if ( !empty( $role ) ) {
		/* Role management capabilities. */
		$role->add_cap( 'publish_cptname' );
		$role->add_cap( 'create_cptname' );
		$role->add_cap( 'delete_cptname' );
		$role->add_cap( 'edit_cptname' );


I’ve edited some of the names used. When you’re writing your own, remember to prefix your functions so they’ll be unique, and of course replace ‘cptname’ with a meaningful name.

Unfortunately, the code above did not work for me. It looked like the activation function was not being called. Putting echo statements inside didn’t do anything, and even putting die() inside did nothing.

When there’s a problem, start with the Codex. The page for register_activation_hook() had line near the bottom referencing a support forum thread. Turns out that ‘echo’ really doesn’t work, and the way to check if the activation hook is being called is to use exit().

Another user pointed out that __FILE__ doesn’t work when the plugin directory is only symlinked. That’s exactly what I’m doing! The solution is to pass it the path to the symlink.

register_activation_hook( WP_PLUGIN_DIR . '/plugin-name/plugin-name.php', 'prefix_cpt_install' );

And now the CPT shows up in the admin menus! wp_user_roles in the options table also has the new capabilities added by the activation function.

SlideDeck Bumps

With new events coming up, it was time to replace the Slidedeck on the home page. This turned out to be more difficult than expected.

Firstly, the Insert SlideDeck button was hidden behind the Upgrade banner. When I moved that admin widget away from the sidebar to the main post column, the ‘Insert’ button became visible, but it didn’t work. Terribly irritating.

I remembered that all it did was to insert a shortcode into HTML view, but when I tried [Slidedeck], that didn’t work either. After firing up my development VM and checking the test page I had created, I realized that the shortcode is case sensitive.

For my own reference, and because all the information online was on how to use the ‘Insert’ button, the shortcode I’m using is below.

[SlideDeck id='xxxx' width='100%' height='250px'] Replace xxxx with the id number of the SlideDeck, which can be seen when editing it.

Updating Slidedeck Plugin

Updating the Slidedeck plugin to version 1.4.2 broke my site. I got PHP warnings about “file get content cannot be empty”, or something like that.

Much to my irritation, there’s also no way to downgrade back to version 1.4.1, although that wouldn’t have solved anything.

The problem is that the ‘skins’ folder containing my custom slidedeck skin was overwritten, so it could no longer find the active skin. Replacing this folder from the backup on my local development copy solved the problem.

Plugin Bugfix

It has come to my attention that my plugin was generating a PHP warning “Warning: Missing argument 2 for flh_wpcomgms_search_map_code()”

Although it doesn’t hurt anything, the warning is ugly.

Reading the documentation of the wp_insert_post_data filter more closely revealed the problem.

You must pass 2 for the $accepted_args variable in add_filter() if you want to access $postarr.

So I did that, and the warning went away.

However, when updating the plugin, I ran into a problem. The correct version was made available, but the text on the download button still referred to the old version number. I emailed plugins support, and discovered that I had forgotten to change the version number in the PHP file itself. I had only changed the ‘Stable Tag’ field in the readme.txt file.

So remember, when updating a plugin, it’s necessary to change both the ‘Stable Tag’ in the readme.txt file as well as the version number in the PHP file header.

First Plugin!

I’ve written and contributed my first ever plugin! This was in response to a forum post asking for help in getting’s Google Maps shortcode to work. The user had moved over to a self-hosted and all the previously used shortcodes weren’t working.

My original solution was simply to add in the shortcode and get the shortcode handler to throw out the <iframe> code. The width and height was hardcoded and the ‘View Larger Map’ link wasn’t there, but the maps showed.

The very first draft of the plugin can be found in the pastebin.

The release version of the plugin supports variable widths and heights for the maps. It does this by finding the width and height of the original <iframe> then appending those values to the end of the URL stored in the shortcode, just like how it’s done on

When the URL is parsed for output, those values are extracted and used to define the dimensions of the <iframe>.

Another important step which had to be taken was to move the execution of the shortcode up, before wpautop is called. If not, linebreaks will not be added correctly, causing the layout in the post to go haywire. Code to do this was adapted from

After all this talk, I’m sure you want to know where to find the plugin. It’s been uploaded to the official plugin repository.

I’ve also created a page on this blog which explains its purpose.

If you find it useful, do leave a comment and tell me about it 🙂