web-dev-qa-db-ja.com

2つのURLで投稿タイプアーカイブの2つのビューを作成する

コメントで要求されているように、より具体的にするために2月6日6日に更新。

私は2つのビューを提供したいスラッグ "プロジェクト"で、私たちはそれを "プロジェクト"と呼びます。

  1. リストビュー(デフォルト)
  2. マップビュー

私はこれらの見解が以下のパーマリンクにあることを望みます:

  1. example.org/projects/(デフォルトの投稿タイプアーカイブページ、archive-projects.php
  2. example.org/projects/map/

WordPressに特定のテンプレートを使用するように指示するにはどうすればよいですか。そのリダイレクトがデフォルトのポストタイプのアーカイブクエリを維持することができればいいでしょうが、必要ならばテンプレートに二次ループを書くことができます。最初はエンドポイントがその答えだと思っていましたが、それは正しくないと確信しています。


元の投稿

"Projects"という投稿タイプがあります。そのために、投稿タイプのアーカイブを2つ表示してください。 1つ目は、カテゴリ別に分類されたかなり単純なプロジェクトのリストです。2つ目は、プロジェクトのマップビューです。これら2つのビュー用のテンプレートを作成することは問題ありません。

それぞれ独自のURLを持つ投稿タイプアーカイブのこれら2つの異なるビューを作成するにはどうすればよいですか?

理想的には、最初のテンプレートを/projects/のデフォルトにし、2番目のテンプレートを/projects/map/のデフォルトにします。

それはカスタムエンドポイントが行くべき道のように思えました、しかし このコメント 私が探しているものを完全に説明するタイトルを持つ古い質問について/カスタムだけのためにエンドポイントを持つ方法がない投稿タイプアーカイブ。

それでは、カスタムの書き換えを使用する必要がありますか。それとも、もっとjQueryを重視したソリューションを使用することを検討すべきですか。

4
mrwweb

更新されたアプローチ

私が実際に最初に考えた/提案したことは - あなたが言ったように - 私がそれを理解したようにうまくいかない。少なくとも私はそれを試してみてそれを理解することができませんでした。それでも、あなたが望むものはまだ達成可能ですが、エンドポイントを使用することによって、または少なくともadd_rewrite_endpoint()を使用することによっては達成されません。

しかし、私はそれが「普通の」書き換え設定によって可能であるべきだと考えました。以下のコードは、投稿タイプアーカイブのカスタムビューを可能にするために、 投稿タイプ クエリ変数 、および 書き換えルール を設定する方法を示しています。最後になりましたが重要なこととして、 正しいテンプレートをロードすることを確認する必要があります 。これは一種のエンドポイントをエミュレートすることです。模範的なコードは正しい方向へあなたを導いてくれるはずなので、あなたはそれをあなたのニーズに合わせることができます。

コード:

// minimal setup to register the new post type
add_action( 'init', 'wpse130664_pt_rw_ep_cpt');
function wpse130664_pt_rw_ep_cpt() { 
    register_post_type( 'rw_ep_cpt', 
        array(
            'label' => __( 'rw_ep_cpt', 'rw_ep_cpt_textdomain' ),
            'public' => true,
            // the archive slug defaults to the post type name »rw_ep_cpt«
            'has_archive' => true
        )
    );  
} 

// add a new query variable
add_filter('init', 'wpse130664_pt_archive_qv');
function wpse130664_pt_archive_qv() {
    global $wp;
    $wp->add_query_var('aview');
}

// add a new rewrite rule
add_filter('init', 'wpse130664_pt_archive_rw_rule');
function wpse130664_pt_archive_rw_rule() {
    // we're adding »aview« as a possibility to the slug 
    // of the custom post type archive we registered above
    // no need to match anything, e.g. with »$matches[1]«
    // so we're defaulting the aview query variable to 1
    // this kind of emulates a endpoint
    add_rewrite_rule( "rw_ep_cpt/aview$", "index.php?post_type=rw_ep_cpt" . '&aview=1', 'top' );
}

// load the »aview« template
add_filter( 'template_include', 'wpse130664_aview_tmpl_red' );
function wpse130664_aview_tmpl_red( $original_template ) {
    // we're loading the template conditionally, 
    // but only if we're actually at the »aview« "endpoint"
    if ( 1 == intval(get_query_var('aview')) ) {
        // you've to create the template you want to use here
        return get_template_directory().'/archive-aview.php';
    } else {
        return $original_template;
    }
}


コメントへの回答

一方で、関数get_query_var()add_query_var()ではなく、$wpグローバル上のメソッドを使用することを選択したのはなぜでしょうか。

正直に言うと、私は少し前に書いたいくつかのコードを再利用しました。あなたのニーズに合うようにそれを少しだけ改造しました。そこで私は$wpグローバルで上記のアプローチを使いました。しかし、それはもちろん の説明ではない - なぜ なので、私もそれに対処しようとします。

絶対に間違えていないのであれば、add_query_var()WPクラスの関数/メソッドとしてしか利用できません。だから上記の方法はそれを行うための方法です。

get_query_var()については、これを代わりに使用できますが、$wp_queryをグローバル化し、WP_Queryクラスのget()関数/メソッドを使用します。したがって、ある意味では、違いはそれほど大きくないはずです。

それに加えて、もう1つ考えて、WP_QueryオブジェクトはWPオブジェクトよりも大きくなる可能性がありますが、必ずしもそうとは限りません。そのため、グローバルな$wpを介してそれを行うことは、実際には良いことかもしれません。
しかし、実際にはこのトラフを考えたりテストしたりしたのではなく、このように使用していて、セットアップで機能しているので、そのコードを実行したときに満足しました。そのため、別のセットアップ/使用例には欠点があるかもしれません。あるいは、別の方法でそれを行うことは、他の場合にはより価値があり有益です。しかし、私が上で言ったように、これはあなたが始められるようにすることです、あなたはあなた自身のニーズにそれを適応させなければなりません。

コメント後に更新

@MarkJaquithの タイミングの良いブログ投稿 は、新しいテンプレートファイルをインクルードするのにより適しているtemplate_includeフィルタを私に示しました。そのフィルタを使用するようにコードを更新しました。サンプルコードも更新することをお勧めします。

@ mrwwebが指摘し、上記のリンク先の記事で説明されているように、template_redirectフィルタは別のテンプレートを選択するのに最適ではありません。あるいは@MarkJaquithが単純に結論づけているように、

→template _redirectredirect用です。
→template _includeincludesのためのものです。

彼は私を納得させたので、上のコードの"aview"テンプレートのロード方法をtemplate_includeフィルタに変更しました。




最初の考え/取り組み


免責事項:
これは、情報的価値があるために続けていますが、この はカスタム投稿タイプのアーカイブ では機能しません。ただし、ep_maskを使用すると、単一のカスタム投稿タイプの投稿のエンドポイントを作成するのに便利です。


私が理解していることから、そのような場合にはエンドポイントを実行できます。私は最近それについて読みましたが、実際にそれに近づく必要はありませんでした。それで、これは私の知る限りのことであり、もっと多くの情報を持った人がやって来て、物事を明確にするでしょう。

あなたはあなたが言ったことに正しいです:

私の理解するところでは、エンドポイントはポストタイプのアーカイブに対しては機能しません。それらはその投稿タイプ内の投稿を対象としていますが、アーカイブ自体は対象としていません。


そのため、下記のようなep_maskパラメータを使用してカスタム投稿タイプの投稿に使用できますが、notはアーカイブには使用できます。 それに加えて、これをプレイすることで、カスタムのep_maskが単一のカスタム投稿タイプのエンドポイント作成にどれほど便利であるかを実感しました。

基本的に私が読んだものはep_maskを使ったときに使える引数を使うことです。

そして

rewrite引数.

関連する tracのチケット19275 を見てください。 permalink_epmaskの説明のregister_post_type() codexページ、特に tracチケット12605 に、おそらく役に立つと思われる追加情報があります。

エンドポイントについての概要は:

答えはこれです:

カテゴリについては、もちろんEP_CATEGORIESがすでにありますが、ep_mask引数を使用すれば、それは本当に可能であるはずであることを示しています。

5
Nicolai

03/12/17を更新

以下で言及されているプラ​​グインは放棄されています、私が現在維持しているものは別のパッケージです、 Cortex


私の答えを代替案として考えてみてください。

私はプラグイン、 Clever Rules を開発しました。これはルート、問い合わせそして(とりわけ)特定のテンプレートを指定することを可能にします。

賢いルールを使用するために必要なものはルールを登録することですが、現在のバージョンではルールはテーマではなくプラグインでのみ登録できることに注意してください。

巧妙なルールをダウンロードし、それをアクティブにします。ルールを登録するためのプラグインが必要です。新しいプラグインを作成するか、開発中のプラグインに次のコードを挿入します。

add_action('plugins_loaded', 'register_my_rules');

function register_my_rules() {

    // next line ensure function runs only if Clever Rules is installed
    if ( ! function_exists('register_clever_rule') ) return;

    $args = array( 'route' => '/projects/map/', 'query' => 'post_type=projects' );

    register_clever_rule( $args )->template('your-specific-template.php');

}

この3行のコードが、あなたが必要とする唯一のものです。そのための新しいプラグインを作成した場合は、もちろんそれをアクティブにします。

どのデフォルトURLも影響を受けません。

'your-specific-template.php'は、親または子テーマのテンプレートファイルにすることができます。もちろん、あなたが望むようにクエリをカスタマイズし、他のプラグイン機能を使用することができます。

あなたがシステムが好きなら、あなたはあなたが必要とするすべてのルールを登録するために同じプラグインを使うことができます。

ノート

私はそのプラグインの新しいバージョンを開発しています。それはもう少しパフォーマンスが良く(ルールがたくさんあっても1つだけが問題ではない)、テーマにルールを登録できるようにします。間もなく公開される予定ですが、現在のバージョンも機能します。

1
gmazzap