悪いニュースの持ち主であることが嫌いですが、WordPressはページテンプレート機能を「ページ」投稿タイプに少なくともv3.0でハードコーディングします(将来のバージョンでは変更される可能性がありますが、変更する特定のイニシアチブはありません)まだです。これは、コアをハッキングせずに何かを回避する方法を見つけるのに苦労している非常にまれな時間の1つです。)
私が思いついた解決策は、基本的にWordPressコアから関連するコードをコピーし、必要に応じて修正することです。手順は次のとおりです(行番号はv3.0.1からです)。
page_attributes_meta_box()
関数を535行目からコピーし、それ/wp-admin/includes/meta-boxes.php
に合わせて変更します。
add_meta_boxes
#1で作成されたメタボックスを追加するフックをコーディングします。
のget_page_templates()
行166から関数をコピーし、それ/wp-admin/includes/theme.php
に合わせて変更します。
のpage_template_dropdown()
行2550から関数をコピーし、それ/wp-admin/includes/template.php
に合わせて変更します。
テーマに投稿テンプレートを追加します。
save_post
保存時に投稿テンプレートファイル名を保存できるようにフックをコーディングします。
single_template
フックをコーディングして、関連する投稿の投稿テンプレートの読み込みを有効にします。
それで今!
1. page_attributes_meta_box()
関数をコピーします
最初のステップとして、page_attributes_meta_box()
535行目から関数をコピーする必要があり/wp-admin/includes/meta-boxes.php
、名前を変更することにしましたpost_template_meta_box()
。ページテンプレートのみを要求したので、親の投稿を指定するためのコードと、コードをより簡単にする順序を指定するためのコードを省略しました。またpage_template
、意図しない結合によって引き起こされる可能性のある非互換性を回避するために、オブジェクトプロパティを再利用するのではなく、これにpostmetaを使用することを選択しました。コードは次のとおりです。
function post_template_meta_box($post) {
if ( 'post' == $post->post_type && 0 != count( get_post_templates() ) ) {
$template = get_post_meta($post->ID,'_post_template',true);
?>
<label class="screen-reader-text" for="post_template"><?php _e('Post Template') ?></label><select name="post_template" id="post_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php post_template_dropdown($template); ?>
</select>
<?php
} ?>
<?php
}
2. add_meta_boxes
フックをコーディングする
次の手順では、add_meta_boxes
フックを使用してメタボックスを追加します。
add_action('add_meta_boxes','add_post_template_metabox');
function add_post_template_metabox() {
add_meta_box('postparentdiv', __('Post Template'), 'post_template_meta_box', 'post', 'side', 'core');
}
3. get_page_templates()
関数をコピーします
私は、ページテンプレートと投稿テンプレートを区別することだけが理にかなっており、したがっての行166にget_post_templates()
基づく機能の必要性があると想定しました。ただし、マーカーを使用する代わりに、この関数が使用するページテンプレートでは、代わりに使用できるマーカーを使用します。get_page_templates()
/wp-admin/includes/theme.php
Template Name:
Post Template:
私も検査を除外しましたfunctions.php
(それget_page_templates()
なしでどのように正しく動作したかはわかりませんが、何でも!)そして残っている唯一のことは、将来のメンテナンスの読みやすさのために単語page
への参照を変更することpost
です:
function get_post_templates() {
$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];
$post_templates = array();
if ( is_array( $templates ) ) {
$base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );
foreach ( $templates as $template ) {
$basename = str_replace($base, '', $template);
if ($basename != 'functions.php') {
// don't allow template files in subdirectories
if ( false !== strpos($basename, '/') )
continue;
$template_data = implode( '', file( $template ));
$name = '';
if ( preg_match( '|Post Template:(.*)$|mi', $template_data, $name ) )
$name = _cleanup_header_comment($name[1]);
if ( !empty( $name ) ) {
$post_templates[trim( $name )] = $basename;
}
}
}
}
return $post_templates;
}
4. page_template_dropdown()
関数をコピーします
同様にpage_template_dropdown()
、2550行目からコピーし/wp-admin/includes/template.php
て作成しpost_template_dropdown()
、get_post_templates()
代わりにcall に変更します:
function post_template_dropdown( $default = '' ) {
$templates = get_post_templates();
ksort( $templates );
foreach (array_keys( $templates ) as $template )
: if ( $default == $templates[$template] )
$selected = " selected='selected'";
else
$selected = '';
echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
endforeach;
}
5.投稿テンプレートを追加する
次のステップは、テスト用の投稿テンプレートを追加することです。Post Template:
ステップ3で言及したマーカーを使用してsingle.php
、テーマからコピーしsingle-test.php
、次のコメントヘッダーを追加します(の代わりにロードしてsingle-test.php
いることがわかるように、必ず何かを変更してくださいsingle.php
)。
/**
* Post Template: My Test Template
*/
手順1から5を完了すると、「投稿テンプレート」メタボックスが投稿エディターページに表示されます。
(ソース:mikeschinkel.com)
6. save_post
フックをコーディングする
エディターが四角になったので、ユーザーが[発行]をクリックしたときに、ページテンプレートファイル名を実際にpostmetaに保存する必要があります。そのためのコードは次のとおりです。
add_action('save_post','save_post_template',10,2);
function save_post_template($post_id,$post) {
if ($post->post_type=='post' && !empty($_POST['post_template']))
update_post_meta($post->ID,'_post_template',$_POST['post_template']);
}
7. single_template
フックをコーディングする
最後に、実際にWordPressで新しい投稿テンプレートを使用できるようにする必要があります。それを行うには、single_template
1つが割り当てられている投稿に必要なテンプレート名をフックして返します。
add_filter('single_template','get_post_template_for_template_loader');
function get_post_template_for_template_loader($template) {
global $wp_query;
$post = $wp_query->get_queried_object();
if ($post) {
$post_template = get_post_meta($post->ID,'_post_template',true);
if (!empty($post_template) && $post_template!='default')
$template = get_stylesheet_directory() . "/{$post_template}";
}
return $template;
}
そしてそれはそれについてです!
カスタム投稿タイプのみを考慮していないことに注意してください。私の意見では、カスタム投稿タイプに対処するには、異なる投稿タイプを区別する必要があり、それほど難しくはありませんが、ここではそれを試みませんでした。post_type=='post'