¿Cómo agrego varias taxonomías a la URL?

8

Múltiples taxonomías en URL

¿Cómo se añaden múltiples taxonomías a la URL que tiene lo siguiente:

  • Tipo de publicación: productos
  • Taxonomía: product_type
  • Taxonomía: marca_producto


Agregar un nuevo producto y seleccionar el tipo y la marca de este producto:

Al agregar un nuevo producto , hay dos cuadros de taxonomía (product_type y product_brand). Llamemos a esta nueva publicación Probar producto 1 . Lo primero que queremos hacer es marcar qué tipo de producto estoy tratando, digamos teléfonos celulares . A continuación, quiero marcar a qué marca pertenece el producto, digamos samsung.

Ahora " Test Product 1 " está asociado con el tipo "teléfonos celulares" y la marca "samsung" .

El resultado final deseado es:

/ productos
»Ver todas las publicaciones personalizadas

/ productos / celulares
»Ver todas las publicaciones personalizadas con la taxonomía de teléfonos celulares

/ product / cell-phones / samsung /
»Ver todas las publicaciones personalizadas donde la taxonomía es celulares y samsung

/ productos / teléfonos celulares / samsung / test-product-1
»Ver el producto (publicación personalizada única)


La pregunta

¿Cómo haría esto posible? Mi pensamiento inicial fue usar una taxonomía, tener "teléfonos celulares" como el término principal de "samsung" . En realidad, agregar la taxonomía y sus términos no fue tan difícil. Pero condujo a muchos otros problemas, algunos bien conocidos, otros no tanto. De todos modos, no funciona así, ya que da 404 problemas y WP no permitirá ciertas cosas.
WP.org »plantilla-archivo-taxonomía

Esto me llevó a repensar la estructura, tener que abandonar las taxonomías y sus términos y pensé; ¿por qué no crear una segunda taxonomía, asociar el tipo de publicación y agregarla a la url?

Buena pregunta de hecho, pero ¿cómo?

DRSK
fuente
¿pueden consultar este enlace? Tengo un problema con lo mismo stackoverflow.com/questions/34351477/…
Sanjay Nakate

Respuestas:

7

Esto es ciertamente posible utilizando algunas reglas de reescritura propias hasta cierto punto. La API WP_Rewrite expone funciones que le permiten agregar reglas de reescritura (o 'mapas') para convertir una solicitud en una consulta.

Hay requisitos previos para escribir buenas reglas de reescritura, y la más importante es la comprensión básica de la expresión regular. El motor de reescritura de WordPress utiliza expresiones regulares para traducir partes de una URL a consultas para obtener publicaciones.

Este es un breve y buen tutorial sobre PHP PCRE (expresiones regulares compatibles con Perl).

Entonces, ha agregado dos taxonomías, supongamos que sus nombres son:

  • tipo de producto
  • producto de marca

Podemos usar esto en consultas de esta manera:

get_posts( array(
    'product_type' => 'cell-phones',
    'product_brand' => 'samsung'
) );

La consulta sería ?product_type=cell-phones&product_brand=samsung. Si escribe eso como su consulta, obtendrá una lista de teléfonos Samsung. Para reescribir /cell-phones/samsungen esa consulta, se debe agregar una regla de reescritura.

add_rewrite_rule()Hará esto por ti. Aquí hay un ejemplo de cómo se vería su regla de reescritura para el caso anterior:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]',
    'top' );

Necesitaras flush_rewrite_rules() tan pronto como haya agregado la regla de reescritura para guardarla en la base de datos. Esto se hace solo una vez, no es necesario hacer esto con cada solicitud, una vez que se vacía una regla, está allí. Para eliminarlo, simplemente enjuague sin la regla de reescritura agregada.

Si desea agregar paginación, puede hacerlo haciendo algo como:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
    'top' );
soulseekah
fuente
1
El artículo más simple que he visto sobre las reglas de reescritura de WordPress. He estado leyendo mucho, pero después de leer esto, finalmente conseguí que todo funcionara. ¡Gracias! +1
evu
3

El final resulto

Esto es lo que se me ocurrió usando parcialmente partes de todas las respuestas que obtuve:

