Wordpress 3.3 loại bài đăng tùy chỉnh với /% postname% / permastruct?


9

Có bài đăng trước đó với tiêu đề tương tự, nhưng nó không nhìn vào WordPress 3.3 và điều quan trọng là 3.3 quảng cáo thú vị: "Sử dụng cấu trúc permalink của postname mà không bị phạt hiệu suất"

Vấn đề với Wordpress 3.2 và trước đó là trước tiên nó trông giống tên trang và sau đó là 404. Nó không kiểm tra các loại bài đăng tùy ý trước. Mặt khác, 3.3 phải xem các loại bài đăng, sau đó là các trang và cuối cùng là 404 (vì nó quảng cáo tính năng này). Điều này ngụ ý rằng các loại bài đăng tùy chỉnh không có sên nên đơn giản , nếu chúng không mã cứng post_type=postở đâu đó.

Tôi không thể tìm thấy một giải pháp cụ thể 3,3 mặc dù.

Câu hỏi : Làm cách nào tôi có thể định nghĩa cấu trúc permalink "/% postname% /" cho bất kỳ loại bài đăng tùy chỉnh nào "xyz"?

Cảm ơn.


Tôi không thấy một câu hỏi - bạn thực sự đang hỏi gì?
Travis Northcutt

Để rõ ràng, bạn muốn xác định loại bài đăng tùy chỉnh mới sử dụng cấu trúc permalink của /% postname% /? Bạn có kế hoạch để có bài viết cũng sử dụng cùng cơ sở hạ tầng này, hoặc họ sẽ có tiền tố?
Prettyboymp

Theo dõi điều này để xem có ai đưa ra câu trả lời không. Tôi cũng đã thử các cách tiếp cận ở trên cùng với việc chỉ cần đặt sên viết lại thành '/', điều này cũng phá vỡ các liên kết trang. Lê thở dài ...

Câu trả lời:


2

Điều này không dễ thực hiện trong WP 3.3 trừ khi bạn lừa các quy tắc viết lại ở đúng vị trí và khiến wp_rewrite nghĩ rằng các quy tắc dài dòng đang được sử dụng ở mặt trước. Lớp học dưới đây hoạt động.

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

Sao chép dán mã này trong chủ đề của tôi, tuôn ra các quy tắc viết lại. Đã thêm một bài đăng mới, xem bài đăng (url là chính xác), đã nhận được 404 ... Trên WP 3.3.1. Bất cứ ý tưởng tại sao điều này sẽ không làm việc cho tôi? (Cảm ơn mã btw!)
Rob Vermeer

EP_NONE -> EP_PERMALINK để các trang bình luận hoạt động và sau đó để có nhiều loại bài đăng hoạt động với /% postname% / bạn cũng phải sử dụng bộ lọc parse_query. Xem câu trả lời của tôi ở trên.
Ciantic

Rob, bạn đã thêm một bài đăng mới hoặc thêm một bài đăng 'thử nghiệm' mới? Điều này không rõ ràng trong câu hỏi ban đầu về việc liệu các bài đăng có cần phải có cơ sở hạ tầng của /% post_name% /. Nếu đó là trường hợp tại sao thậm chí tạo ra một loại bài mới? Ngoài ra, bạn sẽ gặp các vấn đề tiềm ẩn với xung đột tên nếu có nhiều loại bài đăng có cùng cơ sở hạ tầng.
Prettyboymp

1

Chìa khóa xe thần thánh!

Tôi nghĩ rằng điều này làm việc . Nó gần như hoạt động, nó siêu đơn giản, chỉ có một dòng:

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 Nếu bạn thử điều này ở nhà, sau khi thêm một dòng này vào "Cài đặt" -> "Permalinks" và Lưu thay đổi, nó sẽ làm mới các permalinks.

Tôi đã đọc register_post_type()mã nguồn WP và tìm thấy một dòng:

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

Không cần phải nói nhưng không có sên tôi đã kết luận nó sẽ hoạt động, và nó đã làm được . Ngay cả chỉnh sửa permalink bên dưới tiêu đề trong trình chỉnh sửa cũng hoạt động chính xác!

Cập nhật: Điều này phá vỡ permalinks trang, trở lại bảng vẽ ...


Tôi cũng đã thử cái này, với kết quả tương tự. Sẽ rất tuyệt nếu điều này sẽ làm việc. Có lẽ một người khác với một ý tưởng?
Rob Vermeer

