3

I want to add a new endpoint to the author page, so that the URL looks like this:

http://example.com/writer/username/articles

So far, I have:

  • Changed the author base
  • Added a rewrite rule
  • Setup the query_vars
  • Added the endpoint
  • Used template_redirect to use my template

Result: 404 Page Not Found (even after flushing the rewrite rules). I can't figure out where the problem is. Also I'd like to add pagination to the endpoint. Below is my code:

Changed the author base:

function foo_change_author_base() {
    global $wp_rewrite;
    $wp_rewrite->author_base = 'writer';
}
add_filter( 'init', 'foo_change_author_base', 0 );

Added a rewrite rule:

function foo_rewrite_rule()
{
    add_rewrite_rule( 'writer/([^/]+)/articles(/(.*))?/?$', 'index.php?author_name=$matches[1]&articles=$matches[3]', 'top' );
}
add_action( 'init', 'foo_rewrite_rule' );

Setup query_vars:

function foo_add_vars($vars) {
    $vars[] = 'articles';   
    return $vars;
}
add_filter('query_vars', 'foo_add_vars');

Added the endpoint:

function foo_add_endpoint() {
    global $wp_rewrite;
    add_rewrite_endpoint( 'articles', EP_AUTHORS | EP_PAGES );
}
add_action( 'init', 'foo_add_endpoint');

And added my template:

function foo_rewrite_template()
{
    global $wp_query;

    if ( array_key_exists( 'articles', $wp_query->query_vars ) ) {
        include (get_template_directory_uri() . '/articles.php');
        exit;
    }
}
add_action( 'template_redirect', 'foo_rewrite_template' );
  • Have you update permalink from setting page ? – Strik3r Sep 6 '13 at 13:09
  • @Strik3r - Yes, I have. – chowwy Sep 6 '13 at 13:12
  • 1
    you don't need to add a rewrite rule and query var if you're adding an endpoint, that's what adding an endpoint does- it generates rules and creates a matching query var. – Milo Sep 6 '13 at 15:36
  • What the articles query var should contain? – gmazzap Sep 6 '13 at 15:37
  • @Milo Thanks. Do you have any idea why I'm getting a 404 message? Even when I remove the rewrite rule and query var functions, I'm still getting a 404 page not found. – chowwy Sep 6 '13 at 15:43
4

Your code should works. The line:

include (get_template_directory_uri() . '/articles.php');

Needs to have allow_url_include=1 in the server configration because you are trying to include a file via http. Can you check this?

You must know also that template_redirect should be use for a real redirect, a include() may have undesired effects here. I think what you really want is template_include:

add_filter('template_include', 'my_template_include');

function my_template_include( $template ) {
    global $wp->query;
    if ( array_key_exists( 'articles', $wp_query->query_vars ) ) {
        return get_template_directory() . '/articles.php';
    }
   return $template;
}

So here is my code:

function foo_change_author_base() {
    global $wp_rewrite;
    $wp_rewrite->author_base = 'writer';
}
add_filter( 'init', 'foo_change_author_base', 0 );

function foo_rewrite_rule()
{
    add_rewrite_rule( 'writer/([^/]+)/articles/page/([0-9]{1,})/?$', 'index.php?author_name=$matches[1]&articles=1&paged=$matches[2]', 'top' );
    //If you don't want the last trailing slash change the las /?$ to just $
    add_rewrite_rule( 'writer/([^/]+)/articles/?$', 'index.php?author_name=$matches[1]&articles=1', 'top' );
}
add_action( 'init', 'foo_rewrite_rule' );

function foo_add_vars($vars) {
    $vars[] = 'articles';   
    return $vars;
}
add_filter('query_vars', 'foo_add_vars');

function foo_add_endpoint() {
    add_rewrite_endpoint( 'articles', EP_AUTHORS );
}
//add_action( 'init', 'foo_add_endpoint'); // Commented out
// Edit: add_rewrite_endpoint is not needed when using add_rewrite_rule


// auto-add the articles endpoint to author links
function foo_author_link_filter( $link, $author_id, $author_nicename ) {
    return user_trailingslashit($link) . 'articles/';
}
add_filter( 'author_link', 'foo_author_link_filter', 20, 3);

