Support » Developing with WordPress » cpt taxonomies in permalink structure

  • Resolved zeilenschreiber

    (@zeilenschreiber)


    Hello!

    On my new website I’d like to have a new permalink structure with some custom post types and the taxonomies.

    This is, what I have until now:
    https://example.com/cpt/category/post_title/

    I reached this with the code below:

    //Setup Custom Post Type - Glossar
    add_action( 'init', 'create_custom_post_type_glossar' );
    
    function create_custom_post_type_glossar() {
       $labels = array(
        'name'						 => __( 'Glossar', TRANSLATION_CONST ),
        'singular_name' 			 => __( 'Glossar', TRANSLATION_CONST ),
        'all_items' 				 => __( 'Glossar-Übersicht', TRANSLATION_CONST ),
        'add_new' 					 => __( 'Hinzufügen', TRANSLATION_CONST ),
        'add_new_item' 				 => __( 'Glossareintrag hinzufügen', TRANSLATION_CONST ),
        'edit_item' 				 => __( 'Glossareintrag bearbeiten', TRANSLATION_CONST ),
        'new_item' 					 => __( 'Glossareintrag hinzufügen', TRANSLATION_CONST ),
        'view_item' 				 => __( 'Glossareintrag anzeigen', TRANSLATION_CONST ),
        'view_items'             	 => __( 'Glossareinträge anzeigen', TRANSLATION_CONST ),
        'search_items' 				 => __( 'Glossareintrag suchen', TRANSLATION_CONST ),
        'not_found' 				 => __( 'Keine Glossareinträge gefunden', TRANSLATION_CONST ),
        'not_found_in_trash' 		 => __( 'Keine Glossareinträge im Papierkorb gefunden', TRANSLATION_CONST ),
        'parent_item_colon'     	 => __( 'Übergeordnete Glossareinträge:', TRANSLATION_CONST ),
        'archives'              	 => __( 'Glossar', TRANSLATION_CONST ),
        'attributes'          	     => __( 'Glossar Attribute:', TRANSLATION_CONST ),
        'insert_into_item'    	     => __( 'Zum Glossar hinzufügen', TRANSLATION_CONST ),
        'uploaded_to_this_item' 	 => __( 'Zum Glossar hinzugefügt', TRANSLATION_CONST ),
        'featured_image'        	 => __( 'Glossarbild', TRANSLATION_CONST ),
        'set_featured_image'    	 => __( 'Glossarbild auswählen:', TRANSLATION_CONST ),
        'remove_featured_image' 	 => __( 'Glossarbild entfernen:', TRANSLATION_CONST ),
        'use_featured_image'    	 => __( 'Als Glossarbild verwenden:', TRANSLATION_CONST ),
        'menu_name'                  => __( 'Glossar', TRANSLATION_CONST ),
        );
    
        $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'description' => __( 'Glossar (CPT) für mein Webseite', TRANSLATION_CONST ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 6, // Unterhalb von Schmuck
        'has_archive' => 'glossar',
    	'query_var' => true,
        'menu_icon' => 'dashicons-welcome-learn-more',
        'publicly_queryable' => true,
        'exclude_from_search' => false,
    	'rewrite' => array('slug' => 'glossar/%glossarkategorie%', 'with_front' => false),
    	'taxonomies' => array( 'glossar-stichwoerter', 'glossarkategorie'),
    	'supports'  => array( 'title', 'editor', 'publicize', 'thumbnail' , 'excerpt', )
    	);
    
      register_post_type( 'glossar', $args);
    }
    
    function glossarkategorie_taxonomy() {
        register_taxonomy('glossarkategorie', 'glossar', array(
    		'labels' => array(
    			'name'          => 'Glossarkategorie'
    		,	'singular_name' => 'Glossarkategorie'
    		,	'search_items'  => 'Suche in Glossarkategorien'
    		,	'edit_item'     => 'Bearbeite Glossarkategorien'
    		,	'add_new_item'  => 'Füge eine neue Glossarkategorie hinzu'
    		)
    	,	'hierarchical' => false
    	,	'query_var'    => true
    	,	'show_admin_column'     => true
    	,	'rewrite'      => array('slug' => 'glossar', 'with_front' => false)
    	)); // type taxonomy
    }
    add_action( 'init', 'glossarkategorie_taxonomy');
    
    function tm_glossarkategorie_post_link( $post_link, $id = 0 ){
        $post = get_post($id);
            $terms = wp_get_object_terms( $post->ID, 'glossarkategorie' );
            if( $terms ){
                return str_replace( '%glossarkategorie%' , $terms[0]->slug , $post_link );
    	} else {
    	    return str_replace( '%glossarkategorie%/' , '' , $post_link );
    }
    
        return $post_link;
    }
    add_filter( 'post_type_link', 'tm_glossarkategorie_post_link', 1, 3 );

    Sometimes it will be necessary to have child-categories – I am not able to get this run (I don’t like plugins to rewrite).
    I ‘d like to have this permalink:
    https://example.com/cpt/parent-category/child-categorie/post_title/
    Of course there is a need of fallback, if there are no child-categories, it should go back to this:
    https://example.com/cpt/category/post_title/

    Is there anybody out there, who did something like this, already?

Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    What’s the issue with rewrites? Adding custom taxonomies or post types adds rewrite rules. Maybe you mean different rewrites, in which case I might agree.

    You should be able to create a rewrite rule with add_rewrite_rule(). The regexp can identify the final term as title slug, cpt as base, and assume anything in between of any length are taxonomy terms.

    The other approach is usually WP ignores permalink terms before the title slug as long as the title slug can be matched. You can’t use numbers because WP tries to make dates out of them, but this link should work:
    example.com/cpt/useless/meaningless/terms/actual-title-slug/

    You can put taxonomy terms instead, WP should ignore them if they do not match any existing rewrite rules. One advantage of this approach is the link will not 404 if one places the wrong term in the link.

    Thank you – I found a great solution, which works well:
    https://wordpress.stackexchange.com/questions/177010/how-to-check-if-last-uri-segment-is-a-custom-post-type-or-taxonomy-term/177015

    “serks” and “Milo” had great ideas about. Only the last comment of Milo (Question was: what to do, if the archive gets pagination – 404) I don’t understand. Hope to get this done, also.

    Moderator bcworkz

    (@bcworkz)

    About paged? As he said, you need to add another rule that picks up pagination parameters from the permalink because your first page rewrite cannot match the added parameter. A pagination link such as /cpt/parent-category/child-categorie/post_title/page/2/.

    This second rule will add regexp to your other rule to match the /page/#/ section and collect the # parameter into the $matches array. Then add that $matches element to a index.php paged= query var on the right side of ?. As he said, in the OP’s gallery_rewrite_rules($rules) function, looking at another rule in $rules that matches a /page/#/ fragment will be the best example of what to do.

    I hope that makes more sense. If not, tell me what’s confusing you and I’ll try to clarify.

    FWIW, hooking the ‘rewrite_rules_array’ filter and adding to the passed array is essentially the same as using add_rewrite_rule() like I suggested, so you are definitely on the right path.

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘cpt taxonomies in permalink structure’ is closed to new replies.