Portfolio single post, remove base / slug

WordPress 9 posts 2 voices

  1. Hi Justin,

    Is there a way, I could make portfolio permalinks behave like standard pages?

    Like for example I have urls like /projects/my-test-project/ but I would like it be like /my-test-project/ without ‘/projects/’

    Note: projects is **Portfolio Base**

    The issue here is, I have worked on a theme project, which previously was using “Pages” & “Page Templates” for portfolios.

    But now I have utilized “Custom Content Portfolio” plugin for managing portfolios, which is great, but there are lots of users using old version of theme, and they will certainly be angry if they see their urls being changed once they update theme to latest version, most importantly their SEO.

    So is there anything you can do to solve this?

  2. Not that I know of. I’m not sure it’s possible to not have a rewrite slug for a CPT. I’ll search around to see.

  3. function prefix_post_type_link( $post_link, $post, $leavename ) {
        if ( ! in_array( $post->post_type, array( ccp_get_project_post_type() ) ) || 'publish' != $post->post_status ) {
            return $post_link;
        }
    
        $post_link = str_replace( '/' . ccp_get_portfolio_rewrite_base() . '/', '/', $post_link );
    
        return $post_link;
    }
    
    add_filter( 'post_type_link', 'prefix_post_type_link', 15, 3 );
    
    function prefix_pre_get_posts( $query ) {
        # bail, if not main query
        if ( ! $query->is_main_query() ) {
            return;
        }
    
        # Only noop our very specific rewrite rule match
        if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
            return;
        }
    
        // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
        if ( ! empty( $query->query['name'] ) ) {
            $query->set( 'post_type', array( 'post', 'page', ccp_get_project_post_type() ) );
        }
    }
    
    add_action( 'pre_get_posts', 'prefix_pre_get_posts', 15 );

    this code seems to be working how I want it, but not sure if this is a best solution?

    What you think?

  4. It looks like it should work. I’m wondering if WP will catch potential name conflicts. Like if a user creates a page named sunshine and a project named sunshine.

    Of course, you wouldn’t want to put that code in your theme. It’d break the plugin’s settings. You’d probably want to wrap it up as a small plugin for those users who need it.

  5. Thanks.

    I think it might not catch the name conflicts, which is fine, as it will be available only if user opt to use this url structure, and they will be responsible for the consequences if they want to have such url structure.

    Sure, its not going to be forced on users, it will be offered as opt in, as some users don’t like to have project slug in url, so they want to have project name in url only.

    If you have any better solution in near future, please let me know.

  6. Hi Justin,

    I have an issue now regarding this thread.

    The issue is, above solution works fine as long as I set blog permalinks to “Post Name” : “/%postname%/” but if I change it to something like “Day and name” it breaks the logic and throws 404.

    So I searched for the fix / solution but found none, except the plugin called “Simple Post Type Permalinks” which works, but I am not confident in suggesting the users to go for it, as if any issue arises because of it, I will not be able to fix as I am having hard time understanding its logic. Because I am not familiar with WordPress rewrite rules.

    So is there anyway you can somehow point me in right direction, so I can implement my own solution?

    Have you written any article regarding this?

    Any snippet will be helpful.

    Thanks