Tipos de posts personalizados, taxonomías y enlaces permanentes

14 dic 2010, 01:56:21
Vistas: 22.3K
Votos: 66

Esto me está volviendo loco y estoy seguro de que es simple, pero nada de lo que busco muestra una estructura simple (todo es muy complejo).

Tengo un tipo de post personalizado product_listing y una taxonomía personalizada product_cat (que es jerárquica y debe comportarse como categorías).

Simplemente quiero que mis URLs se vean así:

mysite.com/products/category1/product-name1 
mysite.com/products/category2/product-name2

Pero por más que lo intento, sigo obteniendo el temido error 404. Las páginas funcionan bien y los Posts funcionan bien, pero mis posts personalizados no funcionan correctamente. Se están mostrando como:

mysite.com/products/product-name1
mysite.com/products/product-name2

¡Lo cual realmente funciona! Es solo que quiero ver mi taxonomía personalizada allí y además quiero poder acceder a la plantilla taxonomy.php que tengo configurada yendo a:

mysite.com/products/category1/
mysite.com/products/category2/

Ninguno de mis slugs es igual, ni quiero que lo sean. Aquí está la parte del tipo de post y taxonomía de mi archivo functions.php:

///// TIPOS DE POST PERSONALIZADOS /////

// registrar el nuevo tipo de post
register_post_type( 'product_listing', array( 
    'labels'                 => array(
        'name'               => __( 'Productos' ),
        'singular_name'      => __( 'Producto' ),
        'add_new'            => __( 'Añadir Nuevo' ),
        'add_new_item'       => __( 'Crear Nuevo Producto' ),
        'edit'               => __( 'Editar' ),
        'edit_item'          => __( 'Editar Producto' ),
        'new_item'           => __( 'Nuevo Producto' ),
        'view'               => __( 'Ver Productos' ),
        'view_item'          => __( 'Ver Producto' ),
        'search_items'       => __( 'Buscar Productos' ),
        'not_found'          => __( 'No se encontraron productos' ),
        'not_found_in_trash' => __( 'No se encontraron productos en la papelera' ),
        'parent'             => __( 'Producto Padre' ),
    ),
    'description'           => __( 'Aquí es donde puedes crear nuevos productos en tu sitio.' ),
    'public'                => true,
    'show_ui'               => true,
    'capability_type'       => 'post',
    'publicly_queryable'    => true,
    'exclude_from_search'   => false,
    'menu_position'         => 2,
    'menu_icon'             => get_stylesheet_directory_uri() . '/images/tag_orange.png',
    'hierarchical'          => true,
    '_builtin'              => false, // ¡Es un tipo de post personalizado, no integrado!
    'rewrite'               => array( 'slug' => 'products', 'with_front' => true ),
    'query_var'             => true,
    'supports'              => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions' ),
) );


//conectar a la acción init y llamar a create_book_taxonomies cuando se active
add_action( 'init', 'create_product_taxonomies', 0 );
//add_action('admin_init', 'flush_rewrite_rules');

//crear dos taxonomías, géneros y escritores para el tipo de post "book"
function create_product_taxonomies() {
    // Agregar nueva taxonomía, hacerla jerárquica (como categorías)
    $labels = array(
        'name'              => _x( 'Categorías', 'nombre general de taxonomía' ),
        'singular_name'     => _x( 'Categoría', 'nombre singular de taxonomía' ),
        'search_items'      =>  __( 'Buscar Categorías' ),
        'all_items'         => __( 'Todas las Categorías' ),
        'parent_item'       => __( 'Categorías Padre' ),
        'parent_item_colon' => __( 'Categorías Padre:' ),
        'edit_item'         => __( 'Editar Categoría' ), 
        'update_item'       => __( 'Actualizar Categoría' ),
        'add_new_item'      => __( 'Añadir Nueva Categoría' ),
        'new_item_name'     => __( 'Nuevo Nombre de Categoría' ),
        'menu_name'         => __( 'Categoría' ),
    );  

    register_taxonomy( 'product_cat', array( 'product_listing' ), array(
        'hierarchical'  => true,
        'labels'        => $labels,
        'show_ui'       => true,
        'query_var'     => true,
        //'rewrite'     => true,
        'rewrite'       => array( 'slug' => '%category%', 'with_front' => true ),
    ) );

    // Agregar nueva taxonomía, NO jerárquica (como etiquetas)
    $labels = array(
        'name'                       => _x( 'Aromas', 'nombre general de taxonomía' ),
        'singular_name'              => _x( 'Aroma', 'nombre singular de taxonomía' ),
        'search_items'               =>  __( 'Buscar Aromas' ),
        'popular_items'              => __( 'Aromas Populares' ),
        'all_items'                  => __( 'Todos los Aromas' ),
        'parent_item'                => null,
        'parent_item_colon'          => null,
        'edit_item'                  => __( 'Editar Aroma' ), 
        'update_item'                => __( 'Actualizar Aroma' ),
        'add_new_item'               => __( 'Añadir Nuevo Aroma' ),
        'new_item_name'              => __( 'Nuevo Nombre de Aroma' ),
        'separate_items_with_commas' => __( 'Separar aromas con comas' ),
        'add_or_remove_items'        => __( 'Añadir o eliminar aromas' ),
        'choose_from_most_used'      => __( 'Elegir entre los aromas más usados' ),
        'menu_name'                  => __( 'Aromas' ),
    ); 

    register_taxonomy( 'scent', 'product_listing', array(
        'hierarchical'  => false,
        'labels'        => $labels,
        'show_ui'       => true,
        'query_var'     => true,
        //'rewrite'     => array( 'slug' => 'scents' ),
    ) );
}

