Ajout de catégories au type de publication personnalisé en permalien

22

Je sais que les gens ont déjà posé cette question et sont allés jusqu'à ajouter le type de message personnalisé et réécrire pour le permalien.

Le problème est que j'ai 340 catégories existantes que je voudrais continuer à utiliser. J'étais capable de voir / catégorie / sous-catégorie / nom de poste

Maintenant, j'ai le slug de customposttype / postname. La sélection de la catégorie n'apparaît plus dans le permalien ... Je n'ai pas changé le paramètre du permalien dans admin pour quelque chose de différent.

Y a-t-il quelque chose qui me manque ou que je dois ajouter à ce code?

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,
    )
);
hacher
la source
2
cela peut être une question idiote, mais avez-vous vidé vos réécritures?
kristina childs
Récemment, je fais face à ce problème. Résolu! [# 188834] [1] [1]: wordpress.stackexchange.com/questions/94817/…
maheshwaghmare

Réponses:

16

Il y a 2 points d'attaque à couvrir lorsque vous ajoutez des règles de réécriture de type de publication personnalisées:

Réécrire les règles

Cela se produit lorsque les règles de réécriture sont générées dans wp-includes/rewrite.phpdans WP_Rewrite::rewrite_rules(). WordPress vous permet de filtrer les règles de réécriture pour des éléments spécifiques tels que les publications, les pages et divers types d'archives. Où vous voyez posttype_rewrite_rulesla posttypepartie doit être le nom de votre type de publication personnalisé. Alternativement, vous pouvez utiliser le post_rewrite_rulesfiltre tant que vous n'effacez pas également les règles de publication standard.

Ensuite, nous avons besoin de la fonction pour générer réellement les règles de réécriture:

// 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;
}

La principale chose à surveiller ici si vous décidez de jouer est le booléen «Walk répertoires». Il génère des règles de réécriture pour chaque segment d'une infrastructure et peut entraîner des incohérences de règles de réécriture. Lorsqu'une URL WordPress est demandée, le tableau des règles de réécriture est vérifié de haut en bas. Dès qu'une correspondance est trouvée, elle chargera tout ce qu'elle a rencontré, par exemple si votre infrastructure a une correspondance gourmande, par exemple. pour les /%category%/%postname%/répertoires for et walk est activé, il affichera des règles de réécriture pour les deux /%category%/%postname%/ET /%category%/qui correspondront à tout. Si cela arrive trop tôt, vous êtes foutu.

Permaliens

Il s'agit de la fonction qui analyse les permaliens de type de publication et convertit une infrastructure (par exemple, '/% year% /% monthnum% /% postname% /') en une URL réelle.

La partie suivante est un exemple simple de ce qui serait idéalement une version de la get_permalink()fonction trouvée dans wp-includes/link-template.php. Les permaliens personnalisés sont générés par get_post_permalink()ce qui est une version très édulcorée de get_permalink(). get_post_permalink()est filtré par post_type_linkdonc nous utilisons cela pour créer une permastructure personnalisée.

// 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;
}

Comme mentionné, c'est un cas très simplifié pour générer un ensemble de règles de réécriture personnalisé et des permaliens, et n'est pas particulièrement flexible, mais cela devrait suffire pour vous aider à démarrer.

La triche

J'ai écrit un plugin qui vous permet de définir des infrastructures pour tous les types de publication personnalisés, mais comme vous pouvez l'utiliser %category%dans la structure de permalien pour les publications, mon plugin prend en charge %custom_taxonomy_name%toutes les taxonomies personnalisées que vous avez également, où custom_taxonomy_nameest le nom de votre taxonomie, par exemple. %club%.

Cela fonctionnera comme vous vous en doutez avec les taxonomies hiérarchiques / non hiérarchiques.

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

sanchothefat
la source
1
le plugin est génial, mais pourriez-vous expliquer comment résoudre le problème dans la question sans votre plugin?
Eugene Manuilov
Je suis d'accord que c'est génial qu'il y ait un plugin pour y remédier (je l'ai mis en signet et c'est le premier qui m'est venu à l'esprit sur ce Q), mais la réponse bénéficierait d'un bref résumé de ce qu'est le problème et comment le plugin l'a conquis. :)
Rarst
@EugeneManuilov Très bien, désolé, c'est une longue réponse. C'est avec moi aussi que je le ramène à l'essentiel!
sanchothefat
Il semble que le premier $permalink = home_url(...soit remplacé $permalink = user_trailingslashit(...et jamais utilisé. Ou est-ce que je manque quelque chose? $post_linkn'est même pas défini. Était-ce censé l'être $permalink = user_trailingslashit( $permalink, 'single' );?
Ian Dunn
Bonne prise, ça ne devrait $permalinkpas l' être $post_link. Cheers :)
sanchothefat
1

Vous avez la solution!

Pour disposer de permaliens hiérarchiques pour le type de publication personnalisé, installez le plug-in de permaliens de type de publication personnalisé ( https://wordpress.org/plugins/custom-post-type-permalinks/ ).

Mettre à jour le type de message enregistré. J'ai le nom du type de message comme centre d'aide

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');

Et voici la taxonomie enregistrée

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');

Cette ligne fait fonctionner votre permalien

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

vous pouvez supprimer %post_id%et conserver/%help_centre_category%/%postname%/"

N'oubliez pas de vider les permaliens du tableau de bord.

Varsha Dhadge
la source
+1 la solution la plus simple consiste à utiliser simplement ce plugin: wordpress.org/plugins/custom-post-type-permalinks fonctionne parfaitement
Jules
Oui, mais c'est pour si vous avez un seul type de publication personnalisé, mais si vous avez plusieurs types de publication personnalisés dans un seul thème, la solution ci-dessus est ci-dessus. De plus, cela modifie également votre slug de catégorie comme votre slug de type de publication.
Varsha Dhadge
1

J'ai trouvé une solution!!!

(Après des recherches sans fin .. Je peux avoir des permaliens de TYPE DE POSTE PERSONNALISÉS comme:
example.com/category/sub_category/my-post-name

ici le code (dans functions.php ou plugin):

//===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
la source
-2

Vous avez plusieurs erreurs avec votre code. J'ai nettoyé votre code existant:

<?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' );
?>

Remplacez votre code par le code ci-dessus et voyez si cela fonctionne. Répondez si vous avez d'autres questions et j'essaierai de vous aider.

MODIFIER:

J'ai remarqué que j'avais omis 'has_archive' => true.

Jeremy Jared
la source