Pages-Children 1.5 released

Over the last week I’ve released 3 versions of my popular Pages-Children plugin.

Here is a breakdown of the changes.

1.3.1 – Fixed issues is plugin which were effecting the Media Library listing. As far as I can tell this was related to the update in WordPress 3.1.3

1.4 – Added support for any hierarchical post type. Previous versions of the plugin only worked for the default Pages. Now if you have any custom post type defined hierarchical you can have better formatting of the output.

1. 5 – In the previous version (1.4) I added support for custom post types. In this latest version I’ve added support for hierarchical taxonomies as well. Here is an example of a terms listing showing the breadcrumbs and navigation to ‘children’.

To comment or report an issue regarding this plugin please see the main project page for Pages-Children

Out of 1000 WordPress plugin developers I’m now ranked 372!

Thanks to W-Shadow for putting together this nice page, http://w-shadow.com/files/top-1000-plugin-authors.html.

The page appears to be a mashup (do people still use that term) taken form wordpress.org plugin repository. The ranking on the page appears to be based on plugin downloads. Still out of 1000 plugin authors it’s nice to be in the top half. Though would be grateful to placement anywhere on the list. Thanks W-Shadow.

Adding Custom Meta Headers To Taxonomy Table Columns in WordPress 3.0

This is part 2 of a series on digging deeper into the new WordPress Custom Taxonomies. In the previous article, “Custom Meta for new Taxonomies in WordPress 3.0“, I walked you through setting up the custom meta tables and the Taxonomy term editor form. In this part of the series I’ll show you how to add your new taxonomy meta fields to the taxonomy listing page.

Background

To bring everyone up to speed on the project I’m developing a simple product management system (e-Commerce) for a client. I wanted to take advantage of the new Custom Post Types and Taxonomies in the WordPress 3.0 system. I setup a new Post Type ‘Products’. As part of Products I’m defining a new Taxonomy ‘Product Packages’. A ‘Package’ is how a product is sold to the user. Think of threadless.com or some product site where you must select options like size or color. In our case each package has a number of extra ‘meta’ fields associated with it. In the case of my product packages some of these meta fields are unit price, shipping price, package active.

The goal of this article is to modify the default columns displayed on the taxonomy listing. These default columns are Name, Description and Slug. While these are sufficient for other taxonomies like post categories or post tags they don’t exactly work for my product package needs. What we will be building is some more like the following which includes meta field from part I. The column headers we will be added are ‘Active’ to show when a Product Package is on or off and the column header ‘Price’ which is the unit Price for a given package. These columns were chosen because the let the administrator visually see the information in the table form without needing to access each package detail.

WordPress Taxonomy meta listing

So lets get started.

Adding Taxonomy Column Headers

We will start with adding the filter to modify the column headers. When I click on the ‘Product Packages’ I noted that URL for the taxonomy listing is

http://local.localsite.com/wp-admin/edit-tags.php?taxonomy=product_packages&post_type=products

After doing some digging I found that the edit-tags.php code calls a number of functions to build out the page structure. One of these function is ‘get_column_headers()’ The get_column_headers function is located in the /wp-admin/includes/template.php file line 674. Inside this function there are various checks to see if we are dealing with a normal build-in screen like for post categories or post tags. If not the logic falls down to line 761 there a filter is executed. The filename key or name is dynamic and is based on the taxonomy name. The filter key is ‘manage_’ . $screen->id . ‘_columns’. The screen->id value is the taxonomy name we used ‘product_packages’. The filter we will be setting up will be ‘manage_product_packages_columns’. So in our code’s init function we to subscribe to this filter and add a function to handle the processing. Below is the code. The init function you may recognize from part I.


