8

I'm building a Wordpress site with several custom post types. Every post type is a different magazine. I have also a custom meta fields for a magazine year and issue.

I would like to have urls (used archive.php):

http://my_site/magazine/name/
http://my_site/magazine_name/year/
http://my_site/magazine_name/year/issue/

I made it by code:

function magazine_rewrite_tag() {
    add_rewrite_tag('%issue_year%', '([0-9]{4})');
    add_rewrite_tag('%issue%', '([0-9])');
}
add_action('init', 'magazine_rewrite_tag', 10, 0);

and:

function magazine_rewrite_rules() {
    add_rewrite_rule('^([a-z]+)/([0-9]{4})/([0-9])?', 'index.php?post_type=$matches[1]&issue_year=$matches[2]&issue=$matches[3]', 'top');
    add_rewrite_rule('^([a-z]+)/([0-9]{4})?', 'index.php?post_type=$matches[1]&issue_year=$matches[2]', 'top');
}
add_action('init', 'magazine_rewrite_rules');

Off course I have also a custom queries in archive.php. And it works fine.

But now, my urls for single articles doesn't work. By default, it is:

http://my_site/magazine/post-title

but it's show all articles from magazine like url (and it used archive.php template):

http://my_site/magazine/

How add properly rewrite rules for single custom posts? It is possible, I would like to have urls for single post (only for chosen custom post types) in this format:

http://my_site/magazine/year/issue/post-title
  • Multiple notes: (1) The 4th argument is the number of arguments a filter or action takes. And 10 is the default priority. You can leave both off in that case … or try a higher number. (2) Have you checked the resulting rewrite rules? Also make sure you check the order of those rules as they are processed in their order. Dump $GLOBALS['wp_rewrite']. (3) Have you added query_vars that might conflict? – kaiser Jun 14 '16 at 12:59
4

I found solution! A Monkeyman Rewrite Analyzur plugin was very helpful: https://wordpress.org/plugins/monkeyman-rewrite-analyzer/

So now, I have such working urls...

single.php:

/magazine-name/issue-year/issue/article-name

archive.php:

/magazine-name/issue-year/issue
/magazine-name/issue-year
/magazine-name

On a custom post editor page in wp-admin I use Advanced Custom Fields plugin for issue year and issue. You can also define meta fields by yourself.

Next I added rewrite tags for issue year and issue:

function custom_rewrite_tag() {
    add_rewrite_tag('%issue_year%', '([0-9]{4})' );
    add_rewrite_tag('%issue%', '([0-9]+)' );
}

add_action('init', 'custom_rewrite_tag');

Next, I added rewrite rewrite rules for any combination of urls:

function custom_rewrite_rule() {
    // URL: /magazine/year/issue/title
    add_rewrite_rule('^([^/]+)/([0-9]{4})/([0-9])/(.?.+?)?(:/([0-9]+))?/?$', 'index.php?post_type=$matches[1]&issue_year=$matches[2]&issue=$matches[3]&name=$matches[4]', 'top');

    // URL: /magazine/year/issue
    add_rewrite_rule('^([^/]+)/([0-9]{4})/([0-9])?$', 'index.php?post_type=$matches[1]&issue_year=$matches[2]&issue=$matches[3]', 'top');

    // URL: /magazine/year
    add_rewrite_rule('^([^/]+)/([0-9]{4})?$', 'index.php?post_type=$matches[1]&issue_year=$matches[2]', 'top');
}

add_action('init', 'custom_rewrite_rule');

At the end I replace standard urls for my own, with issue year and issue

function custom_permalink($url, $post) {
    if ($post->post_type == 'magazine-name-1' || $post->post_type == 'magazine-name-2' || $post->post_type == 'magazine-name-2' ) {
        global $post;

        $post_type = $post->post_type;
        $issue_year = get_field('issue_year', $post->ID); // ACF; for meta: get_post_meta($post->ID, '$issue', true);
        $issue = get_field('issue', $post->ID); // ACF

        $url = str_replace( $post_type . '/', $post_type . '/' . $issue_year . '/' . $issue . '/' , $url);
    }
    return $url;
}
add_filter('post_type_link', 'custom_permalink', 10, 2);

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.