4

I've created custom permalinks for various custom post types on a website. They all worked. Until recently I added another one, which I cannot get to work 8-o. The "company" struct is not working and gives a 404..

Can anyone spot a flaw in my thinking or put me on the right track? I must be forgetting something very stupid ;-)

Oh, I also went to the permalink settings page to flush the old permalinks / permalink cache / ...

Here's the code for the custom structure:

// rewrite rewrite
global $wp_rewrite;

$wp_rewrite->add_rewrite_tag("%merkname%", '([^/]+)', "merk=");
$wp_rewrite->add_permastruct('merk', '/merken/%merkname%', false);

$wp_rewrite->add_rewrite_tag("%modelname%", '([^/]+)', "model=");
$wp_rewrite->add_permastruct('model', '/merken/%merkname%/%modelname%', false);

$wp_rewrite->add_rewrite_tag("%carname%", '([^/]+)', "car=");
$wp_rewrite->add_permastruct('car', '/merken/%merkname%/%modelname%/%carname%', false);

$wp_rewrite->add_rewrite_tag("%companyname%", '([^/]+)', "company=");
$wp_rewrite->add_permastruct('company', '/company/%companyname%', false);

function kw_custom_permalink($permalink, $post, $leavename) {

    if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {

        $merkname='';
        $modelname='';
        $carname='';
        $companyname='';

        if ( strpos($permalink, '%merkname%') !== false ) {
            $merkname = $post->post_name;
        }

        if ( strpos($permalink, '%modelname%') !== false ) {
            $merkpost = get_post( get_post_meta( $post->ID, "merk", true ) );
            $merkname = $merkpost->post_name;
            $modelname = $post->post_name;
        }

        if ( strpos($permalink, '%carname%') !== false ) {
            $merkpost = get_post( get_post_meta( $post->ID, "_car_merk", true ) );
            $merkname = $merkpost->post_name;

            $modelpost = get_post( get_post_meta( $post->ID, "_car_model", true ) );
            $modelname = $modelpost->post_name;

            $carname = $post->post_name;
        }

        if ( strpos($permalink, '%companyname%') !== false ) {
            $companyname = $post->post_name;
        }

        $permalink = str_replace(
            array(
                $leavename? '' : '%postname%',
                '%post_id%',
                '%merkname%',
                '%modelname%',
                '%carname%',
                '%companyname%',
                $leavename? '' : '%pagename%',
            ), 
            array(
                $post->post_name,
                $post->ID,
                $merkname,
                $modelname,
                $carname,
                $companyname,
                $post->post_name,
            ), 
            $permalink
            );

    }
    return $permalink;
}
add_filter('post_type_link', 'kw_custom_permalink', 10, 3);
2
  • You shouldn't add your permastructs etc in the global namespace, you should hook into the appropriate place then modify $wp_rewrite as ordering can matter. Also have you tried flushing permalinks?
    – Tom J Nowell
    Dec 3, 2014 at 11:48
  • Flushing I tried. What would be the appropriate hook for adding permastructs? "init"?
    – Jos
    Dec 5, 2014 at 8:31

1 Answer 1

2

You're currently placing your rewrite rules in the global scope, which means they execute as soon as your file is loaded, which may be too early. Instead try adding them on the init hook, or rewriting them to use the generate_rewrite_rules filter instead, e.g.:

add_action('generate_rewrite_rules', 'themes_dir_add_rewrites');

function themes_dir_add_rewrites() {
  $theme_name = next(explode('/themes/', get_stylesheet_directory()));

  global $wp_rewrite;
  $new_non_wp_rules = array(
    'css/(.*)'       => 'wp-content/themes/'. $theme_name . '/css/$1',
    'js/(.*)'        => 'wp-content/themes/'. $theme_name . '/js/$1',
    'images/wordpress-urls-rewrite/(.*)'    => 'wp-content/themes/'. $theme_name . '/images/wordpress-urls-rewrite/$1',
  );
  $wp_rewrite->non_wp_rules += $new_non_wp_rules;
}

Taken from Hongkiat

Or

function josfaber_add_rules() {
    global $wp_rewrite;

    $wp_rewrite->add_rewrite_tag("%merkname%", '([^/]+)', "merk=");
    $wp_rewrite->add_permastruct('merk', '/merken/%merkname%', false);

    $wp_rewrite->add_rewrite_tag("%modelname%", '([^/]+)', "model=");
    $wp_rewrite->add_permastruct('model', '/merken/%merkname%/%modelname%', false);

    $wp_rewrite->add_rewrite_tag("%carname%", '([^/]+)', "car=");
    $wp_rewrite->add_permastruct('car', '/merken/%merkname%/%modelname%/%carname%', false);

    $wp_rewrite->add_rewrite_tag("%companyname%", '([^/]+)', "company=");
    $wp_rewrite->add_permastruct('company', '/company/%companyname%', false);
}
add_action( 'init', 'josfaber_add_rules' );
3
  • It didn't solve the problem. But I see now this is the correct way to do this, so thank you for this one!
    – Jos
    Dec 9, 2014 at 8:44
  • Wow, I thought I'd tried a different slug, but I did not change the post type name. I now tried with a fresh custom post type 'Business' and that works correctly. Anyone knows if 'company' might be a reserved slug? Or to prevent future issues, is there a list of reserved slugs to be found somewhere?
    – Jos
    Jan 8, 2015 at 11:42
  • Company isn't reserved but that question would be interesting and I'm sure it's been asked and answered already
    – Tom J Nowell
    Jan 8, 2015 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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