Wordpress 3.3 tipo di post personalizzato con /% postname% / permastruct?


9

C'è un post precedente con un titolo simile, ma non guarda a WordPress 3.3, e questo è importante poiché 3.3 pubblicizza in modo interessante: "Usa la struttura del permalink del postname senza penalità di prestazione"

Il problema con Wordpress 3.2 e precedenti era che prima apparivano i nomi delle pagine e poi 404. Non controllava prima i tipi di post arbitrari. 3.3 d'altra parte devono cercare i tipi di post, quindi le pagine e infine 404 (poiché pubblicizza questa funzione). Ciò implica che i tipi di post personalizzati senza lumaca dovrebbero essere semplici , se non hanno programmato un codice post_type=postda qualche parte.

Non riesco ancora a trovare una soluzione specifica 3.3.

Domanda : Come posso definire permalink struct "/% postname% /" per ogni dato tipo di post personalizzato "xyz"?

Grazie.


Non vedo una domanda: cosa stai chiedendo davvero?
Travis Northcutt,

Per chiarezza, si desidera definire un nuovo tipo di post personalizzato che utilizza la struttura permalink di /% postname% /? Stai pensando di avere anche i post che usano la stessa permastruttura o avranno un prefisso?
prettyboymp,

A seguito di questo per vedere se qualcuno trova una risposta. Ho provato anche gli approcci di cui sopra insieme semplicemente impostando la lumaca di riscrittura su '/' che interrompe anche i permalink della pagina. Le sigh ...

Risposte:


2

Questo non è facile da eseguire in WP 3.3 a meno che non indovini le regole di riscrittura in modo che si trovino nel posto giusto e facciano in modo che wp_rewrite pensi che vengano utilizzate regole dettagliate nel front-end. La classe seguente funziona.

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' ) );

Copia incollato questo codice nel mio tema, scarica le regole di riscrittura. Aggiunto un nuovo post, visualizzato il post (l'URL è corretto), ottenuto un 404 ... Su WP 3.3.1. Qualche idea sul perché questo non funzionerà per me? (Grazie per il codice a proposito!)
Rob Vermeer,

EP_NONE -> EP_PERMALINK per far funzionare le pagine dei commenti e quindi per far funzionare più tipi di post con /% postname% / devi anche usare il filtro parse_query. Vedi la mia risposta sopra.
Ciantic,

Rob, hai aggiunto un nuovo post o hai aggiunto un nuovo post "test"? Questo non era chiaro nella domanda originale se i post dovevano avere anche la permastruttura di /% post_name% /. In tal caso, perché anche creare un nuovo tipo di post? Inoltre, potresti avere potenziali problemi con i conflitti di nomi se più di un tipo di post ha la stessa permastruttura.
prettyboymp,

1

Chiavi della macchina santa!

Penso che funzioni . Funziona quasi, è super semplice, solo una riga:

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 Se lo provi a casa, dopo aver aggiunto questa riga Vai su "Impostazioni" -> "Permalink" e Salva modifiche, aggiorna i permalink.

Stavo leggendo il register_post_type()codice sorgente WP e ho trovato una riga:

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

Inutile dire che, ma senza lumaca, ho concluso che dovrebbe funzionare, e lo ha fatto . Anche la modifica del permalink sotto il titolo nell'editor funziona correttamente!

Aggiornamento: questa pagina interrompe i permalink, torna al tavolo da disegno ...


Ho anche provato questo, con risultati simili. Sarebbe molto bello se funzionasse. Forse qualcun altro con un'idea?
Rob Vermeer,

@RobVermeer Notato che senza la linea (con solo una lumaca predefinita), WordPress è già in grado di reindirizzare all'URL. Ad esempio, "some-post" reindirizza a "nothing / some-post". In codespeak, da qualche parte nel codice c'è un supporto per CPT senza lumaca che per impostazione predefinita reindirizza. faccia palma
Ciantic

1

La risposta di prettyboymp è quasi la stessa che ho ricevuto ieri, ma non ne sono felice. La risposta di prettyboymp ha un solo difetto, non funziona quando /% postname% / viene utilizzato contemporaneamente su più tipi di post.

Ecco la mia risposta, che guarda anche alla struttura attuale e crea una serie di tipi di post su cui eseguire il fallback. C'è anche un difetto anche in questo, se due tipi di post hanno la stessa lumaca ed entrambi sono /% postname% / allora mostra entrambi.

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

È possibile che alcuni tipi di post diventino gerarchici. L'ho provato da solo, ma nulla sembra funzionare ... Pensa che il post sia un attaccamento con genitore / figlio / ... E se lo faccio genitore / figlio / nipote / ottiene un 404.
Rob Vermeer

1

Ho creato una soluzione e non sono riuscito a trovare un problema. Per favore prova a dirmi se trovi un problema

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);
    } 
}

Cambia "yemek" con il nome del tuo tipo di post.



0

La risposta più chiara che mi è venuta in mente per questo (sto costruendo un plug-in che ha davvero bisogno di un tipo di post personalizzato senza alcuna lumaca iniziale) è utilizzare un modello di pagina personalizzato invece di utilizzare un tipo di post personalizzato.

In questo modo, il tuo "tipo di post personalizzato" può avere URL come / qualunque cosa senza doversi preoccupare di passare alla pagina o pubblicare permalink.

Per fare ciò, ho finito per fare quanto segue:

  • Aggiunta di un modello di pagina personalizzato all'interno del mio plugin
  • Impostazione del modello di pagina in modo che possa essere selezionato nell'editor di pagine
  • Creazione di meta box personalizzate che vengono visualizzate solo per il mio modello di pagina

Questo mi ha permesso di:

I lati negativi

Naturalmente, sebbene ciò non calpesti i link della pagina o dei post, ha un paio di aspetti negativi ovvi.

Nessun archivio Non avrai un archivio (se lo desideri), sebbene ciò possa essere risolto creando un altro modello di pagina per disegnare un archivio di tutte le pagine usando il tuo modello personalizzato.

Gestito in Pagine Non si ottiene la bella navigazione a sinistra nell'amministratore che raggruppa tutti i tipi di post.

Ciò potrebbe essere parzialmente risolto aggiungendo un filtro all'elenco delle pagine (per consentire di filtrare in base al modello di pagina utilizzato), mostrando qualsiasi modello di pagina utilizzato in una nuova colonna, ecc.


Detto questo, volevo qualcosa che non causasse agli utenti di chiedersi perché abbiano creato una nuova pagina personalizzata e ho scoperto che non potevano più raggiungere le pagine normali o che la nuova pagina personalizzata faceva scomparire una pagina esistente sul loro sito.

So che non è una vera soluzione, ma è un'alternativa che ha funzionato perfettamente per le mie esigenze.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.