web-dev-qa-db-fra.com

URL CPT imbriquées + Posts 2 Posts

Je travaille sur un site client comportant deux types de publication personnalisés différents: artist et portfolio. J'utilise le plugin posts-to-posts pour créer une relation entre chaque artiste et son portefeuille.

Les URL de l'artiste sont configurées en tant que {siteUrl}/artist, tandis que les URL du portefeuille sont configurées pour recevoir le nom de l'artiste: {siteUrl}/artist/%artistname%.

J'ai écrit ce qui suit pour vérifier si la portfolio est connectée à une artist et, dans l'affirmative, modifiez l'URL de cette portfolio en {siteUrl}/artist/artist-name/portfolio-name. S'il n'y a pas d'artiste connecté, il demande de changer l'URL en {siteUrl}/portfolio/portfolio-name.

function filter_portfolio_link( $post_link, $post ) {
  if ( $post->post_type === 'portfolio' ) {
    $connected = new WP_query( array(
      'post_type' => 'artist',
      'connected_type' => 'portfolios_to_artists',
      'connected_items' => $post,
      'nopaging' => true,
    ) );
    if ($connected->have_posts() ) {
      foreach ( $connected as $connectedPost ) {
        setup_postdata($connectedPost);
        if ($connectedPost->post_type === 'artist') {
          $artistName = $connectedPost->post_name;
          $first = false;
        }
      }
      $post_link = str_replace( '%artist_name%', $artistName, $post_link );
    }
    else {
      $post_link = str_replace( 'artist/%artist_name%', 'portfolio', $post_link);
    }
  }
  return $post_link;
}
add_filter( 'post_type_link', 'filter_portfolio_link', 10, 2);

Cela extrait les données correctes et les insère correctement dans l'URL, mais avec beaucoup de notifications PHP. Je ne m'inquiète pas trop pour le moment.

Ainsi, bien que cela change correctement le slug, cela ne change pas le permalien et je reçois 404 erreurs sur le front-end. J'imagine que cela nécessite une fonction de réécriture pour être couplé avec elle? Juste pas sûr où aller d'ici.

Cela ( Obtenir l'identifiant de publication de slug pendant init ) semblait frapper quelque part autour de ce que je cherchais, bien que pas tout à fait exactement. Des idées?

1
brooklynjb

Donc, après avoir passé beaucoup de temps et essayé beaucoup de choses différentes, j'ai finalement trouvé la bonne façon de procéder. J'ai utilisé MonkeyMan Rewrite Analyzer et la barre de débogage WP _ pour l'aider à comprendre comment créer la réécriture.

Alors tout d'abord, mes URL de type publication personnalisées sont réécrites en tant que telles:

// Artist Rewrite Args
$rewrite = array(
  'slug'                => 'artist',
  'with_front'          => true,
  'pages'               => true,
  'feeds'               => true,
);

// Portfolio Rewrite Args
$rewrite = array(
  'slug'                => 'portfolio',
  'with_front'          => false,
  'pages'               => true,
  'feeds'               => true,
);

Ensuite, j’enregistre une balise de réécriture %artistname% pour le nom de l’artiste, que nous saisirons via une fonction WP_Query, ainsi qu’une règle de réécriture pour remplir le slug qui sera occupé par le nom de l’artiste, qui précédera le slug du portefeuille affiché.

// Portfolio Rewrite Rule
add_action( 'init', 'portfolio_rewrite_tag' );
function portfolio_rewrite_tag() {

    add_rewrite_tag('%artistname%','[^/]+');
    // defines the rewrite structure for 'portfolios'
    // says that if the portfolio URL matches this rule, then it should display the 'artists' post whose post name matches the last slug set
    add_rewrite_rule( '^artist/[^/]+/([^/]+)/?$','index.php?portfolio=$matches[1]','top' );   
}

Ensuite, j'ai affiné le filtre d'URL pour vérifier s'il s'agissait d'une publication de portefeuille et, le cas échéant, extraire le slug de la première artist connectée, puis l'ajoute à la chaîne du lien de publication.

// Grab connected artist name and swap it into the URL
function filter_portfolio_link( $post_link, $post ) {
  if ( $post->post_type === 'portfolio' ) {
    $connected = new WP_query( array(
      'post_type' => 'artist',
      'connected_type' => 'portfolios_to_artists',
      'connected_items' => $post,
      'nopaging' => true,
    ) );
    if ($connected->have_posts() ) {
      $first = true;
      foreach ( $connected as $connectedPost ) {
          setup_postdata($connectedPost);
          if ($connectedPost->post_type === 'artist') {
            if ($first) {
              $artistName = $connectedPost->post_name;
              $first = false;
            }
          }
      }
      $post_link = str_replace( 'portfolio', 'artist/' . $artistName, $post_link );
    }
  }
  return $post_link;
}
add_filter( 'post_type_link', 'filter_portfolio_link', 10, 2);

Alors c'est tout! Bien que je n'aie pas utilisé le même plug-in que celui décrit dans le fil de discussion , des types de publications personnalisées imbriquées avec des permaliens , le fil de discussion complet a été extrêmement utile pour parvenir à cette conclusion. .

2
brooklynjb