/%postname%/ permastructを使用したWordpress 3.3カスタム投稿タイプ?


9

同じようなタイトルの以前の投稿がありますが、WordPress 3.3には見えません。3.3が興味深い宣伝をしているので、これは重要です:「パフォーマンスの低下なしに投稿名のパーマリンク構造を使用してください」

Wordpress 3.2以前の問題は、最初にページ名、次に404を検索することでした。最初に任意の投稿タイプをチェックしませんでした。一方、3.3は投稿タイプ、ページ、最後に404(この機能をアドバタイズするため)でなければなりません。これは、どこかにハードコーディングしていなければ、slugのないカスタム投稿タイプは単純でなければならないことを意味しますpost_type=post

まだ3.3固有の解決策が見つかりません。

質問:特定のカスタム投稿タイプ「xyz」に対してパーマリンク構造体「/%postname%/」をどのように定義できますか?

ありがとう。


質問はありません。実際に何を質問していますか。
Travis Northcutt 2012年

明確にするために、/%postname%/?のパーマリンク構造を使用する新しいカスタム投稿タイプを定義する必要があります。投稿にも同じパーマ構造を使用することを計画していますか、それともプレフィックスを付けますか?
prettyboymp

これに続いて、誰かが答えを考え出すかどうかを確認します。上記のアプローチも試してみましたが、リライトスラグを「/」に設定するだけで、ページのパーマリンクも壊れます。Le sigh ...

回答:


2

WP 3.3では、書き換えルールをだまして正しい場所に配置し、wp_rewriteでフロントエンドで詳細ルールが使用されていると思わせない限り、これは簡単には行えません。以下のクラスは動作します。

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 2012年

ロブ、新しい投稿を追加しましたか、それとも新しい「テスト」投稿を追加しましたか?これは、投稿が/%post_name%/のパーマ構造を持つ必要があるかどうかという元の質問では明確ではありませんでした。その場合、なぜ新しい投稿タイプを作成するのですか?また、複数の投稿タイプが同じパーマ構造を持っている場合、名前の競合に関する潜在的な問題が発生します。
prettyboymp

1

聖なる車の鍵!

これはうまくいくと思います。それはほとんど機能し、それは非常にシンプルで、たった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%");

PS自宅でこれを試す場合、この1行を追加した後、[設定]-> [パーマリンク]に移動して変更を保存すると、パーマリンクが更新されます。

私は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のサポートがあり、デフォルトでリダイレクトするだけです。手のひら
Ciantic、2012年

1

prettyboympの答えは昨日得たものとほとんど同じですが、私はそれに満足していません。prettyboympの回答には1つの欠点があります。/%postname%/が複数の投稿タイプで同時に使用されている場合は機能しません。

これが私の答えです。これも現在の構造を調べ、フォールバックする投稿タイプの配列を作成します。ただし、これにも1つの問題があります。2つの投稿タイプに同じスラッグがあり、両方が/%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

私がこれに対して思いつくことができる最もきれいな答え(私は、先頭のスラッグなしでカスタム投稿タイプを本当に必要とするプラグインを構築しています)は、カスタム投稿タイプを使用する代わりにカスタムページテンプレートを使用することです。

これにより、「カスタム投稿タイプ」に/ whateverなどの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.