web-dev-qa-db-fra.com

Types de messages personnalisés et catégories indépendantes - Taxonomie complexe

Des données d'entrée:

  1. Il existe un type de publication personnalisé, avec des publications Companies relatives à la catégorie Company;
  2. Il existe un type de publication personnalisé, avec des publications Products liées à la catégorie Items -> Item-type;
  3. Il existe un type de publication personnalisé, avec des publications Articles liées à la catégorie Articles;

En résumé, la structure ressemble à ceci:

+ Companies (cat)
   |- Company-1 (post)
   `- Company-2
+ Items (cat)
   `- Item-type-1 (cat)
   |   |- Product-1-1 (post)
   |   `- Product-1-2
   `- Item-type-2 (cat)
       |- Product-2-1 (post)
       `- Product-2-2
+ Articles (cat)
   |- Article-1 (post)
   `- Article-2

Le problème:

Je serai reconnaissant pour un moyen de mettre en œuvre la structure qui peut être consultée comme ceci:

http://example.com/company-1/items/item-type-1/product-1 
http://examplecom/company-2/items/item-type-1/product-1 //(note that both company 1 and 2 can produce a similar product)
http://example.com/company-1/articles/article-1-1
http://example.com/company-2/articles/article-2-1

Les articles Produits et Articles ont des champs personnalisés qui stockent les ID de poste des entreprises auxquelles ils sont liés.

METTRE À JOUR:

Je pensais le développer avec des taxonomies personnalisées:

http://example.com/post-type-company/taxonomy-item/term-item-type/product

Pouvez-vous conseiller de manière plus appropriée?

1
Ignat B.

Dans wordpress, le slug (nom de poste) est unique par type de message.

Ainsi, une URL comme /company-1/items/item-type-1/product-1 et une autre comme /company-2/items/item-type-1/product-1, où product-1 est le nom du message, ne peut pas l'adresse de 2 produits différents.

Si vous créez 2 produits avec le même titre , Wordpress enregistrera un slug unique .

La même chose est pour les articles.

Pour cette raison, dans une URL comme:

http://example.com/company-1/items/item-type-1/product-1

peut simplement être réécrit dans

http://example.com/index.php?post_type=products&name=product-1 

et une URL comme:

http://example.com/company-1/articles/article-1-1

peut simplement être réécrit dans

http://example.com/index.php?post_type=articles&name=article-1-1

Donc, comme vous pouvez le voir, peu importe la catégorie.

Vous n'avez besoin que de 2 règles de réécriture:

add_action('init','my_rewrite_rules');

function my_rewrite_rules() {
    add_rewrite_rule( '[^/]+/items/[^/]+/(.+)/?$' , 'index.php?post_type=products&name=$matches[1]' , 'top' );
    add_rewrite_rule( '[^/]+/articles/(.+)/?$' , 'index.php?post_type=articles&name=$matches[1]' , 'top' );
}

Après cela, vous devez vider les règles de réécriture de la section Paramètres-> Permalink dans votre backend et enregistrer les modifications.

Maintenant, les URL fonctionnent comme prévu, si vous les écrivez manuellement sur le navigateur, mais le problème est de générer la bonne URL à l'aide de la fonction the_permalink. Vous devez utiliser le filtre 'post_link' et générer l'URL correcte:

add_filter('post_link', 'my_custom_permalink', 99, 3);

function my_custom_permalink($permalink, $post, $leavename) {
  if ( $post->post_type == 'products' )
     return products_permalink($permalink, $post, $leavename);
  if ( $post->post_type == 'articles' )
     return articles_permalink($permalink, $post, $leavename);
  return $permalink;
}

function products_permalink($permalink, $post, $leavename) {
  if ( $post->post_type != 'products' ) return $permalink;
  $cats = get_the_category( $post->ID );
  $companies = get_term_by('slug', 'companies', 'category');
  $items= get_term_by('slug', 'items', 'category');
  if ( empty($cats) || empty($companies) || empty($items) ) return $permalink;
  $item = '';
  $company = '';
  while ( ! empty($cats) ) {
    if ( $item && $company )
      return home_url() . '/' . $company . '/items/' . $item . '/' . $post->name;
    $cat = array_pop($cats);
    if ( $cat->parent == $companies->term_id ) $company = $cat->slug;
    if ( $cat->parent == $items->term_id ) $item = $cat->slug;
  }
  return $permalink;
}

function articles_permalink($permalink, $post, $leavename) {
  if ( $post->post_type != 'articles' ) return $permalink;
  $cats = get_the_category( $post->ID );
  $companies = get_term_by('slug', 'companies', 'category');
  if ( empty($cats) || empty($companies) ) return $permalink;
  $company = '';
  while ( ! empty($cats) ) {
    if ( $company )
      return home_url() . '/' . $company . '/articles/' . $post->name;
    $cat = array_pop($cats);
    if ( $cat->parent == $companies->term_id ) $company = $cat->slug;
  }
  return $permalink;
}

Ici, je suppose que vous utilisez uniquement des catégories standard, où la catégorie "Sociétés" est la catégorie parente pour les sociétés et "Articles" est la catégorie parente pour les articles.

On suppose également que cpt sont nommés 'produits' et 'articles' (notez le pluriel).

Ajustez les fonctions si quelque chose de différent dans votre configuration.

2
gmazzap