Dodawanie kategorii do niestandardowego typu postu w permalink

22

Wiem, że ludzie już o to pytali i posunęli się nawet do dodania niestandardowego typu postu i przepisania na link bezpośredni.

Problem polega na tym, że mam 340 istniejących kategorii, z których chciałbym nadal korzystać. Kiedyś mogłem zobaczyć / category / subcategory / postname

Teraz mam ślimak customposttype / postname. Wybranie kategorii nie jest już wyświetlane w permalink ... Nie zmieniłem ustawienia permalink w admin na nic innego.

Czy czegoś brakuje lub muszę dodać do tego kodu?

function jcj_club_post_types() {
    register_post_type( 'jcj_club', array(
        'labels' => array(
            'name' => __( 'Jazz Clubs' ),
            'singular_name' => __( 'Jazz Club' ),
            'add_new' => __( 'Add New' ),
            'add_new_item' => __( 'Add New Jazz Club' ),
            'edit' => __( 'Edit' ),
            'edit_item' => __( 'Edit Jazz Clubs' ),
            'new_item' => __( 'New Jazz Club' ),
            'view' => __( 'View Jazz Club' ),
            'view_item' => __( 'View Jazz Club' ),
            'search_items' => __( 'Search Jazz Clubs' ),
            'not_found' => __( 'No jazz clubs found' ),
            'not_found_in_trash' => __( 'No jazz clubs found in Trash' ),
            'parent' => __( 'Parent Jazz Club' ),
        ),
        'public' => true,
        'show_ui' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'menu_position' => 5,
        'query_var' => true,
        'supports' => array( 
            'title',
            'editor',
            'comments',
            'revisions',
            'trackbacks',
            'author',
            'excerpt',
            'thumbnail',
            'custom-fields',
        ),
        'rewrite' => array( 'slug' => 'jazz-clubs-in', 'with_front' => true ),
        'taxonomies' => array( 'category','post_tag'),
        'can_export' => true,
    )
);
haszysz
źródło
2
to może być głupie pytanie, ale czy opróżniłeś swoje przepisy?
Kristina Childs,
Ostatnio mam do czynienia z tym problemem. Rozwiązany! [# 188834] [1] [1]: wordpress.stackexchange.com/questions/94817/…
maheshwaghmare

Odpowiedzi:

16

W przypadku dodawania niestandardowych reguł przepisywania typu postów należy uwzględnić 2 punkty ataku:

Przepisz reguły

Dzieje się tak, gdy reguły przepisywania są generowane wp-includes/rewrite.phpw WP_Rewrite::rewrite_rules(). WordPress pozwala filtrować reguły przepisywania dla określonych elementów, takich jak posty, strony i różne typy archiwów. Gdzie można zobaczyć część powinna być nazwa typu custom post. Alternatywnie możesz użyć filtru, o ile nie zniszczysz również standardowych reguł postów.posttype_rewrite_rulesposttypepost_rewrite_rules

Następnie potrzebujemy funkcji, aby faktycznie wygenerować reguły przepisywania:

// add our new permastruct to the rewrite rules
add_filter( 'posttype_rewrite_rules', 'add_permastruct' );

function add_permastruct( $rules ) {
    global $wp_rewrite;

    // set your desired permalink structure here
    $struct = '/%category%/%year%/%monthnum%/%postname%/';

    // use the WP rewrite rule generating function
    $rules = $wp_rewrite->generate_rewrite_rules(
        $struct,       // the permalink structure
        EP_PERMALINK,  // Endpoint mask: adds rewrite rules for single post endpoints like comments pages etc...
        false,         // Paged: add rewrite rules for paging eg. for archives (not needed here)
        true,          // Feed: add rewrite rules for feed endpoints
        true,          // For comments: whether the feed rules should be for post comments - on a singular page adds endpoints for comments feed
        false,         // Walk directories: whether to generate rules for each segment of the permastruct delimited by '/'. Always set to false otherwise custom rewrite rules will be too greedy, they appear at the top of the rules
        true           // Add custom endpoints
    );

    return $rules;
}

Najważniejszą rzeczą, na którą należy zwrócić uwagę, jeśli zdecydujesz się na zabawę, jest boolean „Katalogi spacerowe”. Generuje reguły przepisywania dla każdego segmentu permastructwa i może powodować niedopasowania reguł przepisywania. Gdy żądany jest adres URL WordPress, tablica reguł przepisywania jest sprawdzana od góry do dołu. Jak tylko zostanie znalezione dopasowanie, załaduje to, co napotkało, więc na przykład, jeśli twój permastruct ma zachłanne dopasowanie, np. /%category%/%postname%/katalogi for i walk są włączone, wyświetli reguły przepisywania dla obu /%category%/%postname%/AND, /%category%/które pasują do wszystkiego. Jeśli zdarzy się to zbyt wcześnie, to jesteś pieprzony.

Permalinks

Jest to funkcja, która analizuje łącza bezpośrednie typu post i konwertuje permastruct (np. „/% Year% /% monthnum% /% postname% /”) na rzeczywisty adres URL.

Następna część jest prostym przykładem tego, co byłoby idealną wersją get_permalink()funkcji znalezionej w wp-includes/link-template.php. Generowane są niestandardowe bezpośrednie łącza pocztowe, dzięki get_post_permalink()którym jest znacznie rozwodniona wersja get_permalink(). get_post_permalink()jest filtrowane według, post_type_linkdlatego używamy go do tworzenia niestandardowej struktury permastruktury.

// parse the generated links
add_filter( 'post_type_link', 'custom_post_permalink', 10, 4 );

function custom_post_permalink( $permalink, $post, $leavename, $sample ) {

    // only do our stuff if we're using pretty permalinks
    // and if it's our target post type
    if ( $post->post_type == 'posttype' && get_option( 'permalink_structure' ) ) {

        // remember our desired permalink structure here
        // we need to generate the equivalent with real data
        // to match the rewrite rules set up from before

        $struct = '/%category%/%year%/%monthnum%/%postname%/';

        $rewritecodes = array(
            '%category%',
            '%year%',
            '%monthnum%',
            '%postname%'
        );

        // setup data
        $terms = get_the_terms($post->ID, 'category');
        $unixtime = strtotime( $post->post_date );

        // this code is from get_permalink()
        $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;
            }
        }

        $replacements = array(
            $category,
            date( 'Y', $unixtime ),
            date( 'm', $unixtime ),
            $post->post_name
        );

        // finish off the permalink
        $permalink = home_url( str_replace( $rewritecodes, $replacements, $struct ) );
        $permalink = user_trailingslashit($permalink, 'single');
    }

    return $permalink;
}

