Agregar categorías al tipo de publicación personalizada en el enlace permanente

22

Sé que la gente ha preguntado esto antes y ha ido tan lejos como agregar el tipo de publicación personalizada y volver a escribir para el enlace permanente.

El problema es que tengo 340 categorías existentes que me gustaría seguir usando. Solía ​​poder ver / category / subcategory / postname

Ahora tengo la babosa de customposttype / postname. La selección de la categoría ya no aparece en el enlace permanente ... No he cambiado la configuración del enlace permanente en admin a nada diferente.

¿Hay algo que me falta o necesito agregar a este código?

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,
    )
);
picadillo
fuente
2
Esta puede ser una pregunta tonta, pero ¿ha borrado sus reescrituras?
Kristina Childs
Recientemente, me enfrento a este problema. Resuelto! [# 188834] [1] [1]: wordpress.stackexchange.com/questions/94817/…
maheshwaghmare

Respuestas:

16

Hay 2 puntos de ataque que cubrir cuando agrega reglas de reescritura de tipo de publicación personalizada:

Reescribir reglas

Esto sucede cuando las reglas de reescritura se generan wp-includes/rewrite.phpen WP_Rewrite::rewrite_rules(). WordPress le permite filtrar las reglas de reescritura para elementos específicos como publicaciones, páginas y varios tipos de archivos. Donde vea posttype_rewrite_rulesla posttypeparte debe ser el nombre de su tipo de publicación personalizada. Alternativamente, puede usar el post_rewrite_rulesfiltro siempre que no elimine las reglas de publicación estándar también.

A continuación, necesitamos la función para generar realmente las reglas de reescritura:

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

Lo principal a tener en cuenta aquí si decides jugar es el booleano 'Walk directorios'. Genera reglas de reescritura para cada segmento de un permastruct y puede causar desajustes de reglas de reescritura. Cuando se solicita una URL de WordPress, la matriz de reglas de reescritura se verifica de arriba a abajo. Tan pronto como se encuentre una coincidencia, cargará todo lo que haya encontrado, por ejemplo, si su permastruct tiene una coincidencia codiciosa, por ejemplo. para /%category%/%postname%/y los directorios walk están activados, generará reglas de reescritura tanto para /%category%/%postname%/AND /%category%/que coincidirán con cualquier cosa. Si eso sucede demasiado pronto, estás jodido.

Enlaces permanentes

Esta es la función que analiza los enlaces permanentes de tipo de publicación y convierte una permastruct (por ejemplo, '/% year% /% monthnum% /% postname% /') en una URL real.

La siguiente parte es un ejemplo simple de lo que idealmente sería una versión de la get_permalink()función que se encuentra en wp-includes/link-template.php. Los enlaces permanentes de publicaciones personalizadas se generan mediante get_post_permalink()una versión muy diluida de get_permalink(). get_post_permalink()se filtra por post_type_linklo que estamos usando eso para hacer una permastructura personalizada.

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

Como se mencionó, este es un caso muy simplificado para generar un conjunto de reglas de reescritura personalizado y enlaces permanentes, y no es particularmente flexible, pero debería ser suficiente para comenzar.

Engañando

Escribí un complemento que le permite definir permastructs para cualquier tipo de publicación personalizada, pero como puede usar %category%en la estructura de enlaces permanentes para publicaciones, mi complemento admite %custom_taxonomy_name%para cualquier taxonomía personalizada que tenga también, donde custom_taxonomy_nameestá el nombre de su taxonomía, por ejemplo. %club%.

Funcionará como cabría esperar con taxonomías jerárquicas / no jerárquicas.

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

Sanchothefat
fuente
1
el complemento es excelente, pero ¿podría explicar cómo solucionar el problema en la pregunta sin su complemento?
Eugene Manuilov
Estoy de acuerdo en que es excelente que haya un complemento para abordarlo (lo tengo marcado como favorito y es lo primero que se me ocurrió en esta Q), pero la respuesta se beneficiaría de un breve resumen de cuál es el problema y cómo el complemento lo conquistó. :)
Rarst
@EugeneManuilov Muy bien, lo siento, es una respuesta larga. ¡Eso está conmigo reduciéndolo a lo básico también!
sanchothefat
Parece que el primero $permalink = home_url(...se anula $permalink = user_trailingslashit(...y nunca se usa. ¿O me estoy perdiendo algo? $post_linkNi siquiera está definido. ¿Se suponía que debía ser $permalink = user_trailingslashit( $permalink, 'single' );?
Ian Dunn
Buena captura, debe ser $permalinkno $post_link. Saludos :)
sanchothefat
1

¡Tengo la solución!

Para tener enlaces permanentes jerárquicos para el tipo de publicación personalizada, instale el complemento Enlace de tipo de publicación personalizada ( https://wordpress.org/plugins/custom-post-type-permalinks/ ).

Actualizar el tipo de publicación registrada. Tengo el nombre del tipo de publicación como centro de ayuda

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

Y aquí está la taxonomía registrada.

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

Esta línea hace que tu enlace permanente funcione

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

puedes quitar %post_id%y puedes mantener/%help_centre_category%/%postname%/"

No olvides eliminar los enlaces permanentes del tablero de instrumentos.

Varsha Dhadge
fuente
+1 la solución más simple es usar este complemento: wordpress.org/plugins/custom-post-type-permalinks funciona perfectamente
Julio
Sí, pero eso es para si tiene un solo tipo de publicación personalizada, pero si tiene varios tipos de publicación personalizada en un solo tema, entonces lo anterior es la solución. Además, también cambia tu babosa de categoría igual que tu babosa de tipo de publicación.
Varsha Dhadge
1

¡¡¡He encontrado una solución!!!

(Después de una investigación interminable ... puedo tener enlaces permanentes de TIPO POST PERSONALIZADO como:
example.com/category/sub_category/my-post-name

Aquí el código (en functions.php o 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
fuente
-2

Tienes varios errores con tu código. Limpié tu código existente:

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

Reemplace su código con el código anterior y vea si funciona. Responda si tiene más preguntas y trataré de ayudarlo.

EDITAR:

Me di cuenta de que me quedé fuera 'has_archive' => true.

Jeremy Jared
fuente