"my_plugin_lesson"という名前のカスタム投稿タイプを作成するプラグインを書いています。
$args = array (
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'lessons', 'with_front' => false)
);
register_post_type ('my_plugin_lesson', $args);
カスタム投稿タイプにはアーカイブがあり、アーカイブのURLは次のとおりです。
http://example.com/lessons
このアーカイブの外観をカスタマイズしたいです。標準のWordPressブログ投稿アーカイブではなく、表形式で投稿を一覧表示したいです。 archive-my_plugin_lesson.php
ファイルを作成することで、カスタムアーカイブテンプレートをテーマ内に作成できることを私は理解しています。しかし、私はプラグインが任意のテーマで動作するようにしたいと思います。
テーマファイルを追加または変更せずにアーカイブページの内容を変更する方法を教えてください。
編集: 私は archive_template
filterフックを使用できることを理解しています。しかし、これはテーマテンプレートを置き換えることだけです。テーマテンプレートはテーマ固有のものである必要があります。たとえば、ほぼすべてのテーマテンプレートにget_header
、get_sidebar
、およびget_footer
関数が必要になりますが、コンテンツの<div>
のIDは何になりますか。これはテーマごとに異なります。
私がやりたいことは、コンテンツ自体を自分のコンテンツに置き換えて、それを私のカスタム投稿タイプのアーカイブページの代わりに使用することです。
あなたが必要としているのはtemplate_include
フィルターをフックしてプラグインの中に選択的にあなたのテンプレートをロードすることです。
良い習慣として、あなたがあなたのプラグインを配布するつもりなら、あなたはarchive-my_plugin_lesson.php
(あるいは多分myplugin/archive-lesson.php
)がテーマの中に存在するかどうかをチェックするべきです。
この方法では、ユーザーがプラグインコードを編集せずにテーマ(または子テーマ)を介してテンプレートを置き換えるのは簡単です。
これは、一般的なプラグインで使用されている方法です。 WooCommmerce、ただ1つの名前を言うために。
add_filter('template_include', 'lessons_template');
function lessons_template( $template ) {
if ( is_post_type_archive('my_plugin_lesson') ) {
$theme_files = array('archive-my_plugin_lesson.php', 'myplugin/archive-lesson.php');
$exists_in_theme = locate_template($theme_files, false);
if ( $exists_in_theme != '' ) {
return $exists_in_theme;
} else {
return plugin_dir_path(__FILE__) . 'archive-lesson.php';
}
}
return $template;
}
Codexの詳細情報
archive_template
フックを使って、下のスキームを使ってテーマのアーカイブテンプレートのコンテンツを処理することができますが、テンプレートには基本的に古いものを含めることができるので、明らかにそこにあるテーマの一部しか処理できません。事.
スキームは、テンプレートを$tpl_str
フィルタの文字列(archive_template
)にロードし、あなたのコンテンツを置換し、(トリックeval( '?>' . $tpl_str );
を使って)その文字列をインクルードし、そして "wp-includes/template-"のinclude
が空ファイルを返すようにすることです。 loader.php "は何もしません。
以下は私がプラグインで使用するコードのハッキングバージョンです。これはget_template_part
を使用し、アーカイブよりも単一のテンプレートの処理に関心がある「クラシック」テンプレートをターゲットにしていますが、始めるのに役立ちます。セットアップは、空のファイル( "null.php")とコンテンツテンプレート( "content-single-posttype1.php"、 "content-archive-postype1.php"など)を保持する "templates"というサブディレクトリをプラグインが持っていることです。単一のケースのためのフォールバックテンプレート "single.php"と同様に、そしてこのディレクトリで見るget_template_part
のカスタムバージョンを利用します。
define( 'MYPLUGIN_FOLDER', dirname( __FILE__ ) . '/' );
define( 'MYPLUGIN_BASENAME', basename( MYPLUGIN_FOLDER ) );
add_filter( 'single_template', 'myplugin_single_template' );
add_filter( 'archive_template', 'myplugin_archive_template' );
function myplugin_single_template( $template ) {
static $using_null = array();
// Adjust with your custom post types.
$post_types = array( 'posttype1', );
if ( is_single() || is_archive() ) {
$template_basename = basename( $template );
// This check can be removed.
if ( $template == '' || substr( $template_basename, 0, 4 ) == 'sing' || substr( $template_basename, 0, 4 ) == 'Arch' ) {
$post_type = get_post_type();
$slug = is_archive() ? 'archive' : 'single';
if ( in_array( $post_type, $post_types ) ) {
// Allow user to override.
if ( $single_template = myplugin_get_template( $slug, $post_type ) ) {
$template = $single_template;
} else {
// If haven't gone through all this before...
if ( empty( $using_null[$slug][$post_type] ) ) {
if ( $template && ( $content_template = myplugin_get_template( 'content-' . $slug, $post_type ) ) ) {
$tpl_str = file_get_contents( $template );
// You'll have to adjust these regexs to your own case - good luck!
if ( preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
|| preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*get_post_format\s*\(\s*\)\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
|| preg_match( '/get_template_part\s*\(\s*\'content\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
|| preg_match( '/get_template_part\s*\(\s*\'[^\']+\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE ) ) {
$using_null[$slug][$post_type] = true;
$tpl_str = substr( $tpl_str, 0, $matches[0][1] ) . 'include \'' . $content_template . '\'' . substr( $tpl_str, $matches[0][1] + strlen( $matches[0][0] ) );
// This trick includes the $tpl_str.
eval( '?>' . $tpl_str );
}
}
}
if ( empty( $using_null[$slug][$post_type] ) ) {
// Failed to parse - look for fall back template.
if ( file_exists( MYPLUGIN_FOLDER . 'templates/' . $slug . '.php' ) ) {
$template = MYPLUGIN_FOLDER . 'templates/' . $slug . '.php';
}
} else {
// Success! "null.php" is just a blank zero-byte file.
$template = MYPLUGIN_FOLDER . 'templates/null.php';
}
}
}
}
}
return $template;
}
function myplugin_archive_template( $template ) {
return myplugin_single_template( $template );
}
カスタムのget_template_part
:
/*
* Version of WP get_template_part() that looks in theme, then parent theme, and finally in plugin template directory (sub-directory "templates").
* Also looks initially in "myplugin" sub-directory if any in theme and parent theme directories so that plugin templates can be kept separate.
*/
function myplugin_get_template( $slug, $part = '' ) {
$template = $slug . ( $part ? '-' . $part : '' ) . '.php';
$dirs = array();
if ( is_child_theme() ) {
$child_dir = get_stylesheet_directory() . '/';
$dirs[] = $child_dir . MYPLUGIN_BASENAME . '/';
$dirs[] = $child_dir;
}
$template_dir = get_template_directory() . '/';
$dirs[] = $template_dir . MYPLUGIN_BASENAME . '/';
$dirs[] = $template_dir;
$dirs[] = MYPLUGIN_FOLDER . 'templates/';
foreach ( $dirs as $dir ) {
if ( file_exists( $dir . $template ) ) {
return $dir . $template;
}
}
return false;
}
完全を期すために、これはカスタムのget_template_part
を使うフォールバック "single.php"です:
<?php
get_header(); ?>
<div id="primary" class="content-area">
<div id="content" class="clearfix">
<?php while ( have_posts() ) : the_post(); ?>
<?php if ( $template = myplugin_get_template( 'content-single', get_post_type() ) ) include $template; else get_template_part( 'content', 'single' ); ?>
<?php
// If comments are open or we have at least one comment, load up the comment template
if ( comments_open() || '0' != get_comments_number() ) :
comments_template();
endif;
?>
<?php endwhile; ?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
私は同じ質問を熟考してきました、そしてこれは私が思い付いた仮想的な解決策です:
プラグインを有効にしたら、wp_insert_postを使用して名前を投稿タイプ、内容をショートコードとしてページを作成します。
追加のスタイルの考慮事項のためにショートコードでオプションを提供することも、テーマ固有のスタイルまたはカスタムスタイルに一致するように投稿コンテナにクラスを追加することもできます。ユーザーはページを編集して、ループの前後に追加のコンテンツを追加することもできます。
フィルタsingle_template
を使うことができます。 コーデックスからの基本的な例 :
function get_custom_post_type_template($single_template) {
global $post;
if ($post->post_type == 'my_post_type') {
$single_template = dirname( __FILE__ ) . '/post-type-template.php';
}
return $single_template;
}
add_filter( "single_template", "get_custom_post_type_template" );