Jak wspomniano, jest to bardzo uproszczony przypadek generowania niestandardowego zestawu reguł przepisywania i łączy bezpośrednich i nie jest on szczególnie elastyczny, ale powinien wystarczyć, aby zacząć.

Oszukiwanie

Napisałem wtyczkę, która pozwala zdefiniować permastructy dla dowolnych niestandardowych typów postów, ale podobnie jak możesz użyć %category%w strukturze permalink dla postów, moja wtyczka obsługuje %custom_taxonomy_name%dowolne niestandardowe taksonomie, które masz również gdzie custom_taxonomy_namejest nazwa twojej taksonomii np. %club%.

Będzie działać tak, jak można się spodziewać z hierarchicznymi / niehierarchicznymi taksonomiami.

http://wordpress.org/extend/plugins/wp-permastructure/

sanchothefat
źródło
1
wtyczka jest świetna, ale czy możesz wyjaśnić, jak rozwiązać problem w pytaniu bez wtyczki?
Eugene Manuilov,
Zgadzam się, że wspaniale jest mieć wtyczkę do rozwiązania tego problemu (mam ją w zakładce i po raz pierwszy przyszło mi do głowy w tym Q), ale odpowiedź skorzystałaby z krótkiego podsumowania problemu i sposobu, w jaki wtyczka go pokonała. :)
Rarst
@EugeneManuilov W porządku, przepraszam, że to długa odpowiedź. To ze mną sprowadzam to do podstaw!
sanchothefat
Wygląda na to, że pierwszy $permalink = home_url(...zostaje zastąpiony $permalink = user_trailingslashit(...i nigdy nie jest używany. A może coś mi brakuje? $post_linknie jest nawet zdefiniowany. Czy tak miało być $permalink = user_trailingslashit( $permalink, 'single' );?
Ian Dunn
Dobry chwyt, powinna ona być $permalinknie $post_link. Pozdrawiam :)
sanchothefat
1

Mam rozwiązanie!

Aby mieć hierarchiczne łącza bezpośrednie dla niestandardowego typu postu, zainstaluj wtyczkę Niestandardowe łącza bezpośrednie typu ( https://wordpress.org/plugins/custom-post-type-permalinks/ ).

Zaktualizuj zarejestrowany typ postu. Mam nazwę typu posta jako centrum pomocy

function help_centre_post_type(){
    register_post_type('helpcentre', array( 
        'labels'            =>  array(
            'name'          =>      __('Help Center'),
            'singular_name' =>      __('Help Center'),
            'all_items'     =>      __('View Posts'),
            'add_new'       =>      __('New Post'),
            'add_new_item'  =>      __('New Help Center'),
            'edit_item'     =>      __('Edit Help Center'),
            'view_item'     =>      __('View Help Center'),
            'search_items'  =>      __('Search Help Center'),
            'no_found'      =>      __('No Help Center Post Found'),
            'not_found_in_trash' => __('No Help Center Post in Trash')
                                ),
        'public'            =>  true,
        'publicly_queryable'=>  true,
        'show_ui'           =>  true, 
        'query_var'         =>  true,
        'show_in_nav_menus' =>  false,
        'capability_type'   =>  'page',
        'hierarchical'      =>  true,
        'rewrite'=> [
            'slug' => 'help-center',
            "with_front" => false
        ],
        "cptp_permalink_structure" => "/%help_centre_category%/%post_id%-%postname%/",
        'menu_position'     =>  21,
        'supports'          =>  array('title','editor', 'thumbnail'),
        'has_archive'       =>  true
    ));
    flush_rewrite_rules();
}
add_action('init', 'help_centre_post_type');

I tutaj jest zarejestrowana taksonomia

function themes_taxonomy() {  
    register_taxonomy(  
        'help_centre_category',  
        'helpcentre',        
        array(
            'label' => __( 'Categories' ),
            'rewrite'=> [
                'slug' => 'help-center',
                "with_front" => false
            ],
            "cptp_permalink_structure" => "/%help_centre_category%/",
            'hierarchical'               => true,
            'public'                     => true,
            'show_ui'                    => true,
            'show_admin_column'          => true,
            'show_in_nav_menus'          => true,
            'query_var' => true
        ) 
    );  
}  
add_action( 'init', 'themes_taxonomy');

Ta linia sprawia, że ​​twój link bezpośredni działa

"cptp_permalink_structure" => "/%help_centre_category%/%post_id%-%postname%/",

możesz usunąć %post_id%i zachować/%help_centre_category%/%postname%/"

Nie zapomnij opróżnić permalinków z deski rozdzielczej.

Varsha Dhadge
źródło
+1 najprostszym rozwiązaniem jest użycie tej wtyczki: wordpress.org/plugins/custom-post-type-permalinks działa idealnie
Jules
Tak, ale dzieje się tak, jeśli masz jeden niestandardowy typ postu, ale jeśli masz wiele niestandardowych typów postów w jednym motywie, powyższe rozwiązanie jest rozwiązaniem. Co więcej, zmienia to również twój ślimak kategorii tak samo, jak ślimak typu post.
Varsha Dhadge,
1

Znalazłem ROZWIĄZANIE !!!

(Po niekończących się badaniach .. Mogę mieć permalinki CUSTOM POST TYPE takie jak:
example.com/category/sub_category/my-post-name

tutaj kod (w functions.php lub wtyczce):

//===STEP 1 (affect only these CUSTOM POST TYPES)
$GLOBALS['my_post_typesss__MLSS'] = array('my_product1','....');

//===STEP 2  (create desired PERMALINKS)
add_filter('post_type_link', 'my_func88888', 6, 4 );

function my_func88888( $post_link, $post, $sdsd){
    if (!empty($post->post_type) && in_array($post->post_type, $GLOBALS['my_post_typesss']) ) {  
        $SLUGG = $post->post_name;
        $post_cats = get_the_category($id);     
        if (!empty($post_cats[0])){ $target_CAT= $post_cats[0];
            while(!empty($target_CAT->slug)){
                $SLUGG =  $target_CAT->slug .'/'.$SLUGG; 
                if  (!empty($target_CAT->parent)) {$target_CAT = get_term( $target_CAT->parent, 'category');}   else {break;}
            }
            $post_link= get_option('home').'/'. urldecode($SLUGG);
        }
    }
    return  $post_link;
}

// STEP 3  (by default, while accessing:  "EXAMPLE.COM/category/postname"
// WP thinks, that a standard post is requested. So, we are adding CUSTOM POST
// TYPE into that query.
add_action('pre_get_posts', 'my_func4444',  12); 

function my_func4444($q){     
    if ($q->is_main_query() && !is_admin() && $q->is_single){
        $q->set( 'post_type',  array_merge(array('post'), $GLOBALS['my_post_typesss'] )   );
    }
    return $q;
}
T.Todua
źródło
-2

Masz kilka błędów w kodzie. Wyczyściłem twój istniejący kod:

<?php
function jcj_club_post_types() {
  $labels = array(
    'name' => __( 'Jazz Clubs' ),
    'singular_name' => __( 'Jazz Club' ),
    'add_new' => __( 'Add New' ),
    'add_new_item' => __( 'Add New Jazz Club' ),
    'edit' => __( 'Edit' ),
    'edit_item' => __( 'Edit Jazz Clubs' ),
    'new_item' => __( 'New Jazz Club' ),
    'view' => __( 'View Jazz Club' ),
    'view_item' => __( 'View Jazz Club' ),
    'search_items' => __( 'Search Jazz Clubs' ),
    'not_found' => __( 'No jazz clubs found' ),
    'not_found_in_trash' => __( 'No jazz clubs found in Trash' ),
    'parent' => __( 'Parent Jazz Club' ),
    );
  $args = array(
    'public' => true,
    'show_ui' => true,
    'publicly_queryable' => true,
    'exclude_from_search' => false,
    'menu_position' => 5,
    'query_var' => true,
    'supports' => array( 'title','editor','comments','revisions','trackbacks','author','excerpt','thumbnail','custom-fields' ),
    'rewrite' => array( 'slug' => 'jazz-clubs-in', 'with_front' => true ),
    'has_archive' => true
    );
  register_post_type( 'jcj_club', $args );
  }
add_action( 'init','jcj_club_post_types' );
?>

Zastąp swój kod powyższym kodem i sprawdź, czy działa. Odpowiedz, jeśli masz dodatkowe pytania, a ja postaram się pomóc.

EDYTOWAĆ:

Zauważyłem, że pominąłem 'has_archive' => true.

Jeremy Jared
źródło