Добавление метабокса Атрибутов страницы и Шаблонов страниц на Страницу редактирования записей?
( Примечание модераторов: Первоначально заголовок был "Как я могу добавить селектор "Атрибуты страницы" и/или "Атрибуты страницы > Шаблон" в редактор сообщений")
WP в настоящее время позволяет назначать "шаблон" только страницам (т.Е. post_type=='page'
.) Я хотел бы также распространить эту функциональность на сообщения (т. Е. post_type=='post'
.)
Как я могу добавить мета-поле "Атрибуты страницы" и, более конкретно, переключатель шаблонов в сообщения редактор?
Я предполагаю, что это код, который я помещу в свой functions.php
для моей темы.
ОБНОВЛЕНИЕ: Мне удалось добавить раскрывающееся меню "Жестко запрограммированные шаблоны" в мой редактор сообщений, просто добавив html-код в поле "Выбор" в существующее поле "Пользовательские параметры мета". Вот код, который я использую для этого...
add_meta_box('categorydiv2', __('Post Options'), 'post_categories_meta_box_modified', 'post', 'side', 'high');
А вот функция, которая записывает параметры и поле выбора шаблона...
//adds the custom categories box
function post_categories_meta_box_modified() {
global $post;
if( get_post_meta($post->ID, '_noindex', true) ) $noindexChecked = " checked='checked'";
if( get_post_meta($post->ID, '_nofollow', true) ) $nofollowChecked = " checked='checked'";
?>
<div id="categories-all" class="ui-tabs-panel">
<ul id="categorychecklist" class="list:category categorychecklist form-no-clear">
<li id='noIndex' class="popular-category"><label class="selectit"><input value="noIndex" type="checkbox" name="chk_noIndex" id="chk_noIndex"<?php echo $noindexChecked ?> /> noindex</label></li>
<li id='noFollow' class="popular-category"><label class="selectit"><input value="noFollow" type="checkbox" name="chk_noFollow" id="chk_noFollow"<?php echo $nofollowChecked ?> /> nofollow</label></li>
</ul>
<p><strong>Template</strong></p>
<label class="screen-reader-text" for="page_template">Post Template</label><select name="page_template" id="page_template">
<option value='default'>Default Template</option>
<option value='template-wide.php' >No Sidebar</option>
<option value='template-salespage.php' >Salespage</option>
</select>
</div>
<?php
}
И, наконец, код для захвата выбранных значений на сохранить...
function save_post_categories_meta($post_id) {
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
$noIndex = $_POST['chk_noIndex'];
$noFollow = $_POST['chk_noFollow'];
update_post_meta( $post_id, '_noindex', $noIndex );
update_post_meta( $post_id, '_nofollow', $noFollow );
return $post_id;
}
Теперь, я полагаю, что все, что осталось, это (1) захватить выбранный шаблон и добавить его в мета-пост для этого поста и (2) изменить index.php и single.php чтобы он использовал выбранный шаблон.
2 answers
Ненавижу быть носителем плохих новостей, но WordPress жестко кодирует функциональность шаблона страницы в "страница" тип публикации , по крайней мере, в версии v3.0 (это может измениться в будущих версиях, но я пока не знаю о конкретной инициативе по его изменению. Так что это один из немногих случаев, когда я изо всех сил пытаюсь понять, как обойти что-то без взлома ядра.)
Решение, которое я придумал, состоит в том, чтобы в основном скопировать соответствующий код из Ядро WordPress и модифицируйте его в соответствии с нашими потребностями. Вот шаги (номера строк взяты из версии 3.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()
. Поскольку вы просили только шаблоны страниц, я опустил код для указания родительской записи и для указания порядка, что значительно упрощает код. Я также решил использовать для этого 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. Код a save_post
крючок
Теперь, когда у вас есть редактор, вам нужно на самом деле сохранить имя файла шаблона страницы для публикации, когда пользователь нажимает "Опубликовать". Вот код для этого:
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. Код a 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'
. По моему мнению, для решения пользовательских типов сообщений потребуется различать различные типы сообщений, и, хотя это не слишком сложно, я не пытался сделать это здесь.
Wordpress позволяет добавлять мета-данные в категории с помощью плагина:
Для этого вам нужно добавить одно из различных расширений, которое добавляет мету в категории (имитируя то, что страницы выходят из коробки), Простой термин Мета отлично справляется с этой задачей.
N.B.WordPress 3.x необходим для расширения категорий.
После этого вы можете использовать:
- добавить_терм_мета
- обновление_терм_мета
- get_term_meta
Использовать Functions.php чтобы добавить методы, позволяющие делать то, что вы хотите, например
add_action('category_add_form_fields', 'category_metabox_add', 10, 1);
function category_metabox_add($tag) { ?>
<div class="form-field">
<label for="image-url"><?php _e('Image URL') ?></label>
<input name="image-url" id="image-url" type="text" value="" size="40" aria-required="true" />
<p class="description"><?php _e('This image will be the thumbnail shown on the category page.'); ?></p>
</div>
<?php }
add_action('created_category', 'save_category_metadata', 10, 1);
function save_category_metadata($term_id)
{
if (isset($_POST['image-url']))
update_term_meta( $term_id, 'image-url', $_POST['image-url']);
}
Легко вызывать новые поля в темах:
<?php echo get_term_meta(get_query_var('cat'), 'image-url', true); ?>
Более подробная информация и примеры: http://www.wphub.com/adding-metadata-taxonomy-terms/