Adăugarea categoriilor în permalink pentru tipuri de postări personalizate

28 mai 2012, 18:33:48
Vizualizări: 31.9K
Voturi: 23

Știu că oamenii au mai întrebat acest lucru și au mers până la adăugarea tipului de postare personalizat și rescrierea pentru permalink.

Problema este că am 340 de categorii existente pe care aș dori să continui să le folosesc. Înainte puteam vedea /categorie/subcategorie/nume-postare

Acum am slug-ul customposttype/nume-postare. Selectarea categoriei nu mai apare în permalink... Nu am schimbat setarea permalink-ului în admin cu nimic diferit.

Îmi lipsește ceva sau trebuie să adaug ceva la acest cod?

function jcj_club_post_types() {
    register_post_type( 'jcj_club', array(
        'labels' => array(
            'name' => __( 'Cluburi de Jazz' ),
            'singular_name' => __( 'Club de Jazz' ),
            'add_new' => __( 'Adaugă Nou' ),
            'add_new_item' => __( 'Adaugă Club de Jazz Nou' ),
            'edit' => __( 'Editează' ),
            'edit_item' => __( 'Editează Cluburi de Jazz' ),
            'new_item' => __( 'Club de Jazz Nou' ),
            'view' => __( 'Vezi Club de Jazz' ),
            'view_item' => __( 'Vezi Club de Jazz' ),
            'search_items' => __( 'Caută Cluburi de Jazz' ),
            'not_found' => __( 'Nu s-au găsit cluburi de jazz' ),
            'not_found_in_trash' => __( 'Nu s-au găsit cluburi de jazz în Coș' ),
            'parent' => __( 'Club de Jazz Părinte' ),
        ),
        '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' => 'cluburi-jazz-in', 'with_front' => true ),
        'taxonomies' => array( 'category','post_tag'),
        'can_export' => true,
    )
);
2
Comentarii

poate fi o întrebare stupidă, dar ai resetat permaliensurile?

kristina childs kristina childs
20 dec. 2012 00:45:33

Recent, am întâmpinat această problemă. Rezolvat! #188834

maheshwaghmare maheshwaghmare
20 mai 2015 10:02:34
Toate răspunsurile la întrebare 4
6
16

Există 2 puncte de atac de acoperit atunci când adăugați reguli de rescriere pentru tipurile personalizate de articole:

Reguli de rescriere

Acest lucru se întâmplă când regulile de rescriere sunt generate în wp-includes/rewrite.php în WP_Rewrite::rewrite_rules(). WordPress vă permite să filtrați regulile de rescriere pentru elemente specifice cum ar fi articolele, paginile și diferite tipuri de arhivă. Unde vedeți posttype_rewrite_rules partea posttype ar trebui să fie numele tipului dvs. personalizat de articol. Alternativ, puteți utiliza filtrul post_rewrite_rules atâta timp cât nu suprascrieți și regulile standard pentru articole.

În continuare, avem nevoie de funcția care generează efectiv regulile de rescriere:

// adăugăm noul nostru permastruct la regulile de rescriere
add_filter( 'posttype_rewrite_rules', 'add_permastruct' );

function add_permastruct( $rules ) {
    global $wp_rewrite;

    // setați structura dorită pentru permalink aici
    $struct = '/%category%/%year%/%monthnum%/%postname%/';

    // utilizați funcția de generare a regulilor de rescriere din WP
    $rules = $wp_rewrite->generate_rewrite_rules(
        $struct,       // structura permalinkului
        EP_PERMALINK,  // Mască de endpoint: adaugă reguli de rescriere pentru endpointuri ale articolelor unice, cum ar fi paginile de comentarii etc...
        false,         // Paginat: adaugă reguli de rescriere pentru paginare, de ex. pentru arhive (nu este necesar aici)
        true,          // Feed: adaugă reguli de rescriere pentru endpointurile de feed
        true,          // Pentru comentarii: dacă regulile de feed ar trebui să fie pentru comentariile articolului - pe o pagină singulară adaugă endpointuri pentru feedul de comentarii
        false,         // Parcurge directoarele: dacă să genereze reguli pentru fiecare segment al permastructului delimitat de '/'. Setat întotdeauna pe false altfel regulile personalizate de rescriere vor fi prea lacome, apar în partea de sus a regulilor
        true           // Adaugă endpointuri personalizate
    );

    return $rules;
}