También tengo otra taxonomía personalizada de scents que idealmente me gustaría que tuviera algún tipo de url amigable, pero soy más flexible en esto. Me gustaría poder acceder a una lista de todos los aromas yendo a mysite.com/products/scents pero no tienen que ser específicos de la categoría.

¿Alguien puede ayudarme?

0
Todas las respuestas a la pregunta 5
9
67

Cambia el slug en los argumentos de tu tipo de entrada a products/%product_cat%, y el slug en los argumentos de tu taxonomía a simplemente products, luego regenera las reglas de reescritura. ¡Ahora WordPress debería manejar /products/mi-categoria-de-producto/nombre-del-post/!

Finalmente, necesitamos ayudar un poco a WordPress con la generación de enlaces permanentes (por defecto, no reconocerá la etiqueta %product_cat% en la estructura de enlaces):

/**
 * Inyecta el slug del término en la estructura de enlaces permanentes del tipo de entrada personalizado.
 * 
 * @link   http://wordpress.stackexchange.com/a/5313/1685
 * 
 * @param  string  $link
 * @param  WP_Post $post 
 * @return array
 */
function wpse_5308_post_type_link( $link, $post ) {
    if ( $post->post_type === 'product_listing' ) {
        if ( $terms = get_the_terms( $post->ID, 'product_cat' ) )
            $link = str_replace( '%product_cat%', current( $terms )->slug, $link );
    }

    return $link;
}

add_filter( 'post_type_link', 'wpse_5308_post_type_link', 10, 2 );

Algo importante: esto simplemente tomará la primera categoría de producto para el post ordenada por nombre. Si estás asignando múltiples categorías a un solo producto, puedo fácilmente cambiar cómo determina cuál usar en el enlace permanente.

¡Déjame saber cómo te va con esto y podemos abordar los otros problemas!

14 dic 2010 03:50:16
Comentarios

¡Oh VAYA! ¡Estoy impresionado! ¡Esto FUNCIONÓ! ¡Finalmente! ¡Nunca pensé que algo lo haría!!! Muchísimas gracias!!! ............ Ahora, ¿cómo generaría un enlace (algo como the_permalink) para obtener la URL de la taxonomía por sí sola? /products/my-product-cat/

RodeoRamsey RodeoRamsey
14 dic 2010 05:21:13

Creo que resolví eso^^^ ............ pero ahora estoy atascado con la Paginación. Parece romperse al usar cualquier paginación (función personalizada o incorporada) ya que /products/my-product-cat/ se ve bien pero /products/my-product-cat/page/2/ devuelve un error 404 y abandona el archivo taxonomy.php en favor del archivo index.php. He intentado todo lo que pude encontrar y todavía nada.

RodeoRamsey RodeoRamsey
14 dic 2010 08:45:48

¿Considerarías cambiar las reglas de reescritura (rewrites) para productos individuales a product/cat-name/product-name? (nota la singularidad) El problema es que la regla de reescritura para la paginación de taxonomía no se activa, ¡porque queda atrapada por una regla anterior para productos individuales!

TheDeadMedic TheDeadMedic
14 dic 2010 12:52:16

