Wordpress 3.3 jenis kiriman khusus dengan /% postname% / permastruct?

9

Ada posting sebelumnya dengan judul yang mirip, tetapi tidak terlihat di WordPress 3.3, dan itu penting karena 3.3 mengiklankan dengan menarik: "Gunakan struktur permalink postname tanpa penalti kinerja"

Masalah dengan Wordpress 3.2 dan sebelumnya adalah bahwa pertama kali melihat nama halaman, dan kemudian 404. Itu tidak memeriksa jenis posting yang sewenang-wenang terlebih dahulu. 3,3 di sisi lain harus melihat jenis posting, lalu halaman, dan akhirnya 404 (karena mengiklankan fitur ini). Ini menyiratkan bahwa jenis posting khusus tanpa siput harus sederhana , jika tidak ada kode yang sulit di post_type=postsuatu tempat.

Saya belum menemukan solusi spesifik 3.3.

Pertanyaan : Bagaimana saya bisa mendefinisikan permalink struct "/% postname% /" untuk setiap jenis posting kustom "xyz"?

Terima kasih.

Ciantic
sumber
Saya tidak melihat pertanyaan - apa yang sebenarnya Anda tanyakan?
Travis Northcutt
Untuk kejelasan, Anda ingin menentukan jenis posting khusus baru yang menggunakan struktur permalink dari /% postname% /? Apakah Anda berencana memiliki posting juga menggunakan permastruktur yang sama ini, atau akankah mereka memiliki awalan?
prettyboymp
Mengikuti ini untuk melihat apakah ada yang memberi jawaban. Saya telah mencoba pendekatan di atas juga bersamaan dengan hanya mengatur slug penulisan ulang ke '/' yang juga merusak permalinks halaman. Le sigh ...

Jawaban:

2

Ini tidak mudah dilakukan di WP 3.3 kecuali Anda mengelabui aturan penulisan ulang berada di tempat yang benar dan membuat wp_rewrite berpikir aturan verbose digunakan di ujung depan. Kelas di bawah ini berfungsi.

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
sumber
Salin disisipkan kode ini di saya tema, aturan menulis ulang memerah. Menambahkan posting baru, melihat posting (url sudah benar), mendapat 404 ... Di WP 3.3.1. Adakah ide mengapa ini tidak berhasil bagi saya? (Terima kasih untuk kode btw!)
Rob Vermeer
EP_NONE -> EP_PERMALINK untuk membuat halaman komentar berfungsi, dan kemudian untuk membuat beberapa jenis posting bekerja dengan /% postname% / Anda juga harus menggunakan filter parse_query. Lihat jawaban saya di atas.
Ciantic
Rob, apakah Anda menambahkan posting baru atau menambahkan posting 'tes' baru? Ini tidak jelas dalam pertanyaan awal apakah posting perlu memiliki permastruktur dari /% post_name% /. Jika itu masalahnya mengapa bahkan membuat jenis posting baru? Selain itu, Anda akan memiliki masalah potensial dengan konflik nama jika lebih dari satu jenis posting memiliki permastruktur yang sama.
prettyboymp
1

Kunci mobil suci!

Saya pikir ini berhasil . Hampir berfungsi, sangat sederhana, hanya satu baris:

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 Jika Anda mencoba ini di rumah, setelah menambahkan satu baris ini Pergi ke "Pengaturan" -> "Permalinks" dan Simpan Perubahan, itu menyegarkan permalinks.

Saya sedang membaca register_post_type()kode sumber WP dan menemukan sebuah baris:

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

Tak perlu dikatakan, tetapi tanpa siput saya menyimpulkan itu harus bekerja, dan itu berhasil . Bahkan pengeditan tautan permanen di bawah judul di editor berfungsi dengan benar!

Pembaruan: Ini merusak permalinks halaman, kembali ke papan gambar ...

Ciantic
sumber
Saya juga mencoba yang ini, dengan hasil yang serupa. Akan sangat keren jika ini akan berhasil. Mungkin orang lain yang punya ide?
Rob Vermeer
@RobVermeer Memperhatikan bahwa tanpa garis (dengan siput standar saja), WordPress sudah mampu mengarahkan ke url. Misalnya "some-post" mengalihkan ke "anything / some-post". Dalam codespeak, di suatu tempat dalam kode ada dukungan untuk CPT tanpa siput itu hanya default untuk mengarahkan ulang. menghadapi telapak tangan
Ciantic
1

Jawaban prettyboymp hampir sama dengan yang saya dapatkan kemarin, tapi saya tidak senang dengan itu. Jawaban prettyboymp memiliki satu kelemahan, itu tidak berfungsi ketika /% postname% / sedang digunakan secara bersamaan pada beberapa tipe posting.

Inilah jawaban saya, yang juga melihat struktur saat ini, dan membuat berbagai jenis posting untuk mundur. Ada satu kelemahan dalam hal ini juga, jika dua tipe posting memiliki siput yang sama dan keduanya adalah /% postname% / maka itu menunjukkan keduanya.

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
sumber
Apakah mungkin tipe posting tertentu mendapatkan hierarki. Saya mencobanya sendiri, tetapi sepertinya tidak ada yang berhasil ... Menurut saya pos tersebut merupakan lampiran dengan orang tua / anak / ... Dan jika saya melakukannya orang tua / anak / cucu / mendapat 404.
Rob Vermeer
1

Saya membuat solusi dan saya tidak bisa menemukan masalah dengannya. Silakan coba dan beri tahu saya jika Anda menemukan masalah

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

Ubah 'yemek' dengan nama tipe tulisan Anda.

Ünsal Korkmaz
sumber
0

Jawaban terbersih yang dapat saya berikan untuk ini (saya membangun sebuah plugin yang benar-benar membutuhkan jenis posting khusus tanpa siput terkemuka) adalah dengan menggunakan templat halaman khusus alih-alih menggunakan jenis posting khusus.

Dengan melakukan ini, "tipe posting khusus" Anda dapat memiliki url seperti / apa pun tanpa harus khawatir melangkah di halaman atau memposting permalinks.

Untuk melakukan ini, saya akhirnya melakukan hal berikut:

  • Menambahkan templat halaman khusus di dalam plugin saya
  • Menyiapkan template halaman sehingga dapat dipilih di editor halaman
  • Membuat kotak meta khusus yang hanya muncul untuk templat halaman saya

Ini memungkinkan saya untuk:

Sisi bawah

Tentu saja, sementara ini tidak menginjak tautan halaman atau posting, itu memang memiliki beberapa kelemahan jelas.

Tanpa arsip Anda tidak akan memiliki arsip (jika Anda mau), meskipun itu dapat diselesaikan dengan membuat templat halaman lain untuk menggambar arsip semua halaman menggunakan templat khusus Anda.

Dikelola di bawah Halaman Anda tidak mendapatkan navigasi sebelah kiri yang bagus di admin yang mengelompokkan semua jenis posting secara bersamaan.

Ini sebagian dapat diselesaikan dengan menambahkan filter ke daftar halaman (untuk membiarkan Anda memfilter dengan templat halaman yang digunakan), menampilkan templat halaman apa pun yang digunakan dalam kolom baru, dll.


Yang sedang berkata, saya ingin sesuatu yang tidak akan menyebabkan pengguna bertanya-tanya mengapa mereka membuat halaman kustom baru dan menemukan bahwa mereka tidak bisa lagi mencapai halaman normal atau halaman kustom baru menyebabkan halaman yang ada di situs mereka menghilang.

Saya tahu ini bukan solusi nyata , tetapi ini adalah alternatif yang bekerja sangat baik untuk kebutuhan saya.

Privateer
sumber