@RobVermeer Nhận thấy rằng không có dòng (chỉ có sên mặc định), WordPress đã có khả năng chuyển hướng đến url. Ví dụ: "some-post" chuyển hướng đến "anything / some-post". Trong mã, ở đâu đó trong mã có hỗ trợ cho CPT mà không cần sên, nó chỉ mặc định để chuyển hướng. cọ mặt
Ciantic

1

Câu trả lời của Prettyboymp gần giống như tôi đã nhận được ngày hôm qua, nhưng tôi không hài lòng với nó. Câu trả lời của Prettyboymp có một lỗ hổng, nó không hoạt động khi /% postname% / đang được sử dụng đồng thời trên nhiều loại bài đăng.

Đây là câu trả lời của tôi, cũng xem xét cấu trúc hiện tại và tạo ra các loại bài đăng để dự phòng. Mặc dù vậy cũng có một lỗ hổng, nếu hai loại bài đăng có cùng một sên và cả hai đều là /% postname% / thì nó hiển thị cả hai.

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

Có thể là một số loại bài đăng nhất định có thứ bậc. Tôi đã tự mình thử, nhưng dường như không có gì hoạt động ... Nó nghĩ rằng bài đăng là một tệp đính kèm với cha mẹ / con cái / ... Và nếu tôi làm cha mẹ / con / cháu / nó nhận được 404.
Rob Vermeer

1

Tôi đã tạo ra một giải pháp và tôi không thể tìm thấy một vấn đề với nó. Hãy thử và cho tôi biết nếu bạn tìm thấy một vấn đề

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

Thay đổi 'yemek' với tên loại bài đăng của bạn.



0

Câu trả lời rõ ràng nhất mà tôi có thể đưa ra cho vấn đề này (Tôi đang xây dựng một plugin thực sự cần một loại bài đăng tùy chỉnh mà không có bất kỳ sên hàng đầu nào) là sử dụng một mẫu trang tùy chỉnh thay vì sử dụng loại bài đăng tùy chỉnh.

Bằng cách này, "loại bài đăng tùy chỉnh" của bạn có thể có các url như / bất cứ điều gì mà không phải lo lắng về việc bước trên trang hoặc đăng permalinks.

Để làm điều này, cuối cùng tôi đã làm như sau:

  • Thêm một mẫu trang tùy chỉnh bên trong plugin của tôi
  • Thiết lập mẫu trang để có thể chọn nó trong trình chỉnh sửa trang
  • Tạo hộp meta tùy chỉnh chỉ hiển thị cho mẫu trang của tôi

Điều này cho phép tôi:

  • Kéo lên danh sách các trang sử dụng mẫu trang bằng WP_Query

  • Thêm xử lý đặc biệt bằng cách móc vào add_meta_boxes để lưu trữ dữ liệu tùy chỉnh của tôi

  • Thêm mẫu tùy chỉnh của tôi vào những mẫu được hiển thị bằng cách lọc page_attribut_dropdown_pages_args, theme_page_temsheet, wp_insert_post_data và template_include xem bài đăng này khi thêm mẫu trang vào plugin

Mặt trái

Tất nhiên, trong khi điều này không dậm chân trên trang hoặc đăng liên kết, nó có một vài nhược điểm rõ ràng.

Không có kho lưu trữ Bạn sẽ không có kho lưu trữ (nếu bạn muốn như vậy), mặc dù điều đó có thể được giải quyết bằng cách tạo một mẫu trang khác để vẽ một kho lưu trữ của tất cả các trang bằng mẫu tùy chỉnh của bạn.

Được quản lý trong Trang Bạn không có được điều hướng bên trái đẹp trong quản trị viên, nhóm tất cả các loại bài đăng lại với nhau.

Điều này có thể được giải quyết một phần bằng cách thêm bộ lọc vào danh sách trang (để cho phép bạn lọc theo mẫu trang đang được sử dụng), hiển thị bất kỳ mẫu trang nào được sử dụng trong một cột mới, v.v.


Điều đó đang được nói, tôi muốn một cái gì đó sẽ không khiến người dùng tự hỏi tại sao họ tạo một trang tùy chỉnh mới và thấy rằng họ không thể truy cập các trang bình thường hoặc trang tùy chỉnh mới khiến một trang hiện có trên trang web của họ biến mất.

Tôi biết đó không phải là một giải pháp thực sự , nhưng nó là một giải pháp thay thế phù hợp với nhu cầu của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.