Wordpress 3.3 ประเภทโพสต์ที่กำหนดเองด้วย /% ชื่อ post% / permastruct?


9

มีการโพสต์ก่อนหน้านี้ที่มีชื่อคล้ายกัน แต่ไม่ได้ดูใน WordPress 3.3 และนั่นเป็นสิ่งสำคัญที่ 3.3 โฆษณาอย่างน่าสนใจ: "ใช้โครงสร้าง Permalink postname โดยไม่มีการลงโทษประสิทธิภาพ"

ปัญหาเกี่ยวกับ Wordpress 3.2 และก่อนหน้านั้นคือก่อนอื่นมันดูชื่อหน้าแล้ว 404 มันไม่ได้ตรวจสอบประเภทโพสต์โดยพลการก่อน 3.3 ในทางกลับกันต้องดูประเภทโพสต์จากนั้นเพจและสุดท้าย 404 (ตามที่โฆษณาคุณลักษณะนี้) นี่ก็หมายความว่าการโพสต์ที่กำหนดเองประเภทโดยไม่ต้องกระสุนควรจะง่ายถ้าพวกเขาไม่ได้ยากรหัสpost_type=postที่ไหนสักแห่ง

ฉันไม่สามารถหาวิธีแก้ปัญหาเฉพาะ 3.3 ได้

คำถาม : ฉันจะกำหนด permalink struct "/% postname% /" สำหรับประเภทโพสต์ที่กำหนดเองใด ๆ "xyz" ได้อย่างไร

ขอบคุณ


ฉันไม่เห็นคำถามคุณถามอะไรจริง ๆ
Travis Northcutt

เพื่อความชัดเจนคุณต้องการกำหนดประเภทโพสต์ที่กำหนดเองใหม่ซึ่งใช้โครงสร้างลิงก์ / / postname% /? คุณวางแผนที่จะโพสต์ใช้โครงสร้างเดียวกันนี้หรือจะมีคำนำหน้าหรือไม่?
prettyboymp

ติดตามสิ่งนี้เพื่อดูว่าใครมาพร้อมกับคำตอบ ฉันได้ลองวิธีการข้างต้นด้วยเช่นกันเพียงแค่ตั้งค่ากระสุนบุ้งเป็น '/' ซึ่งยังแบ่งหน้า Permalinks Le ถอนหายใจ ...

คำตอบ:


2

สิ่งนี้ไม่สามารถทำได้อย่างง่ายดายใน WP 3.3 เว้นแต่ว่าคุณหลอกให้กฎการเขียนซ้ำอยู่ในตำแหน่งที่ถูกต้องและทำให้ wp_rewrite คิดว่ากฎ verbose นั้นถูกใช้ในส่วนหน้า ชั้นเรียนด้านล่างใช้งานได้

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

คัดลอกวางรหัสนี้ในชุดรูปแบบของฉันล้างกฎการเขียนซ้ำ เพิ่มโพสต์ใหม่ดูโพสต์ (url ถูกต้อง) มี 404 ... ใน WP 3.3.1 มีความคิดใดบ้างที่ว่าทำไมสิ่งนี้ถึงใช้งานไม่ได้สำหรับฉัน (ขอบคุณสำหรับรหัส btw!)
Rob Vermeer

EP_NONE -> EP_PERMALINK เพื่อให้หน้าความคิดเห็นทำงานได้และจากนั้นเพื่อให้โพสต์หลายประเภททำงานกับ /% postname% / คุณต้องใช้ตัวกรอง parse_query ดูคำตอบของฉันข้างต้น
Ciantic

Rob คุณเพิ่มโพสต์ใหม่หรือเพิ่มโพสต์ 'ทดสอบ' ใหม่หรือไม่ สิ่งนี้ยังไม่ชัดเจนในคำถามเดิมว่าต้องการให้มีการเปลี่ยนแปลงของ /% post_name% / หากเป็นเช่นนั้นทำไมถึงสร้างประเภทโพสต์ใหม่ นอกจากนี้คุณจะพบปัญหาที่อาจเกิดขึ้นกับความขัดแย้งของชื่อหากโพสต์มากกว่าหนึ่งประเภทมีโครงสร้างที่เหมือนกัน
prettyboymp