Estoy abierto a ello. Pero para entenderlo, ¿eso significaría que los productos tendrían una ruta URL diferente si estás viendo una página de producto individual vs. una página de 'categoría'? Entonces, el individual sería producto/nombre-cat/nombre-prod pero las categorías serían productos/nombre-cat/? ¿No sería eso como contradecir el propósito de las URLs "amigables para humanos"? Me cuesta ayudar a mis clientes a aprender el panel de WordPress, y mucho menos esa diferencia... Si lo estoy entendiendo mal, por favor házmelo saber. También podría estar contento SIN un directorio frontal, como categoria-producto/nombre-producto y simplemente categoria-producto/. ¿Podría funcionar eso?

RodeoRamsey RodeoRamsey
14 dic 2010 16:44:44

Lo has entendido, aunque diría que SÍ es "amigable para humanos", ya que hay una clara distinción entre archivos (productos/) y elementos individuales (producto/). Y no, yo mantendría el 'directorio frontal', ya que ayuda a mantener una clara distinción de las entradas y páginas, además de que de lo contrario podrías terminar con problemas de rendimiento (es decir, reglas de reescritura verbosas).

TheDeadMedic TheDeadMedic
14 dic 2010 17:31:53

Vale, ¿qué tal si mantenemos tu sugerencia anterior pero usando términos menos relacionados? Digamos... producto/nombre-cat/nombre-producto/ para páginas de productos individuales... y algo como categorias/nombre-cat/ para las páginas de archivo de categorías? ¿Qué necesitaría modificar en el código anterior para que eso funcione?

RodeoRamsey RodeoRamsey
14 dic 2010 19:18:59

Probé ese plugin que sugería la otra respuesta y parece funcionar bien para /products/cat-name/prod-name/ Y /products/cat-name/ ... ¿es una opción viable?

RodeoRamsey RodeoRamsey
14 dic 2010 19:58:26

Podría ser que el plugin genera las reglas de reescritura manualmente en un orden que funciona - lo único que haría sería monitorear el rendimiento - usa <?php timer_stop(true); ?> y <?php echo get_num_queries(); ?> en algún lugar de tu footer.php, y observa qué promedios obtienes al solicitar archivos de taxonomía y productos individuales.

TheDeadMedic TheDeadMedic
15 dic 2010 00:21:48

¿Encontraron alguna manera de solucionar esto? Probé el código que sugirió @TheDeadMedic y el plugin pero ninguno funciona correctamente. Si es así, por favor revisa mi pregunta. ¡Gracias! - http://wordpress.stackexchange.com/questions/40587/shouldnt-this-be-easy-custom-post-type-custom-taxonomy-permalink

fxfuture fxfuture
30 ene 2012 04:43:40
Mostrar los 4 comentarios restantes
0

Gracias @TheDeadMechanic, tu respuesta me ayudó, pero solo parcialmente. Quería hacer lo mismo que preguntó @RodeoRamsey, pero con categorías anidadas (ej: misitio.com/productos/categoria1/subcategoria-1/subsubcategoria-1/nombre-del-producto) y tu solución no funcionó para eso.

Finalmente encontré una solución extendida a mi pregunta que sí funciona, así que si alguien más necesita categorías/subcategorías anidadas puedes ver una solución detallada en mi propia pregunta. Espero que ayude a otros, y gracias por los pasos iniciales.

23 ene 2012 20:39:23
1

No estoy seguro de que WordPress admita esa estructura de forma nativa, pero puedes crear fácilmente tus propias reglas de reescritura para lograrlo.

Consulta una respuesta anterior aquí Reescritura de URL de autor.

Puedes cambiar la línea

$newrules['author/([^/]+)/songs/?$'] = 'index.php?post_type=songs&author=$matches[1]';

por algo como

$newrules['products/([^/]+)/([^/]+)/?$'] = 'index.php?post_type=product_listing&product_cat=$matches[1]&name=$matches[2]';

la parte de product_cat aquí puede ser superflua - no estoy seguro si es necesaria.

Puedes añadir cualquier regla que desees y tendrán prioridad sobre las integradas.

14 dic 2010 02:07:03
Comentarios

Vaya, qué interesante. Oh cielos, creo que las reglas de reescritura personalizadas están más allá de mis capacidades. Probé el código anterior (y el resto del otro post) y no cambió nada. Limpié todo e intenté de nuevo y aún así ningún cambio, así que comenté todas las reglas de reescritura establecidas en los tipos de contenido personalizados y taxonomías, limpié y AÚN nada.

RodeoRamsey RodeoRamsey
14 dic 2010 03:09:48
1