Principalul lucru de care trebuie să fiți atenți dacă decideți să vă jucați este valoarea booleană 'Walk directories'. Aceasta generează reguli de rescriere pentru fiecare segment al unui permastruct și poate cauza nepotriviri în regulile de rescriere. Când este solicitat un URL WordPress, matricea de reguli de rescriere este verificată de sus în jos. De îndată ce se găsește o potrivire, va încărca orice a întâlnit, așa că, de exemplu, dacă permastructul dvs. are o potrivire lacomă, cum ar fi /%category%/%postname%/ și walk directories este activat, va genera reguli de rescriere atât pentru /%category%/%postname%/ cât și pentru /%category%/ care se vor potrivi cu orice. Dacă acest lucru se întâmplă prea devreme, sunteți încurcați.

Permalinkuri

Aceasta este funcția care analizează permalinkurile tipului de articol și convertește un permastruct (de ex. '/%year%/%monthnum%/%postname%/') într-un URL real.

Următoarea parte este un exemplu simplu de ceea ce ar fi ideal o versiune a funcției get_permalink() găsită în wp-includes/link-template.php. Permalinkurile personalizate pentru articole sunt generate de get_post_permalink(), care este o versiune mult mai simplificată a get_permalink(). get_post_permalink() este filtrat de post_type_link, așa că folosim acest lucru pentru a crea un permastruct personalizat.

// analizăm linkurile generate
add_filter( 'post_type_link', 'custom_post_permalink', 10, 4 );

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

    // facem lucrurile noastre doar dacă folosim permalinkuri frumoase
    // și dacă este tipul nostru țintă de articol
    if ( $post->post_type == 'posttype' && get_option( 'permalink_structure' ) ) {

        // reținem structura dorită a permalinkului aici
        // trebuie să generăm echivalentul cu date reale
        // pentru a se potrivi cu regulile de rescriere stabilite anterior

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

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

        // setăm datele
        $terms = get_the_terms($post->ID, 'category');
        $unixtime = strtotime( $post->post_date );

        // acest cod este din get_permalink()
        $category = '';
        if ( strpos($permalink, '%category%') !== false ) {
            $cats = get_the_category($post->ID);
            if ( $cats ) {
                usort($cats, '_usort_terms_by_ID'); // ordonăm după ID
                $category = $cats[0]->slug;
                if ( $parent = $cats[0]->parent )
                    $category = get_category_parents($parent, false, '/', true) . $category;
            }
            // afișăm categoria implicită în permalinkuri, fără
            // a fi nevoie să o atribuim explicit
            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
        );

        // finalizăm permalinkul
        $permalink = home_url( str_replace( $rewritecodes, $replacements, $struct ) );
        $permalink = user_trailingslashit($permalink, 'single');
    }

    return $permalink;
}

După cum s-a menționat, acesta este un caz foarte simplificat pentru generarea unui set de reguli de rescriere personalizate și a permalinkurilor și nu este deosebit de flexibil, dar ar trebui să fie suficient pentru a vă începe.

Trichere

Am scris un plugin care vă permite să definiți permastructuri pentru orice tipuri personalizate de articole, dar la fel cum puteți utiliza %category% în structura permalinkului pentru articole, pluginul meu suportă %custom_taxonomy_name% pentru orice taxonomii personalizate pe care le aveți, unde custom_taxonomy_name este numele taxonomiei dumneavoastră, de ex. %club%.

Va funcționa așa cum vă așteptați pentru taxonomii ierarhice/neierarhice.

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

20 dec. 2012 15:19:58
Comentarii

pluginul este minunat, dar poți explica cum să rezolvi problema din întrebare fără pluginul tău?

Eugene Manuilov Eugene Manuilov
20 dec. 2012 15:39:09

Sunt de acord că e minunat că există un plugin care să rezolve problema (l-am marcat și este primul la care m-am gândit la această întrebare), dar răspunsul ar beneficia de un rezumat scurt despre care este problema și cum a rezolvat-o pluginul. :)

Rarst Rarst
22 dec. 2012 16:30:50

@EugeneManuilov Bine, îmi pare rău că răspunsul este lung. Asta după ce l-am redus la elementele de bază!

sanchothefat sanchothefat
24 dec. 2012 04:01:57

