INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Creating a category overview page

Creating a category overview page

(OP)

I'm trying to create a top-level category overview page for my theme so that if I visit "/category/", I'll see a page which shows me all top-level categories.

I've been using code from this post here:

http://wordpress.org/support/topic/199601

but am having no joy in getting it to redirect anywhere - in fact, I don't see anything to indicate that the filter function is ever being run.

I've tried putting the code in a plugin, in my theme, and inline in the wordpress PHP files, but nothing seems to happen.

I've tried with the new category (as suggested in the original post), and with new PHP files I've created - but no redirect ever seems to happen.

I know the add_filter call is being run, as it returns true... but nothing else seems to happen.

How would I go about debugging this? I've tried "echo" statements in the filter function, but cannot find hide nor hair of them when viewing the page source.

Thanks,

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

dan

the filter is only run once when you save the permalink info in the admin panel.  so if you have not done that yet, please try and post back.

debugging wp is a bitch.  i save debug output to a file mostly.  but since this code is rarely called you might email debug output to yourself.

CODE --> a bit tweaked

public function rewrite($data){
        $catBase = get_option('category_base');
if (substr($catBase,-1) !== "/") $catBase .= "/";
        $array[$catBase.'$'] = 'index.php?category_name=overview';
        $merge = array_merge($data, $array); //use array_merge to force this one on to the end so it gets matched last
                 //debug
               mail ('myaddress', 'wpdebugoutput', print_r($merge), "From: myaddress \r\n");
               return $merge;
    }

you should see output like this

CODE