Sí, me estaba volviendo loco antes de configurar el enlace permanente para el tipo de contenido personalizado. Encontré un plugin para manejar el tipo de contenido personalizado. Es muy fácil de usar. http://wordpress.org/extend/plugins/custom-post-permalinks/ ¡WordPress debería añadir esto como función básica! Leo

14 dic 2010 12:13:59
Comentarios

Había visto esta opción antes y me abstuve de usarla porque decía "para taxonomías no jerárquicas". Tenía una que estaba configurada como jerárquica, así que no pensé que funcionaría, pero hasta ahora, ¡parece haber hecho el truco! Además, parece estar funcionando para lograr la estructura /productos/nombre-categoria/nombre-producto/ que estaba tratando de conseguir (ver comentario en otra respuesta). @TheDeadMedic, ¿es esta una opción viable? ¿O debería seguir con las reescrituras en el archivo functions.php?

RodeoRamsey RodeoRamsey
14 dic 2010 19:57:35
0

En realidad, es bastante sencillo. Solo necesitas una línea. Aquí está mi código


function create_product_taxonomies()
{
// Añadir nueva taxonomía, hacerla jerárquica (como categorías)
    $labels = array(
        'name' => _x('Categorías', 'taxonomy general name'),
        'singular_name' => _x('Categoría', 'taxonomy singular name'),
        'search_items' => __('Buscar Categorías'),
        'all_items' => __('Todas las Categorías'),
        'parent_item' => __('Categorías Padre'),
        'parent_item_colon' => __('Categorías Padre:'),
        'edit_item' => __('Editar Categoría'),
        'update_item' => __('Actualizar Categoría'),
        'add_new_item' => __('Añadir Nueva Categoría'),
        'new_item_name' => __('Nombre de la Nueva Categoría'),
        'menu_name' => __('Categoría'),
    );

    register_taxonomy('product_cat', array('product_listing'), array(
        'hierarchical' => true,
        'labels' => $labels,
        'show_ui' => true,
        'query_var' => true,
        'rewrite' => array('hierarchical' => true),
    ));

Y aplicado a la taxonomía generada para mi CPT de Reseñas desde GenerateWP.com. Estoy usando esto en mi propio sitio WordPress, https://www.wpstarters.com


function reviews_category_taxonomy() {

    $labels = array(
        'name'                       => _x( 'Categorías de Reseñas', 'Taxonomy General Name', 'reviews_category' ),
        'singular_name'              => _x( 'Categoría de Reseña', 'Taxonomy Singular Name', 'reviews_category' ),
        'menu_name'                  => __( 'Categoría de Reseña', 'reviews_category' ),
        'all_items'                  => __( 'Todas las Categorías de Reseña', 'reviews_category' ),
        'parent_item'                => __( 'Categoría de Reseña Padre', 'reviews_category' ),
        'parent_item_colon'          => __( 'Categoría de Reseña Padre:', 'reviews_category' ),
        'new_item_name'              => __( 'Nombre de Nueva Categoría de Reseña', 'reviews_category' ),
        'add_new_item'               => __( 'Añadir Nueva Categoría de Reseña', 'reviews_category' ),
        'edit_item'                  => __( 'Editar Categoría de Reseña', 'reviews_category' ),
        'update_item'                => __( 'Actualizar Categoría de Reseña', 'reviews_category' ),
        'view_item'                  => __( 'Ver Categoría de Reseña', 'reviews_category' ),
        'separate_items_with_commas' => __( 'Separar elementos con comas', 'reviews_category' ),
        'add_or_remove_items'        => __( 'Añadir o eliminar elementos', 'reviews_category' ),
        'choose_from_most_used'      => __( 'Elegir de los más usados', 'reviews_category' ),
        'popular_items'              => __( 'Categorías de Reseña Populares', 'reviews_category' ),
        'search_items'               => __( 'Buscar Elementos', 'reviews_category' ),
        'not_found'                  => __( 'No Encontrado', 'reviews_category' ),
        'no_terms'                   => __( 'No hay Categorías de Reseña', 'reviews_category' ),
        'items_list'                 => __( 'Lista de Categorías de Reseña', 'reviews_category' ),
        'items_list_navigation'      => __( 'Navegación de lista de Categorías de Reseña', 'reviews_category' ),
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => false,
        'show_in_rest'               => true,
        'rewrite' => array( 'hierarchical' => true ),
    );
    register_taxonomy( 'reviews_category', array( 'wps_reviews' ), $args );

}
add_action( 'init', 'reviews_category_taxonomy', 0 );

Todo lo que necesitas es añadir 'rewrite' => array('hierarchical' => true),

6 dic 2017 21:15:00