/**
 * Changes the permalink setting <:> post_type_link
 * Functions by looking for %product-type% and %product-brands% in the URL
 * 
  * products_type_link(): returns the converted url after inserting tags
  *
  * products_add_rewrite_rules(): creates the post type, taxonomies and applies the rewrites rules to the url
 *
 *
 * Setting:         [ produkter / %product-type%  / %product-brand% / %postname% ]
 * Is actually:     [ post-type / taxonomy        /  taxonomy       / postname   ]
 *                   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 * Desired result:  [ products  / cellphones      / apple           / iphone-4   ]
 */

    // Add the actual filter    
    add_filter('post_type_link', 'products_type_link', 1, 3);

    function products_type_link($url, $post = null, $leavename = false)
    {
        // products only
        if ($post->post_type != 'products') {
            return $url;
        }

        // Post ID
        $post_id = $post->ID;

        /**
         * URL tag <:> %product-type%
         */
            $taxonomy = 'product-type';
            $taxonomy_tag = '%' . $taxonomy . '%';

            // Check if taxonomy exists in the url
            if (strpos($taxonomy_tag, $url) <= 0) {

                // Get the terms
                $terms = wp_get_post_terms($post_id, $taxonomy);

                if (is_array($terms) && sizeof($terms) > 0) {
                    $category = $terms[0];
                }

                // replace taxonomy tag with the term slug » /products/%product-type%/productname
                $url = str_replace($taxonomy_tag, $category->slug, $url);
            }

        /** 
         * URL tag <:> %product-brand%
         */
        $brand = 'product-brand';
        $brand_tag = '%' . $brand . '%';

        // Check if taxonomy exists in the url
        if (strpos($brand_tag, $url) < 0) {
            return $url;
        } else { $brand_terms = wp_get_post_terms($post_id, $brand); }

        if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
            $brand_category = $brand_terms[0];
        }

        // replace brand tag with the term slug and return complete url » /products/%product-type%/%product-brand%/productname
        return str_replace($brand_tag, $brand_category->slug, $url);

    }

    function products_add_rewrite_rules() 
    {
        global $wp_rewrite;
        global $wp_query;

        /**
         * Post Type <:> products
         */

            // Product labels
            $product_labels = array (
                'name'                  => 'Products',
                'singular_name'         => 'product',
                'menu_name'             => 'Products',
                'add_new'               => 'Add product',
                'add_new_item'          => 'Add New product',
                'edit'                  => 'Edit',
                'edit_item'             => 'Edit product',
                'new_item'              => 'New product',
                'view'                  => 'View product',
                'view_item'             => 'View product',
                'search_items'          => 'Search Products',
                'not_found'             => 'No Products Found',
                'not_found_in_trash'    => 'No Products Found in Trash',
                'parent'                => 'Parent product'
            );

            // Register the post type
            register_post_type('products', array(
                'label'                 => 'Products',
                'labels'                => $product_labels,
                'description'           => '',
                'public'                => true,
                'show_ui'               => true,
                'show_in_menu'          => true,
                'capability_type'       => 'post',
                'hierarchical'          => true,
                'rewrite'               => array('slug' => 'products'),
                'query_var'             => true,
                'has_archive'           => true,
                'menu_position'         => 5,
                'supports'              => array(
                                            'title',
                                            'editor',
                                            'excerpt',
                                            'trackbacks',
                                            'revisions',
                                            'thumbnail',
                                            'author'
                                        )
                )
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-type', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Types', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'products/types'),
                'singular_label' => 'Product Types') 
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-brand', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Brands', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'product/brands'),
                'singular_label' => 'Product Brands') 
            );

            $wp_rewrite->extra_permastructs['products'][0] = "/products/%product-type%/%product-brand%/%products%";

            // flush the rules
            flush_rewrite_rules();
    }

    // rewrite at init
    add_action('init', 'products_add_rewrite_rules');


Algunos pensamientos:

Esto funciona Aunque está "obligado" a asignar ambas taxonomías a cada publicación o la URL tendrá un final '/'» '/products/taxonomy//postname'. Como voy a asignar ambas taxonomías a todos mis procuts, teniendo un tipo y una marca, este código parece estar funcionando para mis necesidades. Si alguien tiene alguna sugerencia o mejora, ¡no dude en responder!

