Could not Edit Menus

I was having an annoying issue where a site’s menus could not be edited through the WordPress admin interface. The menu structure would load but drag and drop simply refused to work even when the cursor changed to the 4-way move arrow.

Checking the console in Chrome’s web inspector revealed some sort of JavaScript problem. Changing the theme to a default one made the problem go away, thus the problem had to be with the custom theme.

I started debugging by commenting out the add_action() functions enqueuing some extra js files used for the jQuery accordion. That fixed it. Putting back the accordion init script revealed that it was not the problem, so that left the custom jQuery UI file, version 1.8.13.

The latest stable version is now 1.10.2, so I got that by selecting the accordion widget on jQuery UI’s download page, letting the other checkboxes auto populate. Extracted the file into the scripts folder, updated functions.php to point to the new file, and the menus admin page now works again!!

tl;dr
Update the jQuery UI file.

Single Digit Numbering in List

When creating an ordered list recently with more than 10 items, the numbers looked like they reset at 0 and only had one digit. I knew that the list was being generated correctly with 2 digits because the visual view in the post editor showed the proper numbers. It just wasn’t showing up in the actual post itself.

Using Chrome’s Developer tools, it looked like the margins for the ol element weren’t wide enough. This was set by the CSS in the parent theme. I added an entry to the child theme’s style.css to override the margin and increase the left margin to 2 em. Refreshed the page and the numbers came up correctly!

ol {
        margin: 0 0 18px 2em;
}

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 domain.com/, 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.

register_activation_hook()

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.

Permalinks on Mac OS

Mac OS X has Apache and PHP built in. I installed MySQL and set up a localhost WordPress install on it. Everything looked good, until I tried to enable pretty permalinks. The pretty links just didn’t work.

The Codex page indicates that FollowSymLinks must be enabled and AllowOverride should be All (or FileInfo). I tried putting that into the httpd.conf file but that didn’t work.

It took a while to realise that I was putting those directives into the section for the web root directory and not the user specific folder where I had actually put the site. Following the trail of includes in the well commented config files, I found my user Apache config in /etc/apache2/users/.conf

Added those options into the config file and permalinks are working :)

EDIT: Upgraded to OSX Mountain Lion and it uses a different set of configuration files. It looks like user config files aren’t created by default so I just changed the default directive.

SVN Tip

I run a few localhost installs of WordPress for testing and experimentation. They are installed using the svn method, as outlined in the Codex.

At first, I would go in manually to each folder to svn up occasionally. This got tiresome after a while so I wrote a simple bash script to cd to each folder and run svn up

Recently, I discovered that there’s a shortcut. All I have to do is to go to the parent directory and type svn up *

This will run the command on all the subfolders and thus bring all my sites up to date.

Menu Behind Youtube Video

After embedding a Youtube video on the front page, I noticed that the drop down menus were appearing behind the video, making some pages inaccessible from the menus. Not good.

Some poking around Google led to http://manisheriar.com/blog/flash_objects_and_z_index

I found that only step 3 (setting wmode=”transparent” in the embed tag) is necessary. To get that version of the embed code, it is necessary to select the “Use old embed code” checkbox in Youtube’s embed settings. However, this means that only Flash playback is supported.

Prior to this, I also tried wrapping the embed code in a <div> and using the z-index CSS setting. That didn’t work at all. Perhaps there’s another solution that will work with the iframe embed method so HTML5 video can also be supported.

Podcast Feed

Since my site has weekly MP3 uploads, it makes sense to create a podcast feed for it. Unfortunately, those updates were implemented with custom post types, which don’t generate podcast feeds automatically with the <enclosure> tags. Thus I would have to generate a custom feed myself.

The Codex page on Customizing Feeds explains how to get a custom post type to use my own custom feed. Since I’m using a child theme, I used get_stylesheet_directory() instead of get_template_directory().

When I first setup the custom post type and imported the existing content, the meta value _wp_attached_file included the full URL. It still does as the custom insert post functions for the custom post type have been written that way. Thus to generate the path to the file (to get the filesize for the RSS feed), I had to modify the output of get_attached_file() by using the get_attached_file filter.

Using the default RSS2 template as a starting point, I modified the template to produce a feed which more or less follows the iTunes format. The major challenge was getting the filesize of the MP3 files, this was done with the PHP filesize() function.

$size = filesize( get_attached_file( $child->ID ) );

The author and subtitle fields were field with the available post meta stored with the custom post type.

A strange problem I encountered was that this worked perfectly with iTunes on my test setup, but iTunes refused to recognize the feed properly on the live site. This was solved by using feedburner, and subscribing to the feedburner feed instead. However, this still doesn’t explain what’s wrong with the feed on the actual site which prevents iTunes from getting it properly.