web-dev-qa-db-fra.com

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

Il y a un article précédent avec un titre similaire, mais il ne fait pas référence à WordPress 3.3, ce qui est important, car la publicité 3.3 est intéressante: "Utilisez la structure postale permalink sans pénalité de performance"

Le problème avec Wordpress 3.2 et les versions antérieures était qu’il cherchait d’abord les noms de page, puis 404. Il n’a pas vérifié les types de publication arbitraire en premier. 3.3 d’autre part must regarde les types de publication, puis les pages, et enfin 404 (car il annonce cette fonctionnalité). Cela implique que les types de publication personnalisés sans slug doivent être simple , s’ils n’ont pas codé en dur post_type=post quelque part.

Je ne trouve pas encore de solution 3.3 spécifique.

Question : Comment définir une structure permanente "/% postname% /" pour tout type de message personnalisé "xyz"?

Merci.

9
Ciantic

Cela n’est pas facile à faire dans WP 3.3 à moins d’avertir les règles de réécriture et de faire en sorte que wp_rewrite pense que des règles verbeuses sont utilisées au début. 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' ) );
2
prettyboymp

la réponse de prettyboymp est presque la même que celle que j'ai eue hier, mais cela ne me satisfait pas. La réponse de prettyboymp a une faille, elle ne fonctionne pas lorsque /% postname%/est utilisé simultanément sur plusieurs types de publication.

Voici ma réponse, qui s'intéresse également à la structure actuelle et crée un tableau de types de publication à utiliser. Cela dit, il y a une faille, si deux types de publication ont le même slug et que tous deux sont /% postname% /, alors les deux sont affichés.

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"));
1
Ciantic

J'ai créé une solution et je ne pouvais pas trouver un problème avec elle. S'il vous plaît essayez de me dire si vous trouvez 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.

1
Ünsal Korkmaz

Clés de voiture sacrées!

Je pense que ça marche. Ça marche 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%");

P.S. / Si vous essayez ceci à la maison, après avoir ajouté cette ligne, allez dans "Paramètres" -> "Permaliens" et enregistrez les modifications, il actualise les permaliens.

Je lisais le code source WP register_post_type() et trouvai une ligne:

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

Inutile de dire, mais sans slug je concluais que cela devrait fonctionner, et il l'a fait. Même l'édition permanente sous le titre dans l'éditeur fonctionne correctement!

Mise à jour: Cette page casse les permaliens, retour à la planche à dessin ...

1
Ciantic
0
weston deboer

La réponse la plus propre que je puisse trouver pour cela (je construis un plugin qui a vraiment besoin d'un type de publication personnalisé sans slug) 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
  • Configurer le modèle de page pour qu'il puisse être sélectionné dans l'éditeur de page
  • Créer des méta-boîtes personnalisées qui n'apparaissent que pour mon modèle de page

Cela m'a permis de:

Les inconvénients

Bien sûr, même si cela ne gêne pas la page ni les liens postaux, il présente quelques inconvénients évidents.

Pas d'archive Vous n'aurez pas d'archive (si vous voulez), bien que cela puisse ê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 ne recevez pas la navigation de gauche à Nice 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 pousse pas les utilisateurs à se demander pourquoi ils ont créé une nouvelle page personnalisée et 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 solution real , mais c'est une alternative qui a très bien fonctionné pour mes besoins.

0
Privateer