<?php
add_action( 'init', 'product_init' );
function product_init()
{
register_taxonomy( 'product_packages', 'products',
array( 'hierarchical' => true,
'label' => __('Product Packages'),
'query_var' => false
)
);
// Added from Part II.
// This filter sets up a call to your function which will handle
// adding (and removing) items from the columns array. This
// filter passes up only one argument. The array of default headers.
add_filter( 'manage_product_packages_columns',
'admin_product_packages_column_headers, 10, 1);
}
// Add this to your code's init function. This filter passes up
// only one argument. The array of default headers.
add_filter( 'manage_product_packages_columns',
'admin_product_packages_column_headers, 10, 1);
// Add this function somewhere else in your plugin or functions file.
function admin_product_packages_column_headers($columns)
{
// We are going to create a new array to hold the headers.
// Below we take the checkbox column and the name column
// and add to the new column array. Removing unwanted columns
// and adding new one is trivial. The below method has
// room form much improvement.
$columns_local = array();
if (isset($columns['cb']))
{
$columns_local['cb'] = $columns['cb'];
unset($columns['cb']);
}
if (isset($columns['name']))
{
$columns_local['name'] = $columns['name'];
unset($columns['name']);
}
// We add the Package Active to the second column
if (!isset($columns_local['product_package_active']))
$columns_local['product_package_active'] = "Active";
if (isset($columns['posts']))
$columns['posts'] = "Used";
$columns_local = array_merge($columns_local, $columns);
if (!isset($columns_local['product_package_unit_price']))
$columns_local['product_package_unit_price'] = "Price";
return array_merge($columns_local, $columns);
}

This should get the new columns added to the display table. You can save your code and verify. The table headers will be displayed. But the row content will be empty.

Adding Taxonomy Column Data

The table row content is added using another filter hook. Again, once of the function called from within edit_tags.php is the core function tag_rows(); This function in turn calls other functions. Eventually, the flow ends up in _tag_row() in template.php line 398. Much like the header logic various checks are made to see if we are dealing with a built-in taxonomy. If not then a dynamic filter hook is executed at line 483. This dynamic filter like the header filter uses the taxonomy to name the filter key unique. The filter key is
‘manage_${taxonomy}_custom_column’. Again placing in our taxonomy key ‘product_packages’ the complete filter key will be ‘manage_product_packages_custom_column’.

So back to our code we add another add_filter command to out init function. Then we add a new function to process the filter request.


<?php
add_action( 'init', 'product_init' );
function product_init()
{
// From Part I
register_taxonomy( 'product_packages', 'products',
array( 'hierarchical' => true,
'label' => __('Product Packages'),
'query_var' => false
)
);
// Added from Part II.
// This filter sets up a call to your function which will handle adding (and removing) items
// from the columns array. This filter passes up only one argument. The array of default headers.
add_filter( 'manage_product_packages_columns', 'admin_product_packages_column_headers, 10, 1);
// This filter sets up a call to display the contents of a Product Package row column.
// The filter passes up 3 argument. We only use the second and third arguments.
add_filter( 'manage_product_packages_custom_column', 'admin_product_packages_column_row', 10, 3 );
}
// This function we check the column name then pull in the row data using get_metadata()
function admin_product_packages_column_row( $row_content, $column_name, $term_id )
{
switch($column_name)
{
case 'product_package_active':
$product_package_active = get_metadata('product_packages', $term_id, 'product_package_active', true);
if (!$product_package_active)
$product_package_active = "yes";
return ucfirst($product_package_active);
break;
case 'product_package_unit_price':
return get_metadata('product_packages', $term_id, 'product_package_unit_price', true);
break;
default:
break;
}
}

And that is it. At this point you should now see your taxonomy custom meta fields display in new column when listing your taxonomy items.

Disable WordPress Plugins update indicator for inactive plugins

I have to really tip my hat to the guys that work hard on the core WordPress code at Automatic. In the last 12 months they taken the system to new heights with a complete redo of the admin interface. Adding many features to extend the core so that developers like myself can extend things even further.

Take for example the nice little number displayed on the Plugins menu item when some of your installed plugins are out of date. What a nice little feature. There is also an update display on the actual Plugins page the little yellow-ish box below a plugin row to indicate there is an update and the user needs to take action. From a usability stand point I think this sort of forward thinking is the reason I keep hacking in WordPress instead of other CMS-type systems like Drupal, Joomla, eZ Publish, etc.

wp-plugin-list-update-indicator

WordPress Nav Update Indicator

But I do have a major annoyance with this ‘feature’. Like many other WordPress users I have man plugins installed. At any given time I will have a third of the plugins disabled maybe because I was testing things or maybe I deactivated the plugin but didn’t want to uninstall it. My annoyance is that the plugin update indicators work on all plugins even those you don’t have active. Not good. Worse on the client sites I support I really don’t want the client to need to worry about updating inactive plugins.

Sure I know there are at least half a dozen plugins that will completely turn off the plugin and WordPress core update nag indicators. But I really don’t want that. I just don’t want to see update nag on those plugins I’m not currently using.

So I did some research on this lazy Sunday afternoon and figured out how to hide the update indicator on those inactive plugins. The code below will hide these inactive plugin from the update counter. When the plugin is re-activated the plugin update indicator will once again show in the sidebar menu and on the plugins listing.

The Code


function update_active_plugins($value = '') {
/*
The $value array passed in contains the list of plugins with time
marks when the last time the groups was checked for version match
The $value->reponse node contains an array of the items that are
out of date. This response node is use by the 'Plugins' menu
for example to indicate there are updates. Also on the actual
plugins listing to provide the yellow box below a given plugin
to indicate action is needed by the user.
*/
if ((isset($value->response)) && (count($value->response))) {
// Get the list cut current active plugins
$active_plugins = get_option('active_plugins');
if ($active_plugins) {
// Here we start to compare the $value->response
// items checking each against the active plugins list.
foreach($value->response as $plugin_idx => $plugin_item) {
// If the response item is not an active plugin then remove it.
// This will prevent WordPress from indicating the plugin needs update actions.
if (!in_array($plugin_idx, $active_plugins))
unset($value->response[$plugin_idx]);
}
}
else {
// If no active plugins then ignore the inactive out of date ones.
foreach($value->response as $plugin_idx => $plugin_item) {
unset($value->response);
}
}
}
return $value;
}
add_filter('transient_update_plugins', 'update_active_plugins'); // Hook for 2.8.x
//add_filter( 'option_update_plugins', 'update_active_plugins'); // Hook for 2.7.x

A note on the ‘add_filter’ lines just above. Seems there are two different hooks depending your the WordPress version. If you are running version 2.8.x or newer you should be safe to use the first add_filter line. If however you are still using 2.7.x then comment out the first add_filter an use the second one.

Installation

I really don’t plan to turn this into an official plugin for WordPress. So the simplest method of installation is to add it to your theme’s functions.php file.

Media Tags 2.2 plugin for WordPress Released

Over this past week I added quite a few features to the famous Media Tags plugin for WordPress. The list below details many of these new features

  1. Added a new tab to the Media Upload popup box. Anyone familiar with WordPress Post or Page entry is familiar with the popup provided to upload images and other media files. In this popup if you wanted to search for items using the handy Media Tags it was not possible. Now the user is provided with a new Tab labelled ‘Media Tags’. When the tab is clicked the user is presented with a listing of all Media Tags used on the site. Along with the Media Tag name there is a use could in the far right of the listing. This count if greater than zero is a link and will filter the Media Library (another Tab) listing for items from that Media Tags group.

    Below is a screenshot of the new popup tab.

    Media-Tags New Upload popup tab

    Media-Tags New Upload popup tab

  2. More control over the permalink prefix. The Media Tags plugin works with the WordPress Permalink rewrite system to provide ‘pretty’ URLs for the archive. For example if you have some media loaded and tagged on your site for say ‘Texas’. The you can display these items in an archive type listing by using the URL http://www.mysite.com/media-tags/texas/ This format should be familiar to most users of WordPress since Categories and Tags or handled in much the same way. This feature was added in Media Tags version 2.0 and has received much acclaim from the users. The problem is the prefix ‘/media-tags/’ was hard-coded into the plugin. I have a few users request a way to alter this prefix. Other than suggesting they edit the config file for the plugin there was not a good solution.

    So I starting thinking I would just build my own admin page where the user can set this permalink prefix. But I hated having to build a new admin page just for the one setting. Well over the weekend I found the solution of solutions. Why not just add my own field to the WordPress Settings -> Permalink page. This turned out to be quite easy using the new Settings API introduced into WordPress 2.7.

    Below is a screenshot of the new Media Tags Permalink option. The new field just below the standard Category and Tags fields.

    Media-Tag Permalink Slug Prefix

    Media-Tag Permalink Slug Prefix

  3. Playing nice with other plugins. I’ve used the Google Sitemap XML plugin for quite some time and generally install it by default onto any client site I’ve worked on. This is one of those plus plus plugins that can only help your site. Recently I had to figure out a way to include non-WordPress pages into the XML sitemap output. This is actually very easy to do as the plugin authors have provide a nice hook to allow this.

    So my next enhancement to the Media-Tags plugin was to include the Media Tag archives into the Google Sitemaps XML output. This feature is quite powerful since it just adds juice to Google content harvesting. Not wanting to hard-coded this feature into the plugin I ended up building that admin interface I mentioned in the previous point. There is only one option on the page (more to come soon). A simple Yes/No box to include/exclude the Media Tags archive from the Sitemap XML output. I assume most people will wan this but also know there is always the possibility some may now.

    Below is a screenshot of the new Media-Tag admin interface. Look for this under the standard WordPress Settings section.

    Media-Tags Admin Page

    Media-Tags Admin Page

  4. Along with the above mentioned new features I also cleaned up some code related issues. Most of these are under the covers cosmetic items and not related to any screen changes.

Media Tags Future Enhancements

Still on my list of features to add in some upcoming release is Media-Tags Cloud. This is still one of the most requested options for the sidebar. Still working on that code. Trying to follow some of the code written for the built-in WordPress Tags. pretty ugly stuff. Has to be a better way.

Other than the Media Tags Cloud I don’t have any big changes planned for the plugin. Then again the three features mentioned in this post were not planned at all. Just something that hit me on Friday that I started working toward.

So if there is a feature you just think would make the Media-Tags plugin rock for your blog please consider leaving a comment below.

Donations

If you enjoy using the Media Tags plugin or any of my other WordPress plugins, please consider making a donation to show your support. Anything is appreciated. Thanks.

See the Media-Tags Project page for up to date information regarding the Media-Tags plugin