Type de message personnalisé Wordpress 3.3 avec /% postname% / permastruct?

9

Il y a un article précédent avec un titre similaire, mais il ne regarde pas dans WordPress 3.3, et c'est important car 3.3 annonce de manière intéressante: "Utilisez la structure de permalien du nom de poste sans pénalité de performance"

Le problème avec Wordpress 3.2 et versions antérieures était qu'il avait d'abord regardé les noms de page, puis 404. Il n'avait pas vérifié les types de publication arbitraires en premier. 3.3 d'autre part doit regarder les types de publication, puis les pages, et enfin 404 (comme il annonce cette fonctionnalité). Cela implique que les types de publication personnalisés sans slug doivent être simples , s'ils n'ont pas codé en dur post_type=postquelque part.

Cependant, je ne trouve pas encore de solution spécifique 3.3.

Question : Comment puis-je définir la structure de permalien "/% postname% /" pour tout type de publication personnalisé "xyz"?

Merci.

Ciantic
la source
Je ne vois pas de question - que demandez-vous réellement?
Travis Northcutt
Pour plus de clarté, vous souhaitez définir un nouveau type de publication personnalisé qui utilise la structure de permalien de /% postname% /? Envisagez-vous que les publications utilisent également cette même permastructure, ou auront-elles un préfixe?
prettyboymp
Ensuite pour voir si quelqu'un trouve une réponse. J'ai également essayé les approches ci-dessus en définissant simplement le slug de réécriture sur '/', ce qui rompt également les permaliens de page. Le soupir ...

Réponses:

2

Cela n'est pas facile à faire dans WP 3.3 à moins que vous ne trompiez les règles de réécriture pour qu'elles soient au bon endroit et que wp_rewrite pense que des règles verbeuses sont utilisées dans le frontal. La classe ci-dessous fonctionne.

class Test_Post_Type {
    const POST_TYPE = 'test';

    public static function init() {
        global $wp_rewrite;

        $post_type_obj = register_post_type( self::POST_TYPE, array(
            'labels' => array(
                'name' => __( 'Tests' ),
                'singular_name' => __( 'Test' ),
                'add_new' => __( 'Add New' ),
                'add_new_item' => __( 'Add New Test' ),
                'edit_item' => __( 'Edit Test' ),
                'new_item' => __( 'New Test' ),
                'all_items' => __( 'All Tests' ),
                'view_item' => __( 'View Test' ),
                'search_items' => __( 'Search Tests' ),
                'not_found' => __( 'No Tests found' ),
                'not_found_in_trash' => __( 'No Tests found in Trash' ),
                'menu_name' => __( 'Tests' )
            ),
            'publicly_queryable' => true,
            'exclude_from_search' => true,
            'hierarchical' => false,
            'public' => true,
            'rewrite' => false,
            'has_archive' => true,
            'supports' => array( 'title', 'editor', 'thumbnail', 'test_source' ),
            'taxonomies' => array( 'category', 'post_tag' ),
        ) );

        $post_type_obj = get_post_type_object(self::POST_TYPE);

        //register the rewrite tag for permalink building
        $wp_rewrite->add_rewrite_tag( '%' . $post_type_obj->query_var . '%', '([^/]+)', $post_type_obj->query_var . '=' );

        //we have to add the permastruct here in order to build the permalink, otherwise we'll need to filter the post_type link
        add_permastruct(self::POST_TYPE, '%' . $post_type_obj->query_var . '%/', false );

        //add a filter to remove the permastructs generated above
        add_filter(self::POST_TYPE . '_rewrite_rules', array(__CLASS__, '_remove_default_rules')); 

        //now we add a filter to put the generated rewrite rules in the correct spot
        add_action('generate_rewrite_rules', array(__CLASS__, '_filter_rewrite_rules'));

        if(!is_admin()) {
            //we need verbose_page_rules to be on on the front end in order for pages to be process properly
            $wp_rewrite->use_verbose_page_rules = true;
        }
    }

    /**
     * Filter to remove the rules for this post type when they're automatically generated due to the permastruct registration
     * @param type $rules
     * @return type 
     */
    public static function _remove_default_rules($rules) {
        return array();
    }

    /**
     * Filters the rules at the end to add back the ones for this post type at the bottom
     * @param WP_Rewrite $wp_rewrite 
     */
    public static function _filter_rewrite_rules($wp_rewrite) {
        $post_type_obj = get_post_type_object(self::POST_TYPE);
        $my_rules = $wp_rewrite->generate_rewrite_rules('%' . $post_type_obj->query_var . '%', EP_NONE);
        $wp_rewrite->rules += $my_rules;
    }

}