add_filter('template_include', 'foo_template_include');
function foo_template_include( $template ) {
    global $wp_query;
    //You may need some other checks
    if ( array_key_exists( 'articles', $wp_query->query_vars ) ) {
        return get_template_directory() . '/articles.php';
    }
    return $template;
}

Now go to yoursite.com/writer/author_name/articles/

  • Thanks for your response. I checked, and allow_url_include is off. Is there a way to add my template to the template_redirect function without enabling allow_url_include? – chowwy Sep 6 '13 at 14:44
  • use the include function with a directory path, not a URL. For example include(get_template_directory().'/articles.php');. Anyway, template redirect should be used for a redirect, not a include. I think yo don't want the template_redirect action hook, I think you want template_include – cybmeta Sep 6 '13 at 14:48
  • Okay, I changed the include to get_template_directory(), and changed the hook to template_include, but got a white screen. I have the debugger on, and it shows no message. – chowwy Sep 6 '13 at 15:00
  • Maybe you have not used the template_include filter properly. See my edited answer. – cybmeta Sep 6 '13 at 15:16
  • Thanks for your help. Even with your code, I'm still getting the 404 page. No white screen, but not getting the template, either. By the way, I added the global $wp_query to your code. – chowwy Sep 6 '13 at 15:25
1

First if you add the endpoint, you don't need to add the rewrite rule. However if you want to handle the paging is better use the rewrite rule. Really 2 rewrite rules, on for pagen one for not paged.

After that, your articles query var is not intended to contain nothing just 'exist' or not. For this reason you can just set it to 1 if it exists.

Then just add a filter on template include, like @cybnet suggest in his answer.

All code should be something like:

function foo_change_author_base() {
    global $wp_rewrite;
    $wp_rewrite->author_base = 'writer';
}
add_filter( 'init', 'foo_change_author_base', 0 );

function foo_add_vars($vars) {
    $vars[] = 'articles';   
    return $vars;
}
add_filter('query_vars', 'foo_add_vars');  

function foo_rewrite_rule() {
    add_rewrite_rule( 'writer/([^/]+)/articles/page/([^/]*)$', 'index.php?author_name=$matches[1]&articles=1&paged=$matches[2]', 'top' );
    add_rewrite_rule( 'writer/([^/]+)/articles(.*)$', 'index.php?author_name=$matches[1]&articles=1', 'top' );
}
add_action( 'init', 'foo_rewrite_rule' );

function foo_rewrite_template( $template ) {
    if ( ! is_author() ) return $template;
    global $wp_query;
    if ( $wp_query->get('articles') ) return ( get_template_directory(). '/articles.php');
    return $template;
}
add_filter( 'template_include', 'foo_rewrite_template' );

// add a filter to author link, so 'get_author_posts_url' return the customized url
function foo_author_link_filter( $link, $author_id, $author_nicename ) {
    return user_trailingslashit($link) . 'articles/';
}
add_filter( 'author_link', 'foo_author_link_filter', 20, 3);

That will works good with pagination. Only remember to save the permalink settings again.


Below a print-screen from my test environment where I test this code:

enter image description here

  • I also tried your code and got the same result as the other answer. In the browser bar - example.com/writer/username/:/example.com and a 404 message. – chowwy Sep 6 '13 at 16:21
  • That's exactly what I'm typing. example.com/writer/username/articles, and what I end up with is example.com/writer/username/:/example.com. Let me double check. – chowwy Sep 6 '13 at 16:27
  • Yes, I double checked and the URL is automatically changing. The username is correct. I'm trying to see what it could be. – chowwy Sep 6 '13 at 16:32
  • Okay, I've cleaned the browser cache and disabled a couple of plugins. Now it's resolving to example.com/articles. – chowwy Sep 6 '13 at 16:48
  • I'm sorry to say this but your answer should be an edit of mine. It includes almost the same code of my answer plus I was who points @chowwy his main problem of using template_redirect action hook incorrectly as well the suggestion of using template_include instead for his purpose. – cybmeta Sep 6 '13 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.