Changes to WordPress edit-pages

I’ve been working on a client project since March. For this client I build a custom Event system that lets users signup to create events in the system. These events are created as actual WordPress Pages. Each Event is setup in such a way that the events State and City are nodes in the URL. So for example an event in Austin, TX would be http://www.siteurl.com/events/tx/austin/event-title. Pretty cool. All of these events are maintained via forms outside of WordPress. This was key because the client didn’t want the user to have access to the back-end system.

This Event system seemed to work great for the first few months. The problem was when the admin users go into WordPress admin to edit a page they have to first list all the pages in the system then select the page to edit. Well in the span of 4 months there are over 2500 event page in the system. Each event would create it’s event city and state pages as parents when needed. This caused the page listing (edit-pages.php) to take almost 90 seconds to load from the server. This was very frustrating if the user just wanted to change copy on a static page in the system. Many of the admin users got around this by copying the URL of the edit page. I wanted to offer a different solution. I started looking at the code.

Note: All of the following discussion is WP version 2.0.2.

The edit-pages.php appears to just be a simple building script that calls another function, page_rows() from the admin-functions.php. The problem I was seeing is there were some useless calls/queries being made. For example line 28 in edit-pages.php does a select all (select *) in the query to determine if to show the table headers. This is total overkill. You only really need the count of items not all the query result. Plus if you still for some reason needed the query column just pull in the columns needed not everything. Using the asterisk will pull in the biggest column, post_content.

Another big issue I saw was the admin library function page_rows from admin-functions.php was also running the same query but recursive. This in my mind was the reason for the long delay in building the display for the 2500 event pages. So I went to work. I first changed the query on line 28 of edit-pages.php to be just a count. If the count returned was greater than zero the code follows the logic to display the table header.

Next, because the Events pages were created into a hierarchy I wanted to change the way the page_rows function displayed content. I wanted to display the information in tiers. The default view of the page listing would display everything with a page parent of zero. There are the top-tier pages. I then added a new query to page_rows to check if each page contained children. If they did I displayed the title as a link. This link contained a GET variable which is the page id. This would in turn feed back to the edit_pages.php code and then we could display then next tier of page, pages that are children of the page_id provided for the GET variable. This would allow the user to drill through the tiers of content pages.

Next, I wanted to provide something to allow the user to return to the other tiers without needing to use the back button or start from the beginning. I wanted to provide a bread-crumb. This would be displayed above the table listing. The bread-crumb also would not be displayed if the user was on the top-tier page. This was easy enough to implement. Take the parent page_id passed in via the GET variable and call a new function get_parents_array in admin-functions.php. The function will build an array of each tier of the hierarchy from top to bottom by taking the parent id and determine if that page has a parent. All the way up to when the parent is zero. Then we take the returned array and display as a node listing.

My last change was to be nice to the user. If the user drills down 4 levels to find the page they need to edit I want to return the user to this same tier when they save the page. So on the page title link I set a cookie with the page_id for that level. Simple enough.

The zip file contains two files:
1. edit-pages.php – Replacement for the current /wordpress/wp-admin/edit-pages.php core file. Save a copy of your original file. Again these hack is just for WordPress 2.0.2. This hack will not work for WordPress 2.1!
2. admin-functions-supp.php – The contents of this file should be added to your existing /wordpress/wp-admin/admin-functions.php file. The two functions contained are unique and should not conflict withe existing functions.

Download the hack file