404 Errors When Integrating Zenphoto With WordPress
The Problem
In my previous post, 'A Basic WordPress And Zenphoto Integration', I noted that my Zenphoto integration had a problem with silent 404 errors. Although the pages of the gallery were being displayed nicely skinned with my WordPress theme and everything looked okay, behind the scenes they were being delivered to the browser with a HTTP status of 404, "not found". Obviously this is a very bad thing, as once I manage to get search engines indexing my site they would see the 404 and assume that the pages were not available, ignoring the fact that the content was actually there.
The Details
Some comments on the original post that I used to aid my integration suggested that this was being caused by the URL rewriting used by both WordPress and Zenphoto. Taking this lead, I did a few simple tests to narrow the location of the problem. First I disable the URL rewriting in Zenphoto. No change. Second, I disabled the URL rewriting in WordPress. Bingo; the gallery pages were now being served with a HTTP status of 200, but now my WordPress URLs were decidedly less than friendly.
Time for a bit of digging into how WordPress handles URL rewriting. Actually, not much digging was needed in this case. As the gallery is located in a sub-folder under the WordPress installation, I figured all that was needed was to make WordPress ignore this entire sub-folder when it comes to parsing rewritten URLs. This led me to 'WP_Rewrite' in the WordPress Codex. This class, defined in wp-includes/rewrite.php, handles all of the URL rewriting rules used by WordPress.
Using the single global instance of this class, $wp_rewrite, plugins can modify the rules at various points, such as specifically for permalink rewriting or maybe search URL rewriting. There are also two hooks for more global modifications. Plugins can add filters for 'rewrite_rules_array', which allows processing of the whole set of rewrite rules once they have been produced. Alternatively you can add an action for 'generate_rewrite_rules' which runs after all of the rules have been created.
The Solution
There are two possible solutions we could implement. We could add a filter for 'rewrite_rules_array' and insert a rewrite condition stating that the request URI should not start with our gallery path, such as:
-
RewriteCond %{REQUEST_URI} !^zenphoto
Alternatively we can add an action for 'generate_rewrite_rules' to add a rewrite rule indicating that our gallery path should not be rewritten. The eventual rewrite rule would be something like:
-
RewriteRule ^zenphoto - [L]
Using '-' as the substitution just means no substitution, i.e. no rewrite. An very basic example script for a plugin might be:
-
add_action('generate_rewrite_rules', 'zp_add_rewrite_rules'); -
-
function zp_add_rewrite_rules($wp_rewrite) -
{ -
$new_rules = array('^zenphoto' => '-'); -
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules; -
}
This script simply defines the new rule as an associative array with the pattern as the key and the substitution as the value. This is then added to the start of the existing array of rules. This is only a very basic example; there is much more that can be done with collections of rules but in this case this is all that is required. I have decided to go with this second option as it is pretty straight-forward and easy to understand. There is one gotcha with this method though. By default WordPress loads pre-prepared rewrite rules from the database, so our new action would never run. To avoid this issue, you must flush the stored rules on each request, to ensure that any new rules defined by your plugin are added. The following script will do this by defining an initialization action for your plugin:
-
add_action('init', 'zp_flush_rewrite_rules'); -
-
function zp_flush_rewrite_rules() -
{ -
global $wp_rewrite; -
$wp_rewrite->flush_rules(); -
}
A combination of these two scripts make a plugin that will fix 404 errors in a WordPress and Zenphoto integration with a shared theme. This can be expanded with some logic borrowed and extended from Einar Egilsson's integration plugin that attempts to determine the path of the Zenphoto installation. This can be overridden by setting the $gallery_path variable:
-
add_action('init', 'zp_flush_rewrite_rules'); -
-
function zp_flush_rewrite_rules() -
{ -
global $wp_rewrite; -
$wp_rewrite->flush_rules(); -
} -
-
add_action('generate_rewrite_rules', 'zp_add_rewrite_rules'); -
-
function zp_add_rewrite_rules($wp_rewrite) -
{ -
$names = array('zenphoto', 'photos', 'gallery'); -
$gallery_path = ''; -
-
if ($gallery_url == '') -
{ -
foreach($names as $ix => $name) -
{ -
// Will be at current level in WP and up a level in ZP -
if (is_dir("$name") || is_dir("../$name")) -
{ -
$new_rules = array("^$name" => '-'); -
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules; -
} -
} -
} -
else -
{ -
$new_rules = array("^$gallery_path" => '-'); -
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules; -
} -
}
Simply wrap this script up as a plugin and add it to your WordPress installation and once activated it will take immediate effect. Click here to download one I prepared earlier.
July 3rd, 2010 - 22:32
Wow! Great fix. Was suffering that frustrating issue and thanks to your plugin it’s gone away. Much easier than dealing with htaccess headaches
July 10th, 2010 - 12:37
Glad I could help :)
August 2nd, 2010 - 06:12
I’m having a crazy problem; tried this fix, but a no go. Have installed everything and edited everything…but the Zenphoto link in WP gives a “cannot load.” page error. I can access the zenphoto admin separately, but really, really need this stupid thing to work. I have spent days agonizing over photo album codes and finally thought I’d found a decent one… am starting to think I was wrong….
January 9th, 2011 - 00:33
Ben, Can you help – when I activate your plugin it breaks the menu system that wordpress offers – so though it finds zenphoto – any sub menus i create – it comes back with a page not found error – now usig the handcrafted theme http://www.halinasplace.com.au/photography/
March 5th, 2011 - 15:31
Thanks for great job, this plugin really helps to get rid off 404 errors.
However I had troubles installing this plugin to wordpress 3.1. After copying it to /plugins directory it didn’t show up in plugin list in admin panel. I have removed copyright notice from the header and it works ok. I guess there were some special symbols breaking headers and preventing plugin from showing up in the list.
One additional question: is it ok that it flushes stored rules on each request? I am afraid that it slowed site a bit …
April 12th, 2011 - 10:02
Had to just say thanks I’d noticed this on my zp intergration but didn’t have a clue where to start looking to resolve it. Your plugin has just saved me a lot of head scratching (and swearing) nice work and thanks for making the plugin available!!