Array
(
    [category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
    [category/(.+?)/?$] => index.php?category_name=$matches[1]
    [/category/$] => index.php?category_name=overview
)

note the last line

RE: Creating a category overview page

oops.. add the true argument to print_r too

CODE

print_r($merge, true);

otherwise it will output to the screen.

RE: Creating a category overview page

(OP)
Hmm.. I'm still having no luck. At least I know the function is being called now, though (debugging via email might be quirky, but it works!)

Here's the function I have:

CODE

function add_category_overview_page($data) {
    $catBase = get_option('category_base');
    if (substr($catBase,-1) !== "/") $catBase .= "/";

    $array[$catBase.'$'] = 'index.php?category_name=JavaScript';

    $merge = array_merge($data, $array); //use array_merge to force this one on to the end so it gets matched last

mail ('myaddress', 'Debug', print_r($merge, true), "From: myaddress \r\n");

    return $merge;
}
add_filter('category_rewrite_rules', 'add_category_overview_page');

I've chosen to use a pre-existing category for the purposes of this test. I know the URL I'm trying to redirect to works, as if I manually visit "/index.php?category_name=JavaScript", I get sent to the JavaScript category.

The output from the email is as follows:

CODE

Array
(
    [category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
    [category/(.+?)/?$] => index.php?category_name=$matches[1]
    [/$] => index.php?category_name=JavaScript
)

Visiting "/category" or "/category/" still sends me to my 404 page.

It looked a bit odd to me that the last item was "[/$]" instead of "[category/$]" ("$catBase" is being returned from the "get_option" call as ""), so I tried forcibly setting it:

CODE

function add_category_overview_page($data) {
    $catBase = get_option('category_base');

    if (substr($catBase,-1) !== "/") $catBase .= "/";

$catBase = "category/";

    $array[$catBase.'$'] = 'index.php?category_name=JavaScript';

    $merge = array_merge($data, $array); //use array_merge to force this one on to the end so it gets matched last

mail ('dan@test.co.uk', 'Debug 3', print_r($merge, true), "From: myaddress \r\n");

    return $merge;
}

This did change the debug info as expected:

CODE

Array
(
    [category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
    [category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
    [category/(.+?)/?$] => index.php?category_name=$matches[1]
    [category/$] => index.php?category_name=JavaScript
)

But visiting "/category" or "/category/" still gave the same results (the 404 page).

I'm thinking the next step is to add logging to WP to show what rules it is matching against when any page is requested, and see if it matches the last one or not. Does this sound logical, or would there be a better place to start?

Thanks,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/

RE: Creating a category overview page

(OP)

In case it makes a difference, I should have mentioned that I'm using the "Month and name" permalink structure ("/%year%/%monthnum%/%postname%/")

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

(OP)

I've gone on to try various things, including setting my category_base to "wibble" (now I understand why it was blank) and reversing the order of those rules so my one appeared at the top instead of at the bottom, both without joy.

I found that if I removed the '$' from the end of the rule that any category matched, so visiting a non-existent category "/wibble/foo" gave me the overview page. However, it still didn't match "/wibble" or "/wibble/" - which just seems really odd!

I'll keep cracking away at it... I'm determined that this is possible without using the hacky method of setting a page permalink to '/category/'.

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

that does sound strange; and points to some sloppy coding in the wp_rewrite class.  I suspect that we'll have to delve into the WP core to see the whys of this behaviour and the adjust the plugin accordingly.  i'll post back later.

RE: Creating a category overview page

(OP)

Got it (well, with a caveat)!

After finally finding my way (via the 404 handler) to "parse_request" in "classes.php", I found that the rule would never match because what was being matched against never ended in a '/'.

So removing the trailing '/' from $catBase but adding the '$' check back in gives me something that works nicely:

CODE

function add_category_overview_page($data) {
    $catBase = get_option('category_base');
    $catBase = trim($catBase, '/');

    $array[$catBase.'$'] = 'index.php?category_name=JavaScript';

    $merge = array_merge($data, $array); //use array_merge to force this one on to the end so it gets matched last
    return $merge;
}
About that caveat, however. If $catBase is empty (i.e. using the WP default), then the rule is '[$]' which means you can never get to your homepage.

I'm quite happy to set my catBase to "category", although it'd be nice not to have to. But beggars can't be choosers, as they say.

Thanks for all your help (and pushes in the right direction) on this one, jpadie.

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

great stuff!  will you post the soln back in the wp.org forum?

RE: Creating a category overview page

(OP)

Now comes the job of trying to get the redirect to go to an arbitrary PHP file instead of 'index.php'.

You'd have thought that simply replacing 'index.php?category_name=JavaScript' with 'categoryoverview.php' would do the job, but all that seems to happen is the home page displays instead.

I'm guessing that parse_request is assuming all requests are for 'index.php', and so only takes an interest in the parameters present, especially as when I set the redirect URL to this:

CODE

$array[$catBase.'$'] = 'aNonExistentFileNameHere.php?category_name=JavaScript';

I still end up at the JavaScript category page.

So perhaps I'll have to use the "template_redirect" hook at the top of the 404 page instead... but that seems really dirty as well.

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

Dan

i've gone back to the drawing board and have thought of a better way to achieve your aim (if you're really trying to divert to a page outside of the WP managed hierarchy).  try this code (replacing rathercurious.net with your own choice!)

CODE

<?php
/*
Plugin Name: CategoryOverview
Plugin URI: http://rathercurious.net
Description: This.
Author: Justin Adie
Version: 1.0
Author URI: http://rathercurious.net
*/

add_action('parse_request', array('category_overview', 'category_overview'));
class category_overview{
    public function category_overview(&$wp){
         $catBase = trim(get_option('category_base'),'/');
    
        if ($wp->request === $catBase) {
            ob_end_clean();
            wp_redirect('http://rathercurious.net');
            exit;
        } else {
            return $info;
        }
    }
}
?>

RE: Creating a category overview page

(OP)

That's a key point, though - I want the page to be inside the hierarchy so that it can access all the WP vars, etc.

I know I can do this now by forwarding to a category that doesn't exist, but didn't want to have to attempt to remove that category from every possibly place it might have appeared, thus the need for another PHP file.

I found that I could do this to give me a redirect (much the same result as your latest code):

CODE

global $wp_rewrite;
$wp_rewrite->add_external_rule('category$', 'categoryoverview.php');

although the same issue arose - how to access the WP vars.

Another train of thought was to test the URL in "404.php" and redirect if it was "/category/", but then I didn't want to deal with changing the 404 status codes or letting WP know it wasn't really a 404 page.

So I think at the moment, I'm going to go back to my original idea - having a post with permalink "/category/" and testing the URL in "page.php".

It's not pretty, but it works while letting me access all WP vars, etc, and doesn't require me to hide a category from every possible place it might appear.

Thanks again for your help, though!

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

(OP)

For anyone else who might also find this useful, here's what I ended up doing:

- Created a page with permalink "/category/"

- Added the following 2 functions to the top of "page.php":

CODE

// Code snippet used from the "parse_request" function in "classes.php"
function get_permalink_excluding_host() {
    $req_uri = $_SERVER['REQUEST_URI'];
    $req_uri_array = explode('?', $req_uri);
    $req_uri = $req_uri_array[0];

    $home_path = parse_url(get_option('home'));
    if ( isset($home_path['path']) )
        $home_path = $home_path['path'];
    else
        $home_path = ';
    $home_path = trim($home_path, '/');

    // Trim path info from the end and the leading home path from the
    // front.  For path info requests, this leaves us with the requesting
    // filename, if any.  For 404 requests, this leaves us with the
    // requested permalink.
    $req_uri = str_replace($pathinfo, ', rawurldecode($req_uri));
    $req_uri = trim($req_uri, '/');
    $req_uri = preg_replace("|^$home_path|", ', $req_uri);
    $req_uri = trim($req_uri, '/');

    return $req_uri;
}

function is_category_overview_page() {
    return (get_permalink_excluding_host() == "category");
}

- Outside the loop in "page.php" add the following:

CODE

<? if (is_category_overview_page()) {
    include (TEMPLATEPATH . '/categoryoverview.php');
} ?>

- Created a file "categoryoverview.php" in my template folder with my custom content.

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

Dan

sorry - i was not precise enough.  there is no reason why you cannot redirect to a page within the wp hierarchy either.  if you know the page url you can just add that.

you can also change manipulate the WP object a bit more by, for example, setting

CODE

$info->matched_query = pagename=slugname&page=1
or similar.

i think that's better than tricking the 404 error page.

RE: Creating a category overview page

This was annoying me as everything i've suggested so far has been a compromise solution.  so i've gone back again to first principles and had a look at the hooks that exist.  http://adambrown.info was very useful in this as it is a real time code parser for the hooks and actions.

so here's my latest attempt at trying to fulfil the requirements you've set:

CODE

<?php
/*
Plugin Name: CategoryOverview
Plugin URI: http://rathercurious.net
Description: This.
Author: Justin Adie
Version: 1.0
Author URI: http://rathercurious.net
*/

add_action('parse_request', array('category_overview', 'cat_overview'));
class category_overview{
    public function cat_overview(&$wp){
         $catBase = trim(get_option('category_base'),'/');
        file_put_contents(ABSPATH.'/debug.txt', print_r($wp, true),FILE_APPEND);
        if ($wp->request === $catBase) {
            add_action('template_redirect', array('category_overview', 'applyTemplate'));
        } else {
            return $info;
        }
    }
    public function applyTemplate($template){
        include TEMPLATEPATH .'/categoryoverview.php';
    }
}
?>

RE: Creating a category overview page

(OP)

Aaah - so create the page with known permalink, but just use a different method to redirect to it. That certainly sounds like a much cleaner method.

What I tried using your code above is:

CODE

add_action('parse_request', 'category_overview');
function category_overview(&$wp){
    $catBase = trim(get_option('category_base'),'/');
    if ($catBase == "") $catBase = "category";

    if ($wp->request === $catBase) {
        ob_end_clean();
        wp_redirect(bloginfo('url') . "/" . $catBase . "/");
        exit;
    } else {
        return $info;
    }
}

Which would redirect to the "/category/" page whose permalink I've set up.

I know that:

CODE

bloginfo('url') . "/" . $catBase . "/"

produces the right URL, but what actually happens is I see a blank page with the base URL for the blog printed on it. If I hard-code a different URL, it forwards as expected.

I'm guessing that what is happening is that the action is running when the real page is being loaded, redirecting back to itself infinitely, and somehow WP is trapping this?

Right now, the only way I can get this working is with my original hacky method - which is annoying as hell (it just seems wrong, but it's the only way I can get to work so far).

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

(OP)

Ah - your post above came in after I started drafting mine... so I'll take a look at that now.

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

(OP)

I think it's now about the best it has been so far smile.

I've taken the code from your last post (nice one), added an "exit" call at the end of my 'categoryoverview.php' (to stop multiple content being rendered') and added back my page with permalink of '/category/' (to stop the 404 code being returned to the browser).

So I can just ignore the '/category/' page and edit the 'categoryoverview.php' file instead.

Nice!

Thanks again,

Dan



 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

yup - i thought a template based soln looked neatest if you wanted all the wp vars available and (assumedly) the look and feel of a standard page with your own content managed on it.

i don't need the exit() call on my installation, but perhaps our templates are sufficiently different - i (obviously) deleted the loop.

my category overview page just looks like this

CODE

<?php
get_header();
echo <<<HTML
    <div id="content" class="narrowcolumn">
        this is the category overview template

    
    </div>
HTML;
get_sidebar();
get_footer();

I didn't spot the 404.  that's a bit ugly.  i don't think you need to kludge a permalinked page though.  this extra plugin call should do the trick

CODE

<?php
/*
Plugin Name: CategoryOverview
Plugin URI: http://rathercurious.net
Description: create a special output for blank category permalinks
Author: Justin Adie
Version: 1.0 (or something)
Author URI: http://rathercurious.net
*/

add_action('parse_request', array('category_overview', 'cat_overview'));
class category_overview{
    public function status ($status_header, $header, $text, $protocol){
        $header = 200;
        $text = 'OK';
        return "$protocol $header $text";
    }

    public function cat_overview(&$wp){
         $catBase = trim(get_option('category_base'),'/');
        
        if ($wp->request === $catBase) {
            add_filter('status_header', array('category_overview', 'status'), 12, 4);
            add_action('template_redirect', array('category_overview', 'applyTemplate'));
        } else {
            return $info;
        }
    }
    public function applyTemplate($template){
        include TEMPLATEPATH .'/categoryoverview.php';
    }
}
?>


 

RE: Creating a category overview page

(OP)

That's a lot nicer than having to rely on a post having a certain permalink.

The only thing I'm finding now is that my "header.php" is setting the page title to "Page not found". I traced this back to "is_404()" returning true, which in turn came from "handle_404()" in "classes.php" not finding any posts for the URL (count($wp_query->posts) == 0).

I tried getting around this by adding back a "category_rewrite_rules" filter to redirect "/category/" to the homepage, but found that the Categories page then had the same title as the homepage (it was obvious only after I'd tried it bigsmile).

I got around this by modifying your function to set (or clear) a new global boolean, "$wp_query->is_category_overview". Then I wrote an "is_category_overview" function which my "header.php" picked up on to show the correct title.

That last hurdle was setting the title (currently "Page not found") which I did with the wp_title filter.

The finished code looks like this:

CODE

/*** Catergory Overview - START ***/
// These functions add the ability to redirect "/category/" to "categoryoverview.php" in the theme folder, which can be customised as a top-level
// category overview page. Many thanks to Justin Adie, http://rathercurious.net. See http://www.tek-tips.com/viewthread.cfm?qid=1497505 for more information.

function is_category_overview() {
    global $wp_query;
    return $wp_query->is_category_overview;
}

// Because WP will not return "/category/" if you have left this blank.
function get_category_base() {
    $catBase = trim(get_option('category_base'),'/');
    if (empty($catBase) || $catBase == "") $catBase = "category";
    return $catBase;
}

// Allow WP to pick up on the request for "/category/" and perform the redirect
function add_category_overview_page(&$wp) {
    global $wp_query;

    $catBase = get_category_base();

    //file_put_contents(ABSPATH.'/debug.txt', print_r($wp, true),FILE_APPEND);
    if ($wp->request === $catBase) {
        $wp_query->is_category_overview = true;
        add_filter('status_header', 'set_category_overview_page_status', 12, 4);     // 12 = $priority (default = 10, lower = earlier execution), 4 = num of args function takes (default = 1)
        add_action('template_redirect', 'load_category_overview_page');
        add_filter('wp_title', 'set_category_overview_page_title');
    } else {
        $wp_query->is_category_overview = false;
        return $info;
    }
}

function set_category_overview_page_title($title, $sep) {
    return "Category overview";
}

function load_category_overview_page($template) {
    include TEMPLATEPATH .'/categoryoverview.php';
}

// Stops a 404 being returned to the browser.
function set_category_overview_page_status($status_header, $header, $text, $protocol) {
    $header = 200;
    $text = 'OK';
    return "$protocol $header $text";
}
add_action('parse_request', 'add_category_overview_page');
/*** Catergory Overview - END ***/

So I've got everything I need - no unecessary pages, not 404 code, and full access to the WP data.

I can't thank you enough for you help on this one, so perhaps a virtual beer will suffice: cheers

Thanks again,

Dan

 

Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page @ Code Couch
http://www.codecouch.com/dan/


 

RE: Creating a category overview page

great  stuff!

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close