Custom fields в WordPress — примеры продвинутого использования
[ ←Вернуться к стандартному виду ]
Несмотря на то, что некоторые плагины предлагают свои «готовые» функции для вывода custom fields в шаблонах Темы, существует еще много разных «вкусностей», о которых в Кодексе WordPress написано крайне скудно.
Что такое custom fields (произвольные поля) в WordPress?
Многие видели такой бокс в админ. панели при написании/редактировании поста или страницы:
Произвольное поле (custom field) состоит из ключа (key) и его значения (value), и с помощью произвольных полей можно вывести практически любую информацию на странице записи (post) или Страницы (Page). Например, в боковой колонке, в шапке или в подвале блога. По сути механизм произвольных полей дает нам свободу в организации и расположении информации на странице записи и помогает выйти за пределы поля для написания/редактирования записи — все зависит от потребностей, структуры блога и вашей фантазии. Другими словами, мы можем располагать часть контента за пределами Цикла (Loop).
В имени ключа можно использовать латиницу, кириллицу, цифры, нижнее подчеркивание и пробелы — как вам удобно. Дефис в названии ключа (key) лучше не использовать.
Регистр букв в имени ключа имеет значение!
Проведенные здесь коды будут работать как вне Цикла, так и внутри его. Однако следует учитывать, что если в исходном коде одиночной записи/страницы между Циклом и выводом произвольного поля есть еще Циклы (например вывод «Еще из этой рубрики:» с помощью get_posts или query_posts), то тут результат непредсказуем и значение такого произвольного поля выведется из какой-нибудь другой записи, упомянутой в таком дополнительном Цикле, но не из текущей записи.
Полезные ссылки:
- Using_Custom_Fields
- The_Loop
- плагины для работы с произвольными полями: раз, два (wp 2.3.3 и ниже), три (wp 2.5 и выше)
- Иерархия шаблонов WordPress — рекомендуется к ознакомлению всем, кто собрался курочить Тему, а ниже мы этим как раз и займемся :) Если кратко, то за вывод одиночной записи отвечает шаблон
single.php, а за вывод страницы —page.php
Пример 1
Работа с изображениями
Например, настроение (привет жж) можно вывести не только текстом, но и рисунком или смайликом. Для этого создаем папку moodsв папке wp-content/uploads/, загружаем туда картинки happy.gif, sorry.gif, eh.gifи т.п., теперь в записи можно создавать ключ mood
А в нужном месте шаблона single.php(в папке Темы) прописываем:
<img src="http://site.ru/wp-content/uploads/moods/<?php echo get_post_meta($post->ID, "mood", $single = true); ?>.gif" alt="мое настроение" />
Если выбрать при создании/редактировании записи ключ moodи вписать значение happy, то получается:
<img src="http://site.ru/wp-content/uploads/moods/happy.gif" alt="мое настроение" />
Пример 2
Это все хорошо, но если в какой-либо записи настроение не указывать, то ссылка на файл получится битая:
<img src="http://site.ru/wp-content/uploads/moods/.gif" alt="мое настроение" />
Поэтому логично для каждого произвольного поля перед выводом проверять наличие значения для него:
<?php $image = get_post_meta($post->ID, 'mood', true); if($image !== '') { ?>
<img src="http://site.ru/wp-content/uploads/moods/<?php echo $image ?>.gif" alt="мое настроение" />
<?php } ?>
Пример 3
Можно также проверять на наличие значения для произвольного поля mood, и если оно отсутствует, то выводить дефолтовую катринку mymood.gif:
<?php $image = get_post_meta($post->ID, 'mood', $single = true); ?>
<?php if($image !== '') { ?>
<img src="http://site.ru/wp-content/uploads/moods/<?php echo $image; ?>" alt="мое настроение" />
<?php }
else { ?>
<img src="http://site.ru/wp-content/uploads/moods/mymood.gif" alt="без настроения" />
<?php } ?>
Пример 4
Вариантов может быть множество, вот пример с выводом через произвольные поля картинки, css класса для img и alt. В отличие от предыдущего варианта тут мы будет указывать абсолютный урл картинки — для разнообразия, вы можете прописать урл к картинке как вам угодно: только имя файла happy, имя файла с расширением happy.gifили абсолютный урл http://site.ru/wp-content/uploads/moods/happy.gif— главное, чтобы в результате всех манипуляций собрался полный урл к картинке.
Первый шаг:
Получаем значения произвольных полей урл картинки, css класси alt картинки(как видите, в ключах произвольных полей можно использовать не только латиницу, но и кириллицу и пробелы — как вам удобно):
<?php $image = get_post_meta($post->ID, 'урл картинки', $single = true); $image_class = get_post_meta($post->ID, 'css класс', $single = true); $image_alt = get_post_meta($post->ID, 'alt картинки', $single = true); ?>
Второй шаг:
Выводим значения произвольных полей, при этом перед выводом проверяем наличие значения для произвольного поля урл картинки, т.к. бессмысленно выводить изображение с битой ссылкой (пустым значением поля урл картинки), а вот если у изображения будет отсутствовать заполненный alt или css класс — то тут в общем ничего страшного не случится.
<?php if($image !== '') { ?>
<img src="<?php echo $image; ?>"
class="<?php if($image_class !== '') { echo $image_class; } else { echo "alignleft"; } ?>"
alt="<?php if($image_alt !== '') { echo $image_alt; } else { echo the_title(); } ?>"
/>
<?php }
else { echo 'фото отсутствует'; } ?>
В результате мы получаем: если значение для произвольного поля урл картинки существует (главное условие), то выводим картинку. При этом если заполнено поля css класс, то выводим его, если не заполнено, то css класс «по умолчанию» = alignleft. Аналогично с alt к картинке, если значение поля alt картинки существует, то выводим его, иначе вместо него выводится заголовок текущей записи.
Скриншоты:
Итак
Пример с выводом настроения — условный (ни разу не видела, чтобы кто-то в WordPress блоге выводил настроение, как в жж) и иллюстирует принцип работы с произвольными полями и в частности с картинками.
Пример 5
Пример чуть сложнее.
Допустим, мы хотим выводить в сайдбаре при просмотре одиночной записи (или страницы) ссылку, т.е. у нас будет 2 произвольных поля: урл ссылки и анкор ссылки. Анкор без ссылки — это просто текст, а вот ссылка без анкора — это уже нехорошо, поэтому будет проверять в первую очередь на существование значения ключа «анкор ссылки»:
- если анкор существует, а урл — нет, то выведется только анкор (т.е. просто текст)
- если анкор и урл существуют, то выведется полноценная ссылка
- если анкора не существует, а урл заполнен, то не выведется ничего — кому нужна ссылка без текста?
<?php
$url = get_post_meta($post->ID, 'url ссылки', true);
$ancor = get_post_meta($post->ID, 'анкор ссылки', true);
?>
<?php if($ancor !== '') { ?>
<?php if($url !== '') { ?>
<a href="<?php echo $url ?>">
<?php } ?>
<?php echo $ancor ?>
<?php if($url !== '') echo '</a>'; ?>
<?php } ?>
Пример 6
Один ключ и несколько значений
Если у произвольного поля один ключ и несколько значений у этого ключа, то вышеописанные способы не подходят — выведется только первое значение ключа. Как может случиться, что у одного ключа получается несколько значений? Например, при использовании любого из плагинов для вывода custom fields в админ. панели можно создать список-множественный выбор значений произвольного поля, на картинке справа список значений ключа «В номере» создан посредством плагина Custom Write Panel (работает до wp 2.3.3 включительно, для wp 2.5 и выше есть аналог этого плагина — FreshPost).
Вот таким кодом можно вывести все значения для ключа «В номере» (обратите внимание на то, что «В номере» и «в номере» — это разные ключи, регистр букв имеет значение!), значения будут разделяться запятыми:
<?php $inroom = get_post_meta($post->ID, "В номере", false);
if ($inroom[0]=="") {}
else{
echo implode(", ",$inroom);}
?>
UPD Другой вариант, значения ключа songs выводятся в виде ненумерованного списка:
<?php $songs = get_post_meta($post->ID, 'songs', false); ?>
<h3>Слушаю треки:</h3>
<ul>
<?php foreach($songs as $song) {
echo '<li>'.$song.'</li>';
} ?>
</ul>
Пример 7
Выводим nextgen gallery в боковой колонке
С помощью механизма произвольных полей можно вывести каждому посту свою галерею в боковой колонке. Что нам для этого надо? Создать галерею (речь идет о Nextgen Gallery) и посмотреть какой ID ей присвоен, затем создать ключ gallery-idи в значение записать ID галереи, все готово!
В sidebar.php, естественно, должен быть такой код (большое спасибо за него Максиму), который помимо всего прочего «страхует» нас от неправильного указания ID, который может состоят только из цифр, но не в коем случае букв:
<?php
$myid = $wp_query->post->ID;
$my_meta = get_post_custom_values( 'gallery-id', $myid );
if ( $my_meta) {
echo '<strong>Галерея</strong>: ';
foreach ( $my_meta as $val_key => $val_val )
$val_val = (int) trim( $val_val );
echo nggShowGallery($val_val);
}
?>
Пример 8
Каждой одиночной записи — своя шапка, или картинка в боковой колонке или что угодно!
Если у записи (поста) не заполнено значение произвольного поля шапка(полный урл к картинке), то берется картинка-шапка header.jpgиз папки imgактивной Темы, а если такое произвольное поле существует, то выводится индивидуальная картинка-шапка при просмотре этой записи вместо стандартной шапки:
<?php
if (is_single() || is_page() ) {
$shapka = trim(get_post_meta($post->ID, 'шапка', true));
if ( strlen($shapka) > 0 )
echo '<img src="' . $shapka . '" width="530px" height="240px" />';
else echo '<img src="' . TEMPLATEPATH . '/img/header.jpg" width="530px" height="240px" />'; }
else { echo '<img src="' . TEMPLATEPATH . '/img/header.jpg" width="530px" height="240px" />'; }
?>
Пример 9
Дополнительные слова в title записи
Привожу полностью свой любимый title для WordPress, вывод доп. слов в заголовок одиночной записи (поста) осуществляется с помощью произвольного поля с ключом seo-title:
<title><?php
if (is_home () ) { bloginfo('name'); }
elseif ( is_category() ) { single_cat_title(); }
elseif (is_single() ) { wp_title(' '); echo ' '; single_cat_title(); $key="seo-title"; echo get_post_meta($post->ID, $key, true); }
elseif (is_search() ) { bloginfo('name'); echo " результаты поиска: "; echo wp_specialchars($s);}
elseif (is_tag() ) { echo "Тег: >>>"; wp_title(' '); echo ' <<< '; bloginfo('name'); }
else { wp_title(); } ?></title>
Пример 10
Вывод google map с помощью custom fields
Способ, описанный в этой статье Custom Fields & Google Maps API (англ.) я пробовала — отлично работает!
Суть его в том, что создается произвольное поле gpsи в значение записывается координата маркера, например 43.743321,39.721069для Сочи. Скриншоты смотрите в статье.
Пример 11
Цикл (Loop), основанный на custom fields
Из Кодекса WordPress пример Цикла, который выведет посты из рубрик с ID=1,2 и 3, у которых есть произвольное поле paragraf, посты будут отсортированы по алфавиту значений ключа paragraf:
SELECT * FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id) LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id) LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) WHERE $wpdb->term_taxonomy.term_id = 1,2,3 AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->posts.post_status = 'publish' AND $wpdb->postmeta.meta_key = 'paragraf' ORDER BY $wpdb->postmeta.meta_value ASC
Пример 12
Сортировка записей в соответствии со значением определенного ключа custom fields.
Этим решением с нами поделился Александр Мальцев (mayuxi).
Пример: у нас есть посты с произвольным полем rating, допустим, у записи «Привет, мир!» значение произ. поля ratingравно 3, у записи «Как дила?» 69, а у записи «Ахтунг, мухтар» 1, тогда они выведутся в таком порядке:
- «Ахтунг, мухтар»
- «Привет, мир!»
- «Как дила?»
<?php
usort($posts, 'rating_sort');
function rating_sort($a, $b) {
$ar = get_post_meta($a->ID, 'rating', true);
$br = get_post_meta($b->ID, 'rating', true);
if ($ar == $br) return 0;
return ($ar < $br) ? -1 : 1;
}
if (have_posts()) : while (have_posts()) : the_post();
?>
Далее идет стандартный Цикл, примеры см. выше
Еще примеры циклов с использованием custom fields смотрите в статье «Чекбокс «Опубликовать на главной»
Пример 13
Добавляем css к конкретной записи (при просмотре одиночной записи)
Такой код вставить сразу после <?php <span class="keyword">while</span> (have_posts()) : the_post(); ?>в index.php или в single.php — без условия if (is_single ())
<?php if (is_single()) { ?>
<?php $newcss = get_post_meta($post->ID, 'post-css', true); ?>
<style type="text/css">
<?php echo $newcss; ?>
</style>
<?php }
// конец условия is_single
?>
Произвольное поле: post-css, в значение пишем css правила, например:
body {background:#ff0000!important;} .post {color:Green!important; font-size:14px} .entry p strong {color:#ccc!important;}
Пример 14
Организуем посты в серии с помощью custom fields
Источник: WordPress Custom Fields: Listing A Series Of Posts
Что значит серия? Это когда несколько постов объединены в общий сет, и при просмотре одиночной записи из определенной серии выводятся все посты из этой серии. Аналог — плагины типа related posts. Отличие — плагины типа related posts как бы сами «решают» какие записи являются связанными (подходящими) для конкретного поста, а тут мы имеем полный контроль над тем, какие посты должны быть в конкретной серии.
Т.е. мы создаем произвольное поле Серия, а в значение ему пишем наше название серии.
Код можно вставить в sidebar.php
<?php if (is_single() ) {
// проверяем принадлежит ли пост какой-нибудь серии
// получаем имя серии (
$series_name = get_post_meta($post->ID, 'Серия', $single = true);
// если пост в этой серии
if($series_name !== '') {
// выводим название серии
echo '<div class="single-offers"><h4>' . $series_name . ' — смотрите также:</h4>';
// формируем запрос в базу для вывода постов из этой серии
$query_string = "
SELECT *
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->postmeta.meta_key = 'Серия'
AND $wpdb->postmeta.meta_value = '$series_name'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date ASC
";
// выводим список постов
$series_posts = $wpdb->get_results($query_string, OBJECT);
if ($series_posts):
echo '<ul>';
foreach ($series_posts as $post):
echo '<li>'; ?>
<a href="<?php echo the_permalink(); ?>" title="<?php echo the_title(); ?>">
<?php echo the_title();
echo '</a></li>';
endforeach;
echo '</ul></div>';
endif;
rewind_posts();
}
// все, закончили с постами в серии
}
// закончили условие is_single()
?>
Пример 15
Цикл, в котором выводим посты с определенными произвольными полями, т.е. список постов, у которых есть хотя бы одно из указанных произвольных полей (в примере использованы имена произвольных полей Linksи MyData).
Источник: How to Only Retrieve Posts With Custom Fields
Думаю нет смысла дублировать здесь код, см. в конце статьи ссылку на загрузку файлов-примеров sidebar.phpи functions.php«Downloadable Code for Posts and Custom Fields»
Пример 16
Разные сайдбары для записей (постов)
(условимся, что сайдбары в папке Темы существуют, предназначены для вывода в одном месте лейаута блога и отличаются друг от друга содержимым, пример названий: sidebar.php, sidebar-var2.phpи sidebar-var3.php). См. в кодексе про get_sidebar.
Находим в файлах Темы вызов сайдбара:
<?php get_sidebar(); ?>
и заменяем его на:
<?php $sidebar = get_post_meta($post->ID, "sidebar", true); get_sidebar($sidebar); ?>
Теперь в каждой записи создаете произвольное поле sidebar, а в значение пишете ему часть имени (после sidebar- ) того сайдбара, который хотите показывать при просмотре этой записи: var2или var3. Если у одиночной записи нет произвольного поля sidebar, то выведется сайдбар «по-умолчанию» sidebar.php
Источник: WordPress hack: Choose the sidebar to use, post by post
Пример 17
Выводим что-либо в зависимости от значения определенного ключа custom field
<?php $value = get_post_meta($post->ID, 'hobbies', true);
if($value == 'gaming') {
echo '<a href="http://domain.tld/gaming/">Gaming Stuff</a>';
} elseif($value == 'sleeping') {
echo '<a href="http://domain.tld/sleeping/">Nap Supplies</a>';
} elseif($value == 'eating') {
echo '<a href="http://domain.tld/eating/">Dieting Advice</a>';
} else {
echo '<a href="http://domain.tld/">Home Page</a>';
}
?>
Пример 18
Выводим индивидуальный текст для more
Индивидуальный more (вместо стандартного «Читать далее») можно вывести несколькими способами, в том числе и с помощью произвольного поля. Вручную это делается так: <!--more Узнать чем дело закончилось!-->, но для этого нужно переключаться в режим «код» в виз. редакторе.
А вот способ с использованием custom field: ищем в single.php(файле, отвечающем за вывод одиночной записи) строчку
<?php the_content("Читать далее »"); ?>
и заменяем на:
<?php $custommore = get_post_meta($post->ID, 'custom_more', true); ?>
<?php if (!$custommore) { $custommore = 'Читать далее »'; } ?>
<?php the_content($custommore); ?>
В записи создаем ключ произвольного поля custom_moreи в значение пишем свой текст.
Пример 19
Выводим посты с определенным произвольным полем + условие для значения произвольного поля
Нашла в Кодексе новый параметр для произвольных полей в query_posts
meta_compare= оператор для meta_value=, по умолчанию '=', другие возможные значения '!=', '>', '>=', '<', и '<='
Примеры использования:
Вывод записей и страниц с ключем произвольного поля colorи любым значением, кроме blue:
<?php query_posts('post_type=any&meta_key=color&meta_compare=!=&meta_value=blue'); ?>
Вывод записей с ключем milesи числовым значением, которое меньше чем 22 (на заметку: значение 99 будет больше, чем 100, т.к. по сути это не числа; выход: давать значения такие как : 001, 055, 099):
<?php query_posts('meta_key=miles&meta_compare=<=&meta_value=22'); ?>
Нужные вещи
Плагин Mass Custom Fields Manager позволяет из админки массово управлять произвольными полями, больше не нужно открывать каждую запись / страницу чтобы внести изменения в custom filelds, с помощью этого плагина все делается на одной странице в админ. панели ВордПресса.
Про плагины, работающие с custom fields и облегчающие заполнение произвольных полей для записи / страницы я уже писала.





Подскажите пожалуйста, а из-за чего может перестать работать произвольное поле «image»? Я с помощью этого произвольного поля выводил на заглавное странице маленькую картинку. А после переезда на новый хостинг, произвольные поля остались, а картинка не выводится.
Спасибо! Благодаря custom fields реализовал кнопку «скачать» в постах своего блога.
Соника, огромное Вам спасибо — в одном посте квинтэссенцию кастомов объяснили на пальцах, теперь даже стыдно стало, что игнорировал их.
Здравствуйте!
Хотел прокомментировать Пример 14.
Не выдаются списки записей из серии в сайдбар, как Вы говорите. Вставляю этот код в сайдабр, ввожу поля «Серия» — но ничего не происходит.
Зашёл на указанный Вами источник. Там лежит вторая версия реализации этой возможности через добавление куска кода в function.php. Но... почему-то в теле статьи (нужно вставить строчку куда в single.php) всё выводится, а в сайдбаре — нет. Хотя просто вставляю строчку в sidebar.php
В чём может быть дело?
Спасибо! :)
В общем, если еще актуально и кому-то интересно:
Решил задачу с приложенным файлом:
<img src="<?php $image_id = get_post_meta ($post->ID, «File Upload», $single = true); echo get_attached_file ($image_id, $unfiltered); ?>" width="300"/>
Суть заключается в том, что по айдишику, который сохраняется в мета-поле, с помощью функции get_attached_file ($image_id, $unfiltered) определяем путь к файлу.
Но тут есть косячок — путь прописывается «нефильтрованный» фтп-шный,
аля «/public_html/temp01/wp-content/uploads/2010/02»
ничего толком в кодексе не нашел (в 2 ночи колупался) по поводу этой фильтрации, как-то там все мутно
но нашел, что обрабатывается эта функция в файле post.php
там есть такая строка $file = $uploads ['basedir']. «/$file»;
вот тут надо basedir заменить на baseurl, т.е. результат будет:
$file = $uploads ['baseurl']. «/$file»;
ну в общем и заработало :))))))))))))))))))
Скажите, пожалуйста! Мне нужно сделать, как в примере 14, только наоборот: в сайтбаре находится список всех значений (values) одного вида (key) custom-поля. При выборе, выводятся анонсы постов только с соответствующим значением. Как это можно сделать?
Заранее благодарен
Непонятно, а как в свои комментарии вставить avatar
Разные сайдбары для записей (постов)
скажите можно ли использовать тот же сайдбар копировав его, только под другими именами? и где их настроить под свой лад?
Здравствуйте. очень понравилась статья, сижу изучаю.
Подскажите пожалуйста, что такое в первом примере $post->ID и $single=true, а так же о каком loop'e (цикле) вы говорите в начале статьи?
Вопрос: у меня вот такая тема:
Но, когда я её активирую на локалхосте, Feature Article (самая верхняя, большая статья с картинкой; не знаю — рандомная она или нет) не видна. Я так понимаю, что она должна выводиться по умолчанию? Или я ошибаюсь? В настройках темы она не спрятана, т.е. «Enable», а не «Hide». Может что-то надо в пользовательских полях дополнительно прописать?
Заранее спасибо, если поможете разобраться.
А можно ли с помощью Custom fields добавлять к записи keywords и description (ну и title, хотя тут и написано, но сложновато :() спасибо заранее.
Скажите пожалуйста, а не могли бы вы написать пример использования custom полей для превью фотографий на главной страничке? Я ведь правильно понимаю, эта функция так же при помощи этих полей осуществляется? Заранее спасибо.