/ % postname % / permastruct가있는 Wordpress 3.3 사용자 정의 게시물 유형?


9

제목이 비슷한 이전 게시물이 있지만 WordPress 3.3을 보지 않고 3.3이 흥미롭게 광고하기 때문에 중요합니다. "성능 저하없이 게시물 이름 영구 링크 구조 사용"

Wordpress 3.2 및 이전 버전의 문제는 처음에는 페이지 이름을보고 404를 보았습니다. 임의의 게시물 유형을 먼저 확인하지 않았습니다. 반면에 3.3 있어야 합니다 (이 기능을 광고하는대로) 마지막으로 404 포스트 유형, 다음 페이지, 봐. 이것은 슬러그가없는 사용자 정의 게시물 유형이 어딘가에 하드 코딩되지 않은 경우 단순 해야 함을 의미합니다 post_type=post.

그래도 3.3 특정 솔루션을 찾을 수 없습니다.

질문 : 특정 사용자 정의 게시물 유형 "xyz"에 대해 permalink 구조체 "/ % postname % /"를 어떻게 정의 할 수 있습니까?

감사.


질문이 보이지 않습니다. 실제로 무엇을 묻고 있습니까?
트래비스 노스 컷

명확성을 위해 / % postname % /?의 퍼머 링크 구조를 사용하는 새로운 사용자 정의 게시물 유형을 정의하려고합니다. 게시물에 동일한 영구 구조를 사용하도록 계획하고 있습니까, 아니면 접두사가 있습니까?
prettyboymp

이것을 따라 누군가가 답을 얻었는지 확인하십시오. 위의 접근 방식을 단순히 다시 쓰기 슬러그를 '/'로 설정하여 페이지 영구 링크를 끊는 것과 함께 시도했습니다. Le sigh ...

답변:


2

다시 쓰기 규칙이 올바른 위치에 있도록 속이고 wp_rewrite가 자세한 규칙이 프런트 엔드에서 사용되고 있다고 생각하지 않으면 WP 3.3에서는 쉽게 수행 할 수 없습니다. 아래 클래스가 작동합니다.

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이 정확함). WP ... 3WP를 받았습니다. 왜 이것이 효과가 없는지 아십니까? (코드 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%");

추신 집에서 이것을 시도하면이 한 줄을 추가 한 후 "설정"-> "퍼머 링크"로 이동하여 변경 사항을 저장하면 퍼머 링크가 새로 고쳐집니다.

WP register_post_type()소스 코드를 읽고 행을 찾았습니다.

$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"는 "anything / some-post"로 리디렉션됩니다. 코드 스피크에서, 코드 어딘가에 슬러그없이 CPT를 지원하는 것이 기본적으로 리다이렉션된다. face palm
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를 얻습니다.
Rob 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

이 문제를 해결할 수있는 가장 깨끗한 대답은 (정말 슬러그없이 실제로 사용자 정의 게시물 유형이 필요한 플러그인을 작성하고 있음) 사용자 정의 게시물 유형을 사용 하는 대신 사용자 정의 페이지 템플릿 을 사용하는 것입니다.

이렇게하면 "맞춤 게시 유형"에 페이지를 밟거나 퍼머 링크를 게시 할 걱정없이 / what과 같은 URL을 가질 수 있습니다.

이를 위해 다음과 같은 결과를 얻었습니다.

  • 플러그인 내부에 사용자 정의 페이지 템플릿 추가
  • 페이지 편집기에서 선택할 수 있도록 페이지 템플리트 설정
  • 내 페이지 템플리트에만 표시되는 사용자 정의 메타 상자 작성

이를 통해 다음을 수행 할 수있었습니다.

아래쪽

물론 이것은 페이지 나 게시물 링크에서 스톰 핑되지 않지만 몇 가지 명백한 단점이 있습니다.

아카이브 없음 아카이브 가 없을 경우 (그러나 원하는 경우) 사용자 정의 템플리트를 사용하여 모든 페이지의 아카이브를 그리기 위해 다른 페이지 템플리트를 작성하여 해결할 수 있습니다.

페이지 에서 관리 모든 게시물 유형을 그룹화하는 관리자의 멋진 왼쪽 탐색 기능이 없습니다.

이 기능은 페이지 목록에 필터를 추가하여 (사용중인 페이지 템플릿별로 필터링 할 수 있도록) 새 열에 사용 된 페이지 템플릿 등을 표시하여 부분적으로 해결할 수 있습니다.


즉, 사용자가 왜 새 사용자 정의 페이지를 작성했는지 더 이상 일반 페이지에 도달 할 수 없거나 새 사용자 정의 페이지로 인해 사이트의 기존 페이지가 사라지는 것을 알 수없는 것을 원했습니다.

나는 그것이 실제 솔루션 이 아니라는 것을 알고 있지만 내 요구에 잘 맞는 대안입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.