web-dev-qa-db-fra.com

Suppression du slug de base du type de publication personnalisé hiérarchique

J'ai un type de message personnalisé hiérarchique appelé "état". Mon but est d'avoir une structure permalien comme celle-ci:

http://website.com/idaho/http://website.com/idaho/sub-page

Je suis proche mais je ne l'ai pas encore compris. Voici le code que j'utilise:

D'abord, je retire la limace

public function remove_slugs( $permalink, $post, $leavename ) { 

      $url_components = parse_url( $permalink );
      $post_path = $url_components['path'];
      $post_name = end( explode( '/', trim( $post_path, '/' ) ) );

      if( !empty( $post_name )) {

        switch($post->post_type) {

          case 'state':

            if( $post->post_parent ) {

                $parent = get_post( $post->post_parent );
                $parent = $parent->post_name;

                $permalink = str_replace( $post_path, '/' . $parent . '/' . $post_name . '/', $permalink );

            } else { 

                $permalink = str_replace( $post_path, '/' . $post_name . '/', $permalink );
            }

            break;

        }

      }

      return $permalink;

    }

Ceci est relié à post_type_link.

Ensuite, je réinitialise les variables de requête pour que WordPress sache qu'il s'agit d'un CPT

    public function parse_custom_post_type( $query ) {

        if ( ! $query->is_main_query() ) return;
        if ( count( $query->query ) != 2 || ! isset( $query->query['page'] ) ) return;

        // Are we dealing with a page?
        if ( ! empty( $query->query['pagename'] ) && ! is_home() ) {

            // If the page doesn't exist, we must be dealing with a state
            if ( ! is_page( $query->query['pagename'] ) ) {
                $query->set( 'name', $query->query['pagename'] );
                $query->set( 'state', $query->query['pagename'] );
                $query->set( 'post_type', 'state' );
                $query->is_page = 0;
                $query->is_single = 1;
                unset( $query->query_vars['page'] );
                unset( $query->query_vars['pagename'] );
                unset( $query->query['page'] );
                unset( $query->query['pagename'] );
            }
        }

    }

Ceci est lié à pre_get_posts.

Ainsi, les pages de niveau un _ fonctionnent, mais pas les sous-pages. Les URL se résolvent et atteignent ensuite un 404.

Que dois-je faire pour que cela fonctionne?

3
Jonathan Wold

Préface

Deux choses avant de commencer:

  1. Tu ne devrais vraiment pas faire ça. Avoir des ancres statiques pour réécrire les règles est là pour plus d'efficacité. Votre meilleur pari est de trouver une limace avec laquelle vous êtes satisfait - peut-être au lieu d '"indiquer" d'utiliser "des activités" (ou quelles que soient vos sous-pages).
  2. Très probablement, vos sous-pages ne sont pas réellement des états (puisque vous n'auriez pas/idaho/vermont /), donc cette structure de données ne semble pas avoir beaucoup de sens. Vous pouvez envisager que "état" soit une structure de données et "sous-page" en soit une autre. Si l'état est une classification, vous pouvez en faire une taxonomie. Si state est plus que cela, il pourrait s'agir d'un type de publication. Voici les instructions pour configurer les réécritures pour le premier à partir d’un exposé de WordCamp que j’ai donné à Portland, et voici les instructions pour le dernier pour une autre question de ce site.

Le code

Si vous décidez d'aller de l'avant avec cette structure, voici une classe singleton qui devrait fonctionner immédiatement si votre type de publication a la valeur 'hierarchical' définie sur true et la valeur 'rewrite' définie sur false. Assurez-vous de vider vos réécritures après l’avoir ajoutée au fichier functions.php de votre thème ou à votre plug-in (allez dans Paramètres → Permaliens et cliquez sur "Enregistrer les modifications").

/**
 * Strip the slug out of a hierarchical custom post type
 */

if ( !class_exists( 'State_Rewrites' ) ) :

class State_Rewrites {

    private static $instance;

    public $rules;

    private function __construct() {
        /* Don't do anything, needs to be initialized via instance() method */
    }

    public static function instance() {
        if ( ! isset( self::$instance ) ) {
            self::$instance = new State_Rewrites;
            self::$instance->setup();
        }
        return self::$instance;
    }

    public function setup() {
        add_action( 'init',                array( $this, 'add_rewrites' ),            20 );
        add_filter( 'request',             array( $this, 'check_rewrite_conflicts' )     );
        add_filter( 'state_rewrite_rules', array( $this, 'strip_state_rules' )           );
        add_filter( 'rewrite_rules_array', array( $this, 'inject_state_rules' )          );
    }

    public function add_rewrites() {
        add_rewrite_tag( "%state%", '(.+?)', "state=" );
        add_permastruct( 'state', "%state%", array(
            'ep_mask' => EP_PERMALINK
        ) );
    }

    public function check_rewrite_conflicts( $qv ) {
        if ( isset( $qv['state'] ) ) {
            if ( get_page_by_path( $qv['state'] ) ) {
                $qv = array( 'pagename' => $qv['state'] );
            }
        }
        return $qv;
    }

    public function strip_state_rules( $rules ) {
        $this->rules = $rules;
        # We no longer need the attachment rules, so strip them out
        foreach ( $this->rules as $regex => $value ) {
            if ( strpos( $value, 'attachment' ) )
                unset( $this->rules[ $regex ] );
        }
        return array();
    }

    public function inject_state_rules( $rules ) {
        # This is the first 'page' rule
        $offset = array_search( '(.?.+?)/trackback/?$', array_keys( $rules ) );
        $page_rules = array_slice( $rules, $offset, null, true );
        $other_rules = array_slice( $rules, 0, $offset, true );
        return array_merge( $other_rules, $this->rules, $page_rules );
    }
}

State_Rewrites::instance();

endif;

Je pensais que ce sujet était intéressant et j’ai écrit une explication détaillée de cela sur mon blog . Là, j’ai inclus un code légèrement plus complexe qui n’était pas aussi pertinent pour votre question spécifique.

5
Matthew Boynes