Ненавиджу бути носієм поганих новин, але WordPress жорстко кодує функцію "Шаблон сторінки" до типу публікації на "сторінці" , принаймні в версії 3.0 (що може змінитися в наступних версіях, але немає конкретної ініціативи, яку я знаю, щоб змінити її Але це один з небагатьох разів, коли я намагаюся зрозуміти, як обійти щось, не зламаючи серцевину.)
Я придумав таке рішення - в основному скопіювати відповідний код з ядра WordPress та змінити його на наші потреби. Ось такі кроки (номери рядків від v3.0.1):
Скопіюйте page_attributes_meta_box()
функцію з рядка 535 /wp-admin/includes/meta-boxes.php
та модифікуйте відповідно до цього.
Закодувати add_meta_boxes
гак , щоб додати METABOX створений в # 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()
. Оскільки ви просили лише шаблони сторінок, я пропустив код для вказівки батьківського допису та для визначення порядку, який робить код набагато простішим. Я також вирішив використовувати для цього postmeta, а не намагатися повторно використовувати page_template
властивість об'єкта, щоб уникнути та можливих несумісностей, спричинених ненавмисним зв’язком. Отже ось код:
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()
функцію
Я припускав, що має сенс розмежувати лише шаблони сторінок і шаблон публікації, таким чином, необхідність get_post_templates()
функції, заснованої на get_page_templates()
рядку 166 /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()
:
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
та повернувши потрібну назву шаблону для тих постів, яким було призначено одне:
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'
. На мою думку, вирішення спеціальних типів публікацій вимагало б розмежування різних типів публікацій, і, хоча це не надто складно, я цього не робив.