Se pare că primul $permalink = home_url(... este suprascris de $permalink = user_trailingslashit(... și nu este niciodată utilizat. Sau greșesc? $post_link nici măcar nu este definit. Ar fi trebuit să fie $permalink = user_trailingslashit( $permalink, 'single' );?

Ian Dunn Ian Dunn
6 feb. 2013 01:07:58

Bună observație, ar fi trebuit să fie $permalink nu $post_link. Mersi :)

sanchothefat sanchothefat
6 feb. 2013 12:50:58

Am găsit o eroare în plugin-ul tău WP Permastructure. Am trimis problema pe Github.

DaveyJake DaveyJake
20 oct. 2021 23:27:26
Arată celelalte 1 comentarii
0

Am găsit o SOLUȚIE!!!

(După o cercetare nesfârșită.. Pot avea permalinkuri pentru CUSTOM POST TYPE de genul:
example.com/categorie/sub_categorie/numele-postului-meu

Iată codul (în functions.php sau într-un plugin):

//===PASUL 1 (afectează doar aceste CUSTOM POST TYPES)
$GLOBALS['my_post_typesss__MLSS'] = array('my_product1','....');

//===PASUL 2  (creează permalinkurile dorite)
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;
}

// PASUL 3  (implicit, când se accesează:  "EXAMPLE.COM/categorie/nume-post"
// WP crede că se solicită un post standard. Așadar, adăugăm CUSTOM POST
// TYPE în acea interogare.
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;
}
26 iul. 2015 22:07:21
2

Am găsit soluția!

Pentru a avea permalink-uri ierarhice pentru tipurile personalizate de postări, instalați pluginul Custom Post Type Permalinks(https://wordpress.org/plugins/custom-post-type-permalinks/).

Actualizați tipul de postare înregistrat. Eu am tipul de postare numit help center

function help_centre_post_type(){
    register_post_type('helpcentre', array( 
        'labels'            =>  array(
            'name'          =>      __('Centru de Ajutor'),
            'singular_name' =>      __('Centru de Ajutor'),
            'all_items'     =>      __('Vezi Postările'),
            'add_new'       =>      __('Postare Nouă'),
            'add_new_item'  =>      __('Centru de Ajutor Nou'),
            'edit_item'     =>      __('Editează Centrul de Ajutor'),
            'view_item'     =>      __('Vezi Centrul de Ajutor'),
            'search_items'  =>      __('Caută în Centrul de Ajutor'),
            'no_found'      =>      __('Nu s-a găsit nicio postare'),
            'not_found_in_trash' => __('Nu există postări în coșul de gunoi')
                                ),
        '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 aici este taxonomia înregistrată

function themes_taxonomy() {  
    register_taxonomy(  
        'help_centre_category',  
        'helpcentre',        
        array(
            'label' => __( 'Categorii' ),
            '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');

Această linie face ca permalink-ul să funcționeze

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

puteți elimina %post_id% și puteți păstra /%help_centre_category%/%postname%/"

Nu uitați să resetați permalink-urile din panoul de administrare.

20 iul. 2017 15:54:59
Comentarii

+1 cea mai simplă soluție este să folosești acest plugin: https://wordpress.org/plugins/custom-post-type-permalinks/ funcționează perfect

Jules Jules
16 aug. 2017 13:49:02

Da, dar asta este pentru cazul în care ai un singur tip de postare personalizat, dar dacă ai mai multe tipuri de postări personalizate într-o singură temă, atunci soluția de mai sus este cea potrivită.

În plus, acesta modifică și slug-ul categoriei la fel ca slug-ul tipului de postare.

Varsha Dhadge Varsha Dhadge
18 aug. 2017 09:41:01
0
-2

Aveți câteva erori în codul dumneavoastră. Am curățat codul existent:

<?php
function jcj_club_post_types() {
  $labels = array(
    'name' => __( 'Cluburi de Jazz' ),
    'singular_name' => __( 'Club de Jazz' ),
    'add_new' => __( 'Adaugă nou' ),
    'add_new_item' => __( 'Adaugă Club de Jazz nou' ),
    'edit' => __( 'Editează' ),
    'edit_item' => __( 'Editează Cluburi de Jazz' ),
    'new_item' => __( 'Club de Jazz nou' ),
    'view' => __( 'Vezi Club de Jazz' ),
    'view_item' => __( 'Vezi Club de Jazz' ),
    'search_items' => __( 'Caută Cluburi de Jazz' ),
    'not_found' => __( 'Nu s-au găsit cluburi de jazz' ),
    'not_found_in_trash' => __( 'Nu s-au găsit cluburi de jazz în Coșul de Gunoi' ),
    'parent' => __( 'Club de Jazz Părinte' ),
    );
  $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' => 'cluburi-de-jazz-in', 'with_front' => true ),
    'has_archive' => true
    );
  register_post_type( 'jcj_club', $args );
  }
add_action( 'init','jcj_club_post_types' );
?>

Înlocuiți codul dumneavoastră cu codul de mai sus și verificați dacă funcționează. Răspundeți dacă aveți întrebări suplimentare și voi încerca să vă ajut.

EDITARE:

Am observat că am omis 'has_archive' => true.

30 mai 2012 05:30:51