Quiero crear enlaces permanentes canónicos para productos y tipos de productos. Tengo resueltos los tipos de publicaciones personalizadas y la taxonomía personalizada, pero no sé si es posible definir enlaces permanentes con taxonomías. Así que mi flujo de trabajo, por ejemplo, sería este…
- Creo un tipo de publicación personalizada llamada productos.
- Luego creo una taxonomía personalizada para tipos de productos.
- Luego agrego un tipo de producto llamado ‘Sillas’ y agregue un producto llamado
‘Silla roja’ a esta categoría.
Una vez que creo este producto, el estructura de enlace permanente deseada para ver este producto se formatearía así ->
http://shop.com/products/chairs/red-chair
¿Es esto posible en wordpress 3.4? Los metacuadros en mi tipo de publicación personalizada permiten seleccionar los tipos de productos definidos para mi taxonomía personalizada, y solo habrá un tipo por producto.
Si es posible, también me gustaría incluir padres de la categoría de producto seleccionada si es posible (por ejemplo, si el ‘sillas’ categoría era un niño de la ‘salón’ categoría, la estructura de enlaces permanentes sería la siguiente ->
http://shop.com/products/lounge/chairs/red-chair
Así es como creo el tipo de publicación personalizada y la taxonomía personalizada, solo necesito ayuda para definir las reglas de reescritura / slug para incluir el tipo de producto en el enlace permanente.
/* Custom Post Type - Products ------- */
function products_init() {
$args = array(
'public' => true,
'label' => 'Products'
);
register_post_type( 'products', $args );
}
add_action( 'init', 'products_init' );
/* Custom Taxonomy - Product Type ------- */
add_action( 'init', 'create_prodtype' );
function create_prodtype() {
$labels = array(
'name' => _x( 'Product Type', 'products' ),
'singular_name' => _x( 'Product Category', 'product' ),
'search_items' => __( 'Search Product Types' ),
'all_items' => __( 'All Product Types' ),
'parent_item' => __( 'Products' ),
'parent_item_colon' => __( 'Products:' ),
'edit_item' => __( 'Edit Product Type' ),
'update_item' => __( 'Update Product Type' ),
'add_new_item' => __( 'Add New Product Type' ),
'new_item_name' => __( 'New Product Type' ),
);
register_taxonomy(
'products',
array('products'),
array(
'rewrite' => array(
'slug' => 'products',
'hierarchical' => true
),
'with_front' => false,
'labels' => $labels
));
}
rgdigi
Solución
Lo he descubierto con la ayuda de estas publicaciones de Jan Fabry ->
https://wordpress.stackexchange.com/a/5478/10350
https://wordpress.stackexchange.com/a/22490/10350
He configurado el tipo de publicación personalizada de la siguiente manera ->
- Tipo de publicación personalizada (register_post_type) -> “producto”
- Taxonomía (registrar_taxonomía) -> “tipo de producto”
función de fondo
Reescribo la estructura del enlace permanente que se guarda en el back-end, de modo que el enlace permanente se guarda para incluir el tipo de taxonomía personalizado: “tipo de producto”
add_filter('post_type_link', 'product_type_permalink', 10, 4);
function product_type_permalink($post_link, $post, $leavename, $sample) {
//If is custom post type "product"
if ($post->post_type == 'product') {
// Get current post object
global $post;
// Get current value from custom taxonomy "product-type"
$terms = get_the_terms($post->id, 'product-type');
// Define category from "slug" of taxonomy object
$term = $terms[0]->slug;
// Re-structure permalink with string replace to include taxonomy value and post name
$permalink = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $post_link);
}
return $permalink;
}
Selecciona el configuración de enlace permanente a ‘Nombre de la publicación’ y guardar. Si agrega un producto a una categoría y lo guarda, debe volver a escribir el enlace permanente para incluir la definición de taxonomía personalizada, en este caso, “tipo de producto”. Así que si agregas “Silla Roja” hacia “Sillas” categoría, la URL se formateará de la siguiente manera ->
http://website.com/product/chairs/red-chair/
Pero si intenta ir a esta página, obtendrá un error 404. Esto se debe a que wordpress aún no sabe cómo consultar la base de datos con esta URL, por lo que debe escribirla.
Función de front-end
Necesitamos agregar reglas de reescritura para que wordpress pueda tomar nuestra URL y consultar la base de datos. Usamos la función wordpress add_rewrite_rule
para traducir el enlace permanente dado en una cadena de consulta.
add_rewrite_rule(
// The regex to match the incoming URL
'product/([^/]+)/([^/]+)/?',
// The resulting internal URL: `index.php` because we still use WordPress
// `pagename` because we use this WordPress page
// `designer_slug` because we assign the first captured regex part to this variable
'index.php?product-type=$matches[1]&product=$matches[2]',
// This is a rather specific URL, so we add it to the top of the list
// Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
'top'
);
En esta función, WordPress define la matriz de coincidencias explotando la cadena dada en cada barra. En este ejemplo, la expresión regular ([^/]+)
se utiliza para hacer coincidir cualquier cosa entre cada barra. En este ejemplo hay 2 niveles, por lo que hace coincidir el tipo de producto, luego el producto y los agrega a la matriz de coincidencias, donde tipo-producto = $coincidencias1y producto = $coincidencias[2].
Esta regla de reescritura traduce esto ->
product/chairs/red-chair/
En esto ->
index.php?product-type=chair&product=red-chair
Que nuestra base de datos puede usar para consultar la base de datos y devolver la página correcta del producto con el enlace permanente formateado.
Esto descarta las páginas de tipo de producto, ya que solo habrá un nivel en la URL, tipo de producto. Esto significa que la regla de reescritura actualmente siempre intentará identificar el nombre del producto como se define en la cadena de consulta. Entonces, para esto, también escribimos una regla de reescritura de un solo nivel:
add_rewrite_rule('^product/([^/]*)?$','index.php?product-type=$matches[1]','top');
Esto ahora también consultará las páginas de tipos de productos, por lo que podemos recorrer la taxonomía de manera normal si queremos mostrar los distintos tipos de productos, sin arrojar errores 404 cuando intentamos vincularlos.
Abajo
Actualmente, esto solo tomará un único nivel de taxonomía, por lo que la estructura de taxonomía personalizada no puede ser jerárquica. Si especifica más de una taxonomía, usará la más con la primera ID para definir el enlace permanente. Una posible solución para esto es ocultar el menú de taxonomía personalizada que aparece en la barra lateral de los tipos de publicaciones personalizadas y agregar un cuadro meta para la taxonomía donde solo se puede usar un cuadro de selección. Yo uso el Complemento Meta Box para esto. (Nota: este complemento no tiene ningún menú de administración, le permite escribir metacuadros para tipos de publicaciones personalizadas en sus funciones.php simplemente creando matrices, ¡muy recomendable!)
-
Espero que pueda ayudar: su ejemplo funciona muy bien, aparte de la regla de reescritura de un solo nivel, ¿no parece funcionar? Simplemente obtengo la página no se puede encontrar. Cuando ingreso manualmente index.php?product-type=chair, me redirige a /{taxonomy-slug-name}/chair pero ¿funciona?
– Sjwdavies
23 de julio de 2013 a las 16:46
-
¡Gracias por la solución! Tuve que cambiar
$term = $terms[0]->slug;
a$first_key = reset($terms); $term = $first_key->slug;
¡para que funcionen las anclas en las páginas de descripción general!–Vadiem Janssens
13 de marzo de 2015 a las 9:28
-
esto funciona para el cpt en el que lo aplica, pero la regla de redirección reescribe todos los enlaces permanentes que se muestran en la página, incluso de otros cpt. ¿Me he perdido algo?
– bluantinoo
7 mayo 2015 a las 19:47
@reekogi Esto funciona correctamente para el tipo de publicación personalizada del producto, pero rompe todos los demás tipos de publicación.
add_filter('post_type_link', 'product_type_permalink', 10, 4);
function product_type_permalink($post_link, $post, $leavename, $sample) {
//If is custom post type "product"
if ($post->post_type == 'product') {
// Get current post object
global $post;
// Get current value from custom taxonomy "product-type"
$terms = get_the_terms($post->id, 'product-type');
// Define category from "slug" of taxonomy object
$term = $terms[0]->slug;
// Re-structure permalink with string replace to include taxonomy value and post name
$permalink = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $post_link);
}
return $permalink;
}
Una solución sería cambiar vars $post_link y $permalink a $url
function product_type_permalink($url, $post, $leavename, $sample) {
//If is custom post type "product"
if ($post->post_type == 'product') {
// Get current post object
global $post;
// Get current value from custom taxonomy "product-type"
$terms = get_the_terms($post->id, 'product-type');
// Define category from "slug" of taxonomy object
$term = $terms[0]->slug;
// Re-structure permalink with string replace to include taxonomy value and post name
$url = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $url);
}
return $url;
}
add_filter('post_type_link', 'product_type_permalink', 10, 4);
puedes por favor leer este artículo que escribí hace algún tiempo. Logra casi lo que necesita, excepto que solo admite enlaces permanentes de taxonomía de dos niveles. Esto significa que
http://shop.com/products/lounge/chairs/red/fancy-chair
lo más probable es que no funcione.– Nikolá Ivanov Nikolov
25 de noviembre de 2012 a las 19:52
Hmm, intenté integrarlo con mi código y también solo. No detecta el prefijo de URL ‘FAQ’ en absoluto…
– rgdigi
25 de noviembre de 2012 a las 20:44