add_action( 'init', array( 'Test_Post_Type', 'init' ) );
prettyboymp
la source
Copiez collé ce code dans le thème me, vidées des règles de réécriture. Ajout d'un nouveau message, affichage du message (l'URL est correcte), obtention d'un 404 ... Sur WP 3.3.1. Une idée pourquoi cela ne fonctionnera pas pour moi? (Merci pour le code btw!)
Rob Vermeer
EP_NONE -> EP_PERMALINK pour que les pages de commentaires fonctionnent, puis pour que plusieurs types de publication fonctionnent avec /% postname% / vous devez également utiliser le filtre parse_query. Voir ma réponse ci-dessus.
Ciantic
Rob, avez-vous ajouté un nouveau message ou ajouté un nouveau message «test»? Cela n'était pas clair dans la question initiale de savoir si les publications devaient également avoir la permastructure de /% post_name% /. Si tel est le cas, pourquoi même créer un nouveau type de message? En outre, vous aurez des problèmes potentiels avec les conflits de noms si plusieurs types de publication ont la même permastructure.
prettyboymp
1

Clés de voiture sacrées!

Je pense que cela fonctionne . Cela fonctionne presque, c'est super simple, une seule ligne:

global $wp_rewrite;
$args = array(
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'query_var' => true,
    'rewrite' => array('slug' => 'anything'),
    'capability_type' => 'post',
    'has_archive' => true,
    'hierarchical' => false,
    'menu_position' => null,
    'supports' => array('title','editor','thumbnail')
);
register_post_type('my_custom_post_type', $args);

$wp_rewrite->add_permastruct('my_custom_post_type', "%my_custom_post_type%");

PS Si vous essayez ceci à la maison, après avoir ajouté cette seule ligne Allez dans "Paramètres" -> "Permaliens" et Enregistrer les modifications, il actualise les permaliens.

Je lisais le register_post_type()code source de WP et j'ai trouvé une ligne:

$wp_rewrite->add_permastruct($post_type, "{$args->rewrite['slug']}/%$post_type%", $args->rewrite['with_front'], $args->permalink_epmask);

Inutile de dire que sans limace, j'ai conclu que cela devrait fonctionner, et c'est ce qui s'est produit . Même l'édition de permalien sous le titre dans l'éditeur fonctionne correctement!

Mise à jour: Cela rompt les permaliens de page, retour à la planche à dessin ...

Ciantic
la source
J'ai également essayé celui-ci, avec un résultat similaire. Ce serait très cool si cela fonctionne. Peut-être quelqu'un d'autre avec une idée?
Rob Vermeer
@RobVermeer A remarqué que sans la ligne (avec juste le slug par défaut), WordPress est déjà capable de rediriger vers l'url. Par exemple, "certains messages" redirige vers "n'importe quoi / certains messages". Dans codespeak, quelque part dans le code, il y a un support pour les CPT sans slug, il est juste par défaut à rediriger. face palm
Ciantic
1

La réponse de prettyboymp est presque la même que celle que j'ai reçue hier, mais je n'en suis pas satisfaite. La réponse de prettyboymp a un défaut, elle ne fonctionne pas lorsque /% postname% / est utilisé simultanément sur plusieurs types de messages.

Voici ma réponse, qui examine également la structure actuelle et crée un tableau de types de messages sur lesquels se replier. Cependant, il y a un défaut, si deux types de publication ont le même slug et que les deux sont /% postname% / alors cela montre les deux.

class MyCustomPostType {
    /**
     * Register post type
     **/
    public static function register_post_type() {
        global $wp_rewrite;

        $args = array(
            'public' => true,
            'publicly_queryable' => true,
            'show_ui' => true,
            'show_in_menu' => true,
            'query_var' => true,
            'rewrite' => false,
            'capability_type' => 'post',
            'has_archive' => true,
            'hierarchical' => false,
            'menu_position' => null,
            'supports' => array('title','editor','thumbnail')
        );

        register_post_type('my_custom_post_type', $args);

        // Enables the pages to work simultaneously
        $wp_rewrite->use_verbose_page_rules = true;
        add_filter("rewrite_rules_array", array(__CLASS__, 'rewrite_rules_array'));
        add_action("parse_query", array(__CLASS__, 'parse_query'));
        add_filter("post_type_link", array(__CLASS__, 'post_type_link'), 1, 4);
    }

    public static function post_type_link($link, $post, $leavename=false, $sample=false) {
        if ($sample && ($begin = strpos($link, "?my_custom_post_type=")) !== false) {
            return substr($link, 0, $begin-1) . "/%my_custom_post_type%/";
        }
        return str_replace("?my_custom_post_type=", "", $link) . "/";
    }