1

กุญแจรถศักดิ์สิทธิ์!

ฉันคิดว่ามันใช้งานได้ มันใช้งานได้เกือบจะง่ายสุด ๆ เพียงบรรทัดเดียว:

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

ป.ล.ถ้าคุณลองทำที่บ้านหลังจากเพิ่มหนึ่งบรรทัดไปที่ "การตั้งค่า" -> "Permalinks" และบันทึกการเปลี่ยนแปลงมันจะรีเฟรช Permalink

ฉันอ่านregister_post_type()ซอร์สโค้ดWP และพบบรรทัด:

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

จำเป็นต้องพูด แต่ไม่มีกระสุนผมสรุปว่ามันควรจะทำงานและที่มันทำ แม้แต่การแก้ไขความคิดเห็นภายใต้ชื่อเรื่องในโปรแกรมแก้ไขก็ทำงานได้อย่างถูกต้อง!

อัปเดต:หน้านี้แบ่งการลิงก์กลับไปที่กระดานวาดภาพ ...


ฉันลองอันนี้ด้วยผลลัพธ์ที่คล้ายกัน คงจะเจ๋งมากถ้าใช้งานได้ อาจจะมีคนอื่นที่มีความคิด?
Rob Vermeer

@RobVermeer สังเกตว่าไม่มีบรรทัด (ด้วยกระสุนเพียงค่าเริ่มต้น) WordPress นั้นสามารถเปลี่ยนเส้นทางไปยัง URL แล้ว เช่น "some-post" เปลี่ยนเส้นทางไปที่ "any / some-post" ใน codespeak บางแห่งในรหัสมีการสนับสนุนสำหรับ CPT โดยไม่ต้องทากมันก็เป็นค่าเริ่มต้นที่จะเปลี่ยนเส้นทาง หน้าปาล์ม
Ciantic

1

คำตอบ prettyboymp เกือบเหมือนเดิมที่ฉันได้รับเมื่อวานนี้ แต่ฉันไม่มีความสุขกับมัน คำตอบของ prettyboymp มีข้อบกพร่องหนึ่งข้อ แต่ไม่สามารถใช้งานได้เมื่อ /% postname% / กำลังใช้งานพร้อมกันกับโพสต์หลายประเภท

นี่คือคำตอบของฉันซึ่งดูในโครงสร้างปัจจุบันและสร้างอาเรย์ของประเภทโพสต์เพื่อใช้แทน มีข้อบกพร่องเพียงอย่างเดียวในเรื่องนี้เช่นกันหากโพสต์สองประเภทมีทากเหมือนกันและทั้งคู่เป็น /% postname% / ก็จะแสดงทั้งสองอย่าง

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

เป็นไปได้ไหมว่าโพสต์บางประเภทรับลำดับชั้น ฉันพยายามมันเอง แต่ดูเหมือนจะไม่มีอะไรทำงาน ... มันคิดว่าการโพสต์เป็นสิ่งที่แนบมากับผู้ปกครอง / ท่าน / ... และถ้าผมทำแม่ / ลูก / หลาน / จะได้รับ 404
ร็อบ Vermeer

1

ฉันสร้างวิธีแก้ปัญหาแล้วไม่พบปัญหา โปรดลองและบอกฉันหากคุณพบปัญหา

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

เปลี่ยน 'yemek' ด้วยชื่อประเภทโพสต์ของคุณ


0

ลิงก์นี้ควรตอบคำถามของคุณ:

http://ottopress.com/2011/how-the-postname-permalinks-in-wordpress-3-3-work/


ไม่มันไม่เพียงอธิบายวิธีการทำงานในแง่ของ SQL เท่านั้น แต่ไม่ได้พูดถึงประเภทโพสต์ที่กำหนดเองซึ่งเป็นปัญหา
Ciantic

