0

I've created a custom post type, with an easy permalink structure. Now I want to enhance this permalink structure with some extra information.

public function custom_post_mission() {
        $labels = array(
           ...
        );

        $args = array(
            'labels'        => $labels,
            'description'   => __( 'Holds our missions and specific data', TEXT_DOMAIN ),
            'public'        => true,
            'menu_position' => 5,
            'supports'      => array( 'title', 'author', 'editor' ),
            'has_archive'   => true,
            'menu_icon'     => plugin_dir_url( __FILE__ ).'img/mission.png',
            'register_meta_box_cb' => array( $this, 'add_custom_box' )
        );
        register_post_type( 'mission', $args ); 
    }

With the above coding I got the following permalink structure: http://localhost/wordpress/mission/<post-title>/

This structure I would like to improve to the following one: http://localhost/wordpress/mission/<year>/<month>/<post-title>/

How can I do this? It would be nice if there is a way to transfer the old permalink structure to the new one, but it's not necessary.

BR & Thanks,

mybecks

/E: enhanced my code with code example provided by ravi

public function custom_post_mission() {
            global $wp_rewrite;
            $labels = array(
               ...
            );

            $args = array(
                'labels'        => $labels,
                'description'   => __( 'Holds our missions and specific data', TEXT_DOMAIN ),
                'public'        => true,
                'menu_position' => 5,
                'supports'      => array( 'title', 'author', 'editor' ),
                'has_archive'   => true,
                'menu_icon'     => plugin_dir_url( __FILE__ ).'img/mission.png',
                'register_meta_box_cb' => array( $this, 'add_custom_box' )
            );
            register_post_type( 'mission', $args );

            $wp_rewrite->add_permastruct('mission', 'mission/%year%/%monthnum%/%mission%/', true, 1);
            add_rewrite_rule('mission/([0-9]{4})/(.+)/?$', 'index.php?mission=$matches[2]', 'top');
            $wp_rewrite->flush_rules(); // !!! 
        }

This creates the following permalink structure:

http://localhost/wordpress/mission/%year%/%monthnum%/<mission-title>/

But the %year% and %monthnum% placeholder couldn't be replaced with the corresponding values.

/E2: I finally get it to work. I needed a filter which resolves the placeholders:

add_filter('post_type_link', 'mission_permalink', 10, 3);

function mission_permalink( $permalink, $post_id, $leavename ) {
    $post = get_post($post_id);
        $rewritecode = array(
            '%year%',
            '%monthnum%',
            '%day%',
            '%hour%',
            '%minute%',
            '%second%',
            $leavename? '' : '%postname%',
            '%post_id%',
            '%category%',
            '%author%',
            $leavename? '' : '%pagename%',
        );

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

            $category = '';
            if ( strpos($permalink, '%category%') !== false ) {
                $cats = get_the_category($post->ID);
                if ( $cats ) {
                    usort($cats, '_usort_terms_by_ID'); // order by ID
                    $category = $cats[0]->slug;
                    if ( $parent = $cats[0]->parent )
                        $category = get_category_parents($parent, false, '/', true) . $category;
                }
                // show default category in permalinks, without
                // having to assign it explicitly
                if ( empty($category) ) {
                    $default_category = get_category( get_option( 'default_category' ) );
                    $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
                }
            }

            $author = '';
            if ( strpos($permalink, '%author%') !== false ) {
                $authordata = get_userdata($post->post_author);
                $author = $authordata->user_nicename;
            }

            $date = explode(" ",date('Y m d H i s', $unixtime));
            $rewritereplace =
            array(
                $date[0],
                $date[1],
                $date[2],
                $date[3],
                $date[4],
                $date[5],
                $post->post_name,
                $post->ID,
                $category,
                $author,
                $post->post_name,
            );
            $permalink = str_replace($rewritecode, $rewritereplace, $permalink);

            // wp_die($permalink );
        } else { // if they're not using the fancy permalink option
        }
        return $permalink;
    }

and I there was a small error in the add_rewrite_rule regexp. The correct one: add_rewrite_rule('mission/([0-9]{4})/([0-9]{2})/(.+)/?$', 'index.php?mission=$matches[3]', 'top');

  • You don't have to add permastruct and rewrite rule, just use the rewrite argument when you register your post type and WordPress does this for you. Also do not flush rules on every request as your code does now. – Milo Jan 3 '14 at 15:12
1

you can use and manage your permalink for custom post type. Custom Post Type Permalinks

enter image description here

add_action('init', 'my_rewrite');
function my_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_permastruct('typename', 'typename/%year%/%postname%/', true, 1);
    add_rewrite_rule('typename/([0-9]{4})/(.+)/?$', 'index.php?typename=$matches[2]', 'top');
    $wp_rewrite->flush_rules(); // !!!
}
  • thanks a lot for this plugin suggestion, it works fine. But I'm searching a programmatically way, too. BR – mybecks Jan 3 '14 at 10:21
  • thanks again for your helpful code example. I have adopt it so far, but it seems like the %year%/%monthnum% placeholder couldn't replaced with the corresponding values. – mybecks Jan 3 '14 at 11:10
  • Flushing rewrites on every request is very bad. – Milo Jan 3 '14 at 15:14

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.