    public static function parse_query($query) {
        global $wp, $wp_rewrite;

        // Is this query for /%post_name%/? Is it main request query?
        if (isset($query->query['name'])
            && substr($wp->matched_rule, 0, 7) == "([^/]+)"
            && isset($query->query)
            && isset($wp->query_vars)
            && $query->query == $wp->query_vars)
        {
            //echo '<p><h1>hit!</h1></p>';
            if (!($post_types = get_query_var("post_type"))) {
                if ($wp_rewrite->permalink_structure == "/%postname%/")
                    $post_types = array("post");
                else
                    $post_types = array();
            }

            if (is_array($post_types))
                $post_types[] = "my_custom_post_type";

            set_query_var("post_type", $post_types);
            //set_query_var("posts_per_page", 1);
        }
    }

    public static function rewrite_rules_array($array) {
        global $wp_rewrite;
        // Same rules as in /%post_name%/
        return array_merge($array, $wp_rewrite->generate_rewrite_rules("/%postname%/", EP_PERMALINK));
    }
}


add_action('init', array("MyCustomPostType", "register_post_type"));
Ciantic
la source
Est-il possible que certains post-types deviennent hiérarchiques. Je l'ai essayé moi-même, mais rien ne semble fonctionner ... Il pense que le message est un attachement avec le parent / enfant / ... Et si je fais parent / enfant / petit-enfant / il obtient un 404.
Rob Vermeer
1

J'ai créé une solution et je n'ai pas pu trouver de problème avec elle. S'il vous plaît essayez de me dire si vous rencontrez un problème

add_action('init', 'firmasite_resimlitarif_cpt', 0);
function firmasite_resimlitarif_cpt() 
{

// Yemek Tarifi

  $args = array(
    'public' => true,
    'show_in_menu' => true, 
    'permalink_epmask' => EP_NONE,
    'rewrite' => array('slug'=>'/','with_front'=>false),
    'has_archive' => false,
    'supports' => array('title','editor','thumbnail')
  ); 
  register_post_type('yemek',$args);

}


// http://wordpress.stackexchange.com/questions/37650/wordpress-3-3-custom-post-type-with-postname-permastruct
add_action("parse_query", 'firmasite_resimlitarif_parse_query');
function firmasite_resimlitarif_parse_query($query) {
    global $wp, $wp_rewrite;


    // Is this query for /%post_name%/? Is it main request query?
    if (isset($query->query['name'])
        && substr($wp->matched_rule, 0, 7) == "([^/]+)"
        && isset($query->query)
        && isset($wp->query_vars)
        && $query->query == $wp->query_vars)
    {
        if (!($post_types = get_query_var("post_type"))) {
            if ($wp_rewrite->permalink_structure == "/%postname%/")
                $post_types = array("post");
            else
                $post_types = array();
        }

        if (is_array($post_types)){ 
            $post_types[] = 'yemek';
            $post_types[] = 'page';
        }


        set_query_var("post_type", $post_types);
    } 
}

Changez 'yemek' avec votre nom de type de message.

Ünsal Korkmaz
la source
0

La réponse la plus claire que j'ai pu trouver pour cela (je construis un plugin qui a vraiment besoin d'un type de publication personnalisé sans aucun slug principal) est d'utiliser un modèle de page personnalisé au lieu d'utiliser un type de publication personnalisé.

En faisant cela, votre "type de publication personnalisé" peut avoir des URL telles que / quoi que ce soit sans avoir à vous soucier de marcher sur la page ou de publier des permaliens.

Pour ce faire, j'ai fini par faire ce qui suit:

  • Ajout d'un modèle de page personnalisé à l'intérieur de mon plugin
  • Configuration du modèle de page afin qu'il puisse être sélectionné dans l'éditeur de page
  • Création de métadonnées personnalisées qui n'apparaissent que pour mon modèle de page

Cela m'a permis de:

Les inconvénients

Bien sûr, bien que cela ne piétine pas la page ou ne publie pas de liens, il présente quelques inconvénients évidents.

Aucune archive Vous n'aurez pas d'archive (si vous le souhaitez), mais cela peut être résolu en créant un autre modèle de page pour dessiner une archive de toutes les pages en utilisant votre modèle personnalisé.

Géré sous Pages Vous n'avez pas la belle navigation de gauche dans l'administrateur qui regroupe tous les types de messages.

Cela pourrait être partiellement résolu en ajoutant un filtre à la liste des pages (pour vous permettre de filtrer en fonction du modèle de page utilisé), en affichant tout modèle de page utilisé dans une nouvelle colonne, etc.


Cela étant dit, je voulais quelque chose qui ne ferait pas en sorte que les utilisateurs se demandent pourquoi ils ont créé une nouvelle page personnalisée et ont constaté qu'ils ne pouvaient plus atteindre les pages normales ou que la nouvelle page personnalisée faisait disparaître une page existante sur leur site.

Je sais que ce n'est pas une vraie solution, mais c'est une alternative qui a très bien fonctionné pour mes besoins.

Corsaire
la source