0

คำตอบที่ชัดเจนที่สุดที่ฉันสามารถทำได้สำหรับสิ่งนี้ (ฉันกำลังสร้างปลั๊กอินที่ต้องการประเภทโพสต์ที่กำหนดเองโดยไม่ต้องใช้ตัวบุ้งนำหน้า) คือการใช้เทมเพลตหน้าเว็บที่กำหนดเองแทนการใช้ประเภทโพสต์แบบกำหนดเอง

ด้วยการทำเช่นนี้ "ประเภทโพสต์ที่กำหนดเอง" ของคุณสามารถมี URL เช่น / อะไรก็ได้โดยไม่ต้องกังวลเกี่ยวกับการก้าวไปบนหน้าเว็บหรือโพสต์ลิงก์ถาวร

เมื่อต้องการทำสิ่งนี้ฉันลงเอยด้วยการทำสิ่งต่อไปนี้:

  • การเพิ่มเทมเพลตหน้ากำหนดเองภายในปลั๊กอินของฉัน
  • การตั้งค่าเทมเพลตหน้าเพื่อให้สามารถเลือกได้ในตัวแก้ไขหน้า
  • การสร้างเมตาบ็อกซ์ที่กำหนดเองซึ่งจะปรากฏสำหรับเทมเพลตหน้าของฉันเท่านั้น

สิ่งนี้ทำให้ฉัน:

  • ดึงรายการของเพจที่ใช้เทมเพลตหน้าโดยใช้WP_Query

  • เพิ่มการประมวลผลพิเศษโดยการเชื่อมต่อเข้ากับadd_meta_boxesเพื่อเก็บข้อมูลที่กำหนดเองของฉัน

  • เพิ่มเทมเพลตที่กำหนดเองของฉันลงในรายการที่แสดงโดยการกรอง page_attributes_dropdown_pages_args, theme_page_templates, wp_insert_post_data และ template_include ดูโพสต์นี้ในการเพิ่มเทมเพลตหน้าลงในปลั๊กอิน

ด้านข้างลง

แน่นอนว่าแม้ว่าสิ่งนี้จะไม่กระทืบบนหน้าเว็บหรือลิงก์โพสต์ แต่ก็มีข้อเสียที่ชัดเจนสองสามข้อ

ไม่มีการเก็บถาวร คุณจะไม่มีการเก็บถาวร (ถ้าคุณต้องการ) แม้ว่าจะสามารถแก้ไขได้โดยการสร้างเทมเพลตหน้าอื่นเพื่อวาดการเก็บถาวรของทุกหน้าโดยใช้เทมเพลตที่กำหนดเองของคุณ

จัดการภายใต้หน้า คุณไม่ได้รับการนำทางด้านซ้ายมืออย่างดีในผู้ดูแลระบบที่จัดกลุ่มโพสต์ทั้งหมดเข้าด้วยกัน

สิ่งนี้อาจแก้ไขได้บางส่วนโดยการเพิ่มตัวกรองในรายการหน้า (เพื่อให้คุณสามารถกรองโดยใช้เทมเพลตหน้า) แสดงเทมเพลตหน้าใด ๆ ที่ใช้ในคอลัมน์ใหม่ ฯลฯ


ที่ถูกกล่าวว่าฉันต้องการสิ่งที่จะไม่ทำให้ผู้ใช้สงสัยว่าทำไมพวกเขาสร้างหน้ากำหนดเองใหม่และพบว่าพวกเขาไม่สามารถเข้าถึงหน้าปกติหรือหน้ากำหนดเองใหม่ทำให้หน้าเว็บที่มีอยู่ในเว็บไซต์ของพวกเขาหายไป

ฉันรู้ว่ามันไม่ใช่ทางออกที่แท้จริงแต่เป็นทางเลือกที่ใช้งานได้ดีสำหรับความต้องการของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.