DRSK
fuente
Excelente. Gracias por postear tu solución. Selecciónelo como respuesta una vez que haya pasado el tiempo suficiente. Además, se recomienda votar cualquier respuesta útil.
marfarma
Me cuesta mucho hacer que esto funcione, no estoy seguro de por qué. Incluso copiar / pegar en mis funciones en lugar de intentar transferir sus cambios me da muchos errores. Estoy pensando que algo en el núcleo de WordPress debe haber cambiado entre cuando esto se escribió (hace más de 3 años) y hoy. Estoy tratando de descubrir lo mismo: wordpress.stackexchange.com/questions/180994/…
JacobTheDev
flush_rewrite_rules()en init? no lo hagas. básicamente está restableciendo sus reglas de reescritura con cada carga de página.
honk31
1

Comprueba de esta manera, todavía tiene algunos errores con el archivo de la marca

http://pastebin.com/t8SxbDJy

add_filter('post_type_link', 'products_type_link', 1, 3);

function products_type_link($url, $post = null, $leavename = false)
{
// products only
    if ($post->post_type != self::CUSTOM_TYPE_NAME) {
        return $url;
    }

    $post_id = $post->ID;

    $taxonomy = 'product_type';
    $taxonomy_tag = '%' . $taxonomy . '%';

    // Check if exists the product type tag
    if (strpos($taxonomy_tag, $url) < 0) {
        // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
        $url = str_replace($taxonomy_tag, '', $url);
    } else {
        // Get the terms
        $terms = wp_get_post_terms($post_id, $taxonomy);

        if (is_array($terms) && sizeof($terms) > 0) {
            $category = $terms[0];
            // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
            $url = str_replace($taxonomy_tag, $category->slug, $url);
        }
        }

    /* 
     * Brand tags 
     */
    $brand = 'product_brand';
    $brand_tag = '%' . $brand . '%';

    // Check if exists the brand tag 
    if (strpos($brand_tag, $url) < 0) {
        return str_replace($brand_tag, '', $url);
    }

    $brand_terms = wp_get_post_terms($post_id, $brand);

    if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
        $brand_category = $brand_terms[0];
    }

    // replace brand tag with the term slug: /products/cell-phone/%product_brand%/productname 
    return str_replace($brand_tag, $brand_category->slug, $url);
}

function products_add_rewrite_rules() 
{
global $wp_rewrite;
global $wp_query;

register_post_type('products', array(
    'label' => 'Products',
    'description' => 'GVS products and services.',
    'public' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'capability_type' => 'post',
    'hierarchical' => true,
    'rewrite' => array('slug' => 'products'),
    'query_var' => true,
    'has_archive' => true,
    'menu_position' => 6,
    'supports' => array(
        'title',
        'editor',
        'excerpt',
        'trackbacks',
        'revisions',
        'thumbnail',
        'author'),
    'labels' => array (
        'name' => 'Products',
        'singular_name' => 'product',
        'menu_name' => 'Products',
        'add_new' => 'Add product',
        'add_new_item' => 'Add New product',
        'edit' => 'Edit',
        'edit_item' => 'Edit product',
        'new_item' => 'New product',
        'view' => 'View product',
        'view_item' => 'View product',
        'search_items' => 'Search Products',
        'not_found' => 'No Products Found',
        'not_found_in_trash' => 'No Products Found in Trash',
        'parent' => 'Parent product'),
    ) 
);

register_taxonomy('product-categories', 'products', array(
    'hierarchical' => true, 
    'label' => 'Product Categories', 
    'show_ui' => true, 
    'query_var' => true, 
    'rewrite' => array('slug' => 'products'),
    'singular_label' => 'Product Category') 
);

$wp_rewrite->extra_permastructs['products'][0] = "/products/%product_type%/%product_brand%/%products%";

    // product archive
    add_rewrite_rule("products/?$", 'index.php?post_type=products', 'top');

    /* 
     * Product brands
     */
    add_rewrite_rule("products/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_brand=$matches[2]', 'top');
    add_rewrite_rule("products/([^/]+)/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_brand=$matches[2]&paged=$matches[3]', 'top');

    /*
     * Product type archive
     */
    add_rewrite_rule("products/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]', 'top');    
    add_rewrite_rule("products/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_type=$matches[1]&paged=$matches[1]', 'bottom'); // product type pagination

    // single product
    add_rewrite_rule("products/([^/]+)/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]&product_brand=$matches[2]&products=$matches[3]', 'top');



flush_rewrite_rules();

}

add_action('init', 'products_add_rewrite_rules');
Luis Abarca
fuente
1

Si bien no es su estructura de URL deseada exacta, puede obtener:

/ productos
»Ver todas las publicaciones personalizadas

/ productos / type / cell-phones
»Ver todas las publicaciones personalizadas con la taxonomía de teléfonos celulares

/ productos / tipo / teléfonos celulares / marca / samsung
»Ver todas las publicaciones personalizadas donde la taxonomía es teléfonos celulares Y samsung

/ brand / samsung
»Ver todas las publicaciones personalizadas donde la taxonomía es samsung

/ product / test-product-1
»Ver el producto (publicación única personalizada)

sin tener que especificar reglas de reescritura personalizadas.

Sin embargo, requiere que registres tus taxonomías y tipos de publicaciones personalizadas en un orden particular. El truco consiste en registrar cualquier taxonomía donde la babosa comienza con la babosa de su tipo de publicación antes de registrar ese tipo de publicación personalizada. Por ejemplo, suponga las siguientes babosas:

product_type taxonomy slug               = products/type
product custom_post_type slug            = product
product custom_post_type archive slug    = products
product_brand taxonomy slug              = brand

Luego puede registrarlos en este orden:

register_taxonomy( 
    'products_type', 
    'products', 
        array( 
            'label' => 'Product Type', 
            'labels' => $product_type_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'products/type', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

register_post_type('products', array(
    'labels' =>$products_labels,
    'singular_label' => __('Product'),
    'public' => true,
    'show_ui' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'rewrite' => array('slug' => 'product', 'with_front' => false ),
    'has_archive' => 'products',
    'supports' => array('title', 'editor', 'thumbnail', 'revisions','comments','excerpt'),
 ));

register_taxonomy( 
    'products_brand', 
    'products', 
        array( 
            'label' => 'Brand', 
            'labels' => $products_brand_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'brand', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

Si absolutamente tiene que tener una URL como:

/ productos / tipo / teléfonos celulares / marca / samsung / test-product-1
»Ver el producto (publicación personalizada única)

Entonces necesitaría una regla de reescritura similar a esta:

    add_rewrite_rule(
        '/products/type/*/brand/*/([^/]+)/?',
        'index.php?pagename='product/$matches[1]',
        'top' );

ACTUALIZAR /programming/3861291/multiple-custom-permalink-structures-in-wordpress

Así es como redefine correctamente la URL de publicación única.

Establezca re-write en false para el tipo de publicación personalizada. (Deje el archivo como está) y luego, después de registrar las taxonomías y publicaciones, también registre las siguientes reglas de reescritura.

  'rewrite' => false

   global $wp_rewrite;
   $product_structure = '/%product_type%/%brand%/%product%';
   $wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
   $wp_rewrite->add_permastruct('product', $product_structure, false);

Luego filtre post_type_link para crear la estructura de URL deseada, permitiendo valores de taxonomía no establecidos. Modificando el código de la publicación vinculada, tendría:

function product_permalink($permalink, $post_id, $leavename){
    $post = get_post($post_id);

    if( 'product' != $post->post_type )
         return $permalink;

    $rewritecode = array(
    '%product_type%',
    '%brand%',
    $leavename? '' : '%postname%',
    $leavename? '' : '%pagename%',
    );

    if('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){

        if (strpos($permalink, '%product_type%') !== FALSE){

            $terms = wp_get_object_terms($post->ID, 'product_type'); 

            if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))  
               $product_type = $terms[0]->slug;
            else 
               $product_type = 'unassigned-artist';         
        }

        if (strpos($permalink, '%brand%') !== FALSE){
           $terms = wp_get_object_terms($post->ID, 'brand');  
           if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) 
               $brand = $terms[0]->slug;
           else 
               $brand = 'unassigned-brand';         
        }           

        $rewritereplace = array(
           $product_type,
           $brand,
           $post->post_name,
           $post->post_name,
        );

        $permalink = str_replace($rewritecode, $rewritereplace, $permalink);
    }
    return $permalink;
}

add_filter('post_type_link', 'product_permalink', 10, 3);

Ahora solo necesito descubrir cómo volver a escribir la url de taxonomía de marca sin la etiqueta de marca líder, y debería coincidir exactamente con la URL deseada.

marfarma
fuente