Произвольные поля WordPress – инструмент улучшения сайта

Опубликовано 5 февраля 2023 в 16:59 (Обновлено 9 января 2024 в 14:11)

Время чтения: 23 мин

Пользовательские поля или произвольные поля WordPress (custom fields) - это один из самых мощных инструментов, доступных в этом движке.

Зачем нужны произвольные поля?

Произвольные поля WordPress особенно полезны при расширении WordPress за счет использования пользовательских типов постов (custom post types). Я постоянно создаю пользовательские типы постов для таких вещей, как товары, портфолио или галереи при разработке тем WordPress для клиентов.

Пользовательские поля очень удобны, когда нужно добавить детали продукта, такие как номера товаров или цены. К сожалению, поиск в WordPress по пользовательским полям невозможен из коробки. Чтобы исправить это, необходимо изменить поиск WordPress так, чтобы он включал пользовательские поля.

Рассмотрим зачем в WordPress нужны произвольные поля (Custom Fields), как их применять в своих проектах и многое многое другое.

Понимаю, что тем, кто нашел данный справочник скорее всего интересно как именно добавить кастомные поля на сайт технически, но не сказать более подробно о том, что это за поля мы не можем.

Простыми словами, произвольное поле - это блок с дополнительной информацией, которую можно добавить к, практически, любой записи в WordPress. Ниже я покажу как создание произвольного поля помогает добавить ссылку на оригинал статьи, если запись является переводом с другого языка.

Кроме того, через произвольные поля можно делать очень многое. Из простых примеров, которые вы найдете в других статьях про поля - это добавление поля "настроение". Или блок, где перечислен весь коллектив, который имеет отношение к какой-либо статье на сайте.

Например, в блоге про животных можно добавить произвольное поле в котором будет информация о породе какого-либо животного из статьи. В общем, вариантов использования таких полей может быть очень много.

Сам блок добавления кастомного поля в админке при добавлении записи выглядит примерно так:

Произвольные поля WordPress при добавлении записи
Произвольные поля WordPress при добавлении записи

Ниже покажу как закрыть реальную потребность заказчика с мини-задачей по доработке шаблона WordPress в виде добавления возможности через произвольные поля указывать ссылку на оригинал статьи.

Простое использование

WordPress позволяет авторам публикаций назначать пользовательские поля для своих публикаций. Эта произвольная дополнительная информация известна как метаданные (metadata). Эти метаданные могут включать такие кусочки информации как:

  • Настроение: Счастливый
  • В настоящее время Читаю: Золушка
  • Слушаю: Rock Around the Clock
  • Погода: Жарко и влажно

С помощью некоторого дополнительного программирования можно выполнить более сложные действия, например, использовать метаданные для хранения даты истечения срока давности публикации.

Метаданные обрабатываются парами ключ/значение (key/value). Ключом является имя элемента метаданных. Значение - это информация, которая будет появляться в списке метаданных для каждой отдельной записи, с которой эта информация связана.

Ключи можно использовать более одного раза на одну публикацию. Например, если вы читаете две разные книги (возможно, техническую книгу на работе и художественную литературу дома), вы можете создать ключ "reading" (или "читаю") и использовать его дважды в одной и той же записи, один раз для каждой книги.

Вот пример того, как эта информация может выглядеть в вашей записи:

Currently Reading: Calvin and Hobbes
Today's Mood: Jolly and Happy

Основываясь на нашем примере выше, давайте добавим два пользовательских поля, одно из которых называется "Сейчас читаю" (Currently Reading), а другое "Сегодняшнее настроение" (Today’s Mood). Пожалуйста, выполните следующие шаги, чтобы добавить эту информацию в запись, используя пользовательские поля.

  • Опции пользовательских полей на экранах редактирования публикаций и страниц по умолчанию скрыты, если они не использовались ранее. Используя Редактор блоков, нажмите кнопку с тремя точками в верхней части правой боковой панели и посетите раздел Опции, чтобы включить его. Если вы используете Классический редактор, проверьте опции экрана.
  • После того, как вы написали свою запись, прокрутите вниз до области под названием "Пользовательские поля" (Custom Fields).
  • Для создания нового пользовательского поля (Custom Field) под названием "Сейчас читаю" (Currently Reading) введите текст "Сейчас читаю" (без кавычек) в текстовом поле ввода под названием "Имя" (Name).
  • Вновь созданному Ключу ("Сейчас читаю") теперь должно быть присвоено Значение (value), которое в нашем случае является названием читаемой в настоящее время книги, например "Кальвин и Хоббс" (Calvin and Hobbes). Введите "Calvin and Hobbes" в поле Value, опять же без кавычек.
  • Нажмите кнопку Добавить пользовательское поле (Add Custom Field), чтобы сохранить эту пользовательскую информацию для данной записи.

Вот как это выглядит:

Произвольные поля в Wordpess
Произвольные поля в Wordpess

Чтобы добавить ваше "Настроение сегодня" (Today’s Mood), повторите процесс и добавьте "Настроение сегодня" к ключу и описание вашего настроения в текстовом поле значения и нажмите кнопку Add Custom Field (Добавить пользовательское поле), чтобы сохранить эту информацию вместе с сообщением.

В следующей записи вы можете добавить новую книгу и настроение в свои метаданные. В разделе Произвольные поля теперь будет выпадающий список с ранее введенными Пользовательскими полями.

Выберите "Сейчас читаю", а затем введите в значение новую книгу, которую вы читаете.

Нажмите кнопку Add Custom Field (Добавить пользовательское поле) и повторите процесс добавления "Today's Mood" (Сегодняшнее настроение).

Вам нужно лишь один раз создать новый "Ключ", после чего вы можете присваивать значение этому ключу для каждой записи, если вы этого пожелаете. Вы также можете назначить несколько значений ключу для записи. Это пригодится людям, которые читают несколько книг одновременно.

Отображение полей

Для отображения произвольных полей для каждой публикации необходимо использовать тег шаблона, который настраивает вашу тему. Для получения более подробной информации об этом, пожалуйста, обратитесь к:

  • the_meta() – Тэг шаблона, который автоматически перечисляет все произвольные поля публикации
  • get_post_custom() и get_post_meta() – Получает одну или все метаданные записи
  • get_post_custom_values() – Извлекает значения для пользовательского поля записи
  • Template Tags – Страница справочника разработчиков тем WordPress по тегам шаблонов

Вы можете установить Плагин, который управляет произвольными пользовательскими полями:

  • Meta Box plugin – Плагин, позволяющий создавать пользовательские метабоксы и пользовательские поля.
  • Piklist – Плагин, который позволяет создавать пользовательские метабоксы и поля повсюду в WordPress.
  • Advanced Custom Fields – Плагин, позволяющий создавать сложные поля и макеты с помощью дружественного интерфейса.

Что если произвольные поля не отображаются?

Первое и самое важное с чем можно столкнуться - это с тем, что блок "Произвольные поля" в WordPress (Custom Fields - см. скрин выше) не отображается в админке при добавлении "Записи" (Post).

Здесь есть два варианта почему блок не отображается:

  1. Блок для добавления произвольных полей не включен в настройках
  2. Установлен плагин ACF, который отключает базовые произвольные поля

Вариант 1

Здесь всё достаточно просто. В редакторе Gutenberg и в Классическом редакторе WordPress есть настройки, которые помогут включить отображение блока "Произвольные поля" при добавлении Записи.

Для классического редактора мы в самом верху жмем на "Параметры экрана" и в появившемся окне ставим нужную галочку напротив "Произвольные поля".

Всё. Закрываем "Настройки экрана" и продолжаем работать.

Для редактора Gutenberg нам нужно также включать блок с Произвольными полями в редакторе. Делается это немного по другому, чем в Классическом редакторе.

В Гутенберге в правом верхнем углу кликаем на иконку с тремя вертикальными точками. Выбираем "Предпочтения" (Options).

Затем выбираем "Панели" (Panels) и в "Дополнительно" (Additional) видим переключатель включения "Произвольные поля" (Custom Fields):

Теперь блок с добавлением полей должен появиться в админке при добавлении записей.

При этом, еще раз подчеркну, это работает, если у вас не установлен плагин ACF (Advanced Custom Fields). Если у вас установлен плагин ACF, то переходим ко второму варианту.

Вариант 2

Вообще, при наличии плагина ACF я бы не рекомендовал ничего делать и добавлял бы кастомные (произвольные) поля только через этот плагин. Но если вам прям так хочется, то идем дальше.

В ACF, начиная с версии 5.5.13, по умолчанию включена опция отключения опции настраиваемых полей в WordPress. Сделано это для ускорения скорости загрузки страницы редактирования после публикации. Т.е. ACF считает, что если этот плагин есть, то все можно сделать через него.

Если вам такое не нравится и мы хотим включить поля обратно, то в functions.php темы добавляем строчку:

add_filter('acf/settings/remove_wp_meta_box', '__return_false');

Теперь блок с добавление кастомных полей должен появиться.

Мое мнение, что как только вы познакомитесь с ACF, то будете использовать только это плагин, т.к. он перекрывает почти любые потребности при разработке сайтов на WordPress, но об этом ниже.

Вывод значений стандартных полей

Внимание! В данном случае мы не используем ACF, а работаем со стандартным блоком "Настраиваемых полей" на сайте WordPress. Про ACF дальше в этом руководстве.

Чтобы вывести поле на странице Записи мы делаем следующие шаги:

  1. Добавляем функционал вывода произвольного поля в теме WordPress
  2. Добавляем произвольное поле с названием и содержимом в админке
  3. Публикуем статью
  4. Проверяем запись и вывод поля во фронтенде

Так как у нас задача добавления "Кастомного поля" с названием "Ссылка на оригинал", то мы добавим поле original и вывод этого поля в файле single.php темы WordPress.

Для вывода поля в теме мы в single.php в цикле вставляем:

<?php while ( have_posts() ) : the post(); ?> // Начало Цикла

    <?php echo get_post_meta($post->ID, 'original', true); ?>

<?php endwhile; ?> // Конец цикла

Теперь мы просто добавляем поле original в админке при добавлении записи и обновляем Запись.

В итоге, на странице статьи мы увидим, что WordPress вывел значение поля original во фронтенде. Для одного из моих клиентов я делал сниппет с проверкой добавлено ли такое поле и только после этого выводить его на сайте:

<?php 
    $originalLink = get_post_meta($post->ID, 'original', true);

    if ($originalLink) {
        echo '<br><small><a href="' . $originalLink . '" target="_blank" rel="noopener nofollow">Ссылка на оригинал</a></small>';
    }

На сайте WP-kama пример привожу ниже.

Цитата: "Пример ниже показывает, как использовать функцию для того, чтобы получить значение произвольного поля thumb, в значении которого сохраняется ссылка на картинку-миниатюру, для того чтобы получить эту ссылку и использовать её в шаблоне".

<?php if ( $thumb = get_post_meta( $post->ID, 'thumb', true ) ) : ?>
	<a href="<?php the_permalink() ?>" rel="bookmark">
		<img class="thumb" src="<?php echo $thumb ?>" alt="<?php the_title(); ?>" />
	</a>
<?php endif; ?>

Вывод записей с определенными полями

Выводим список всех записей, содержащих конкретные произвольные поля.

Код позволяет вывести список всех записей с настраиваемым полем "Short_Link", отсортированный по значению пользовательского поля "Comment_Count", которое не исключает никаких "post_type" и предполагает, что каждая запись имеет только одно поле для Short_Link и одно для Comment_Count.

<?php
 
$meta_key1 = 'Short_Link';
$meta_key2 = 'Comment_Count';
 
$postids = $wpdb->get_col( $wpdb->prepare( 
    "
    SELECT      key1.post_id
    FROM        $wpdb->postmeta key1
    INNER JOIN  $wpdb->postmeta key2
                ON key2.post_id = key1.post_id
                AND key2.meta_key = %s
    WHERE       key1.meta_key = %s
    ORDER BY    key2.meta_value+(0) ASC
    ",
        $meta_key2,
    $meta_key1
) ); 
 
if ( $postids ) 
{
    echo "List of {$meta_key1} posts, sorted by {$meta_key2}";
    foreach ( $postids as $id ) 
    {
        $post = get_post( intval( $id ) );
        setup_postdata( $post );
        ?>
        <p>
            <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>">
                <?php the_title(); ?>
            </a>
        </p>
        <?php
    }
}

Left Join

Таблица 'postmeta' - это место, где в базе данных хранятся все данные произвольных полей. По умолчанию функция поиска WordPress настроена на поиск только в таблице 'posts'. Чтобы включить данные пользовательских полей в наш поиск, нам сначала нужно выполнить левое объединение (лефт джоин) таблиц 'posts' и 'postmeta' в базе данных.

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

Изменяем запрос (Query)

Нам нужно изменить поисковый запрос WordPress, чтобы включить в него произвольные поля.

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

Предотвращение дубликатов

Наконец, нам нужно добавить ключевое слово DISTINCT в запрос SQL, чтобы предотвратить возврат дубликатов.


/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

Добавьте следующее в файл functions.php, чтобы добавить функционал поиска в WordPress по кастомным полям.

Этот код не только изменит поиск во внешнем интерфейсе, но вы также сможете искать по пользовательским полям в админке.

<?php

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

Получение всех записей

Например, если нам надо получить все записи с одинаковым почтовым индексом (zipcode) в качестве метазначения, то следующий код можно использовать для наших целей:

$query_args = array(
        'post_type'   => 'service',
        'posts_per_page' => -1,
        'meta_query'  => array(
            array(
                'value'   => $zip,
                'compare' => 'LIKE',
                'key'     => 'zipcode',
            ),
        )
    );
   $query = new WP_Query($query_args);
   <?php if ( $query->have_posts() ) :while ( $query->have_posts() ) : $query->the_post();  ?>
       <h3><?php the_title(); ?></h3>
   <?php endwhile; // end of the loop. ?>
   <?php wp_reset_query(); ?>
   <?php else: ?>
      No results found.
   <?php endif; ?>

zipcode - это цифры, например 12345. Если записи имеют значение 12345 в пользовательском поле, то оно должно отображать все записи, которые имеют значение 12345.

Запрос записей

Ниже я приведу рекомендации по запросу (Query) по кастомным (произвольным) полям от создателей плагина ACF (Advanced Custom Fields) и расскажу, как получить массив объектов записей из базы данных с помощью собственных функций WordPress.

В WP существует множество способов запросить записи, однако в этой статье будут использованы общие функции get_posts, объект WP_Query и фильтр pre_get_posts.

Общие правила

Если вы уже знакомы с приведенными выше функциями, объектами и фильтрами, то можете пропустить этот блок.

Объект WP_Query используется для запроса записей и возвращает объект, содержащий массив объектов $post и множество полезных методов.

Функция get_posts использует вышеупомянутый объект WP_Query, однако возвращает только массив объектов $post, что делает ее более простым способом поиска и перебора постов.

Фильтр pre_get_post вызывается после создания объекта запроса, но перед выполнением самого запроса.

Пример

Этот пример демонстрирует, как запросить все посты и отобразить их в списке. Обратите внимание, что функции setup_postdata() и wp_reset_postdata() используются для того, чтобы такие функции, как the_permalink() и the_title(), работали как положено.

<?php 

$posts = get_posts(array(
	'posts_per_page'	=> -1,
	'post_type'			=> 'post'
));

if( $posts ): ?>
	
	<ul>
		
	<?php foreach( $posts as $post ): 
		
		setup_postdata( $post );
		
		?>
		<li>
			<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
		</li>
	
	<?php endforeach; ?>
	
	</ul>
	
	<?php wp_reset_postdata(); ?>

<?php endif; ?>

Параметры произвольного поля

И функция get_posts, и объект WP_Query принимают аргументы для запроса значений пользовательских полей. Существует как базовый, так и расширенный способ запроса, которые описаны ниже. Вы можете прочитать больше о параметрах в руководстве WP codex.

Основной пример

В этом примере показаны аргументы для поиска всех постов, в которых пользовательское поле 'color' имеет значение 'red'.

$posts = get_posts(array(
	'numberposts'	=> -1,
	'post_type'		=> 'post',
	'meta_key'		=> 'color',
	'meta_value'	=> 'red'
));

Продвинутый пример

В этом примере показаны аргументы для поиска всех записей, в которых пользовательское поле 'color' имеет значение 'red' или 'orange', а другое пользовательское поле 'featured' (флажок или чекбокс) отмечен галочкой.

$posts = get_posts(array(
	'numberposts'	=> -1,
	'post_type'		=> 'post',
	'meta_query'	=> array(
		'relation'		=> 'AND',
		array(
			'key'	 	=> 'color',
			'value'	  	=> array('red', 'orange'),
			'compare' 	=> 'IN',
		),
		array(
			'key'	  	=> 'featured',
			'value'	  	=> '1',
			'compare' 	=> '=',
		),
	),
));

Ниже вы найдете еще ряд примеров.

Обратите внимание, что в этих примерах используется объект WP_Query, а не функция get_posts, однако аргументы и логика остаются теми же.

Одно значение пользовательского поля

В этом примере мы найдем все записи, которые имеют тип поста (post_type) 'event', где пользовательское поле 'location' равно 'Melbourne'. Пользовательское поле 'location' в данном случае может быть текстовым полем, радиокнопкой или полем выбора (то, что сохраняет одно текстовое значение).

<?php 

// args
$args = array(
	'numberposts'	=> -1,
	'post_type'		=> 'event',
	'meta_key'		=> 'location',
	'meta_value'	=> 'Melbourne'
);


// query
$the_query = new WP_Query( $args );

?>
<?php if( $the_query->have_posts() ): ?>
	<ul>
	<?php while( $the_query->have_posts() ) : $the_query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>">
				<img src="<?php the_field('event_thumbnail'); ?>" />
				<?php the_title(); ?>
			</a>
		</li>
	<?php endwhile; ?>
	</ul>
<?php endif; ?>

<?php wp_reset_query();	 // Restore global post data stomped by the_post(). ?>

Множественные значения произвольных полей (значения на основе текста)

В этом примере мы найдем все записи, которые имеют тип записи (post_type) 'event', где пользовательское поле 'location' равно 'Melbourne', а пользовательское поле 'attendees' больше 100. Пользовательское поле 'attendees' в данном случае может быть числовым полем, текстовым полем, радиокнопкой или полем выбора (то, что сохраняет одно текстовое значение).

<?php 

// args
$args = array(
	'numberposts'	=> -1,
	'post_type'		=> 'event',
	'meta_query'	=> array(
		'relation'		=> 'AND',
		array(
			'key'		=> 'location',
			'value'		=> 'Melbourne',
			'compare'	=> '='
		),
		array(
			'key'		=> 'attendees',
			'value'		=> 100,
			'type'		=> 'NUMERIC',
			'compare'	=> '>'
		)
	)
);


// query
$the_query = new WP_Query( $args );

?>
<?php if( $the_query->have_posts() ): ?>
	<ul>
	<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>">
				<img src="<?php the_field('event_thumbnail'); ?>" />
				<?php the_title(); ?>
			</a>
		</li>
	<?php endwhile; ?>
	</ul>
<?php endif; ?>

<?php wp_reset_query();	 // Restore global post data stomped by the_post(). ?>

Множественные значения полей (значения на основе массива)

В этом примере мы найдем все записи, имеющие тип (post_type) 'event', в которых пользовательское поле 'location' равно 'Melbourne' или 'Sydney'. Пользовательское поле 'location' в данном случае может быть полем с несколькими вариантами выбора или полем с флажком (что-то, что сохраняет сериализованное значение массива).

<?php 

// args
$args = array(
	'numberposts'	=> -1,
	'post_type'		=> 'event',
	'meta_query'	=> array(
		'relation'		=> 'OR',
		array(
			'key'		=> 'location',
			'value'		=> 'Melbourne',
			'compare'	=> 'LIKE'
		),
		array(
			'key'		=> 'location',
			'value'		=> 'Sydney',
			'compare'	=> 'LIKE'
		)
	)
);


// query
$the_query = new WP_Query( $args );

?>
<?php if( $the_query->have_posts() ): ?>
	<ul>
	<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>">
				<img src="<?php the_field('event_thumbnail'); ?>" />
				<?php the_title(); ?>
			</a>
		</li>
	<?php endwhile; ?>
	</ul>
<?php endif; ?>

<?php wp_reset_query();	 // Restore global post data stomped by the_post(). ?>

О произвольных полях с использованием плагина ACF мы поговорили в этом материале.

Значения подполей

В этом примере мы найдем все events, у которых есть city или Melbourne или Sydney. Каждый city добавляется как новая строка в повторяющееся поле под названием location.

Чтобы успешно запросить значения подполей, нужно помнить, что номер строки неизвестен (может быть 1, 2 или даже 3 строки данных повторяющегося поля). Поэтому нам нужно использовать предложение LIKE в нашем SQL-запросе, чтобы разрешить WILDCARD в поиске мета ключа meta_key. Для этого мы создаем пользовательский фильтр, чтобы заменить стандартное '=' на 'LIKE'.

UPD: После изменения поведения esc_sql() в WordPress 4.8.3, теперь не так просто использовать символ % в качестве заполнителя для следующего поиска и замены, вместо него мы рекомендуем использовать символ $, как показано ниже.

Примечание: этот метод требует подключения к фильтру posts_where, который не гарантированно будет выполняться при всех запросах к записям. Чтобы решить эту проблему, установите значение suppress_filters равным false в массиве аргументов, передаваемых в get_posts() или WP_Query.

<?php 

// filter
function my_posts_where( $where ) {
	
	$where = str_replace("meta_key = 'locations_$", "meta_key LIKE 'locations_%", $where);

	return $where;
}

add_filter('posts_where', 'my_posts_where');


// vars
$city = 'Melbourne';


// args
$args = array(
	'numberposts'	=> -1,
	'post_type'		=> 'event',
	'meta_query'	=> array(
		'relation'		=> 'OR',
		array(
			'key'		=> 'locations_$_city',
			'compare'	=> '=',
			'value'		=> 'Melbourne',
		),
		array(
			'key'		=> 'locations_$_city',
			'compare'	=> '=',
			'value'		=> 'Sydney',
		)
	)
);


// query
$the_query = new WP_Query( $args );

?>
<?php if( $the_query->have_posts() ): ?>
	<ul>
	<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
		</li>
	<?php endwhile; ?>
	</ul>
<?php endif; ?>

<?php wp_reset_query();	 // Restore global post data stomped by the_post(). ?>

Включение редактора Gutenberg

На протяжении многих лет сообщество WordPress использовало пользовательские типы записей (CPT - Custom Post Types) для расширения функциональности стандартной платформы WordPress. Учитывая популярность, эта функция стала неотъемлемой частью WordPress 5.x.

В текущей версии WordPress редактор Gutenberg доступен только для страниц и записей по умолчанию.

Поскольку пользовательские типы постов WordPress присутствуют практически везде, недоступность редактора Gutenberg - это то, о чем сообщество говорило с момента выхода WordPress 5.0. Если у вас есть CPT на сайте WordPress с версией выше 5.x, то при создании или редактировании CPT вы увидите старый добрый классический редактор (Classic Editor).

Хотя в ближайших версиях планируется устранить эту особенность, вам не обязательно ждать, пока команда поддержки ядра WordPress выпустит обновление. На самом деле, если вы хотите использовать редактор Gutenberg с текущим кастомным постом на своем сайте, то нам нужно будет сделать минимум действий.

Я объясню как зарегистрировать пользовательский тип постов WordPress и затем покажу вам, как включить Gutenberg для пользовательских типов постов.

Регистрация пользовательских типов записей

Начнем с регистрации пользовательского типа записи. Этот процесс довольно прост и включает в себя добавление следующего фрагмента кода (сниппета - прим.ред.).

/* Register WordPress  Gutenberg CPT */
function cw_post_type() {

    register_post_type( 'portfolio',
        // WordPress CPT Options Start
        array(
            'labels' => array(
                'name' => __( 'Portfolio' ),
                'singular_name' => __( 'Portfolio' )
            ),
            'has_archive' => true,
            'public' => true,
            'rewrite' => array('slug' => 'portfolio'),
 
        )
    );
}
 
add_action( 'init', 'cw_post_type' );

Когда сниппет установлен, пользовательский тип поста зарегистрирован. Однако, что удивительно - когда вы попытаетесь создать или отредактировать пользовательский тип поста, вы все равно увидите старый редактор Classic.

Добавление поддержки Gutenberg

Теперь, чтобы включить редактор Gutenberg в пользовательских постах WordPress, необходимо выполнить дополнительный простой шаг - добавить следующий фрагмент кода к сниппету выше:

  1. добавить поддержку редактора,
  2. добавить ключ show_in_rest и установить его в true через ваш пользовательский тип поста
'show_in_rest' => true,
'supports' => array('editor')

Как вы можете видеть, приведенный выше фрагмент кода просто установил параметр 'show_in_rest' в значение 'TRUE'. После этого шага при создании или редактировании пользовательского типа поста вы увидите активным редактор Gutenberg.

Вот код, который вы поместите в файл functions.php, расположенный в папке темы:

/*Register WordPress  Gutenberg CPT */
function cw_post_type() {

    register_post_type( 'portfolio',
        // WordPress CPT Options Start
        array(
            'labels' => array(
                'name' => __( 'Portfolio' ),
                'singular_name' => __( 'Portfolio' )
            ),
            'has_archive' => true,
            'public' => true,
            'rewrite' => array('slug' => 'portfolio'),
            'show_in_rest' => true,
            'supports' => array('editor')
        )
    );
}
 
add_action( 'init', 'cw_post_type' );

Использование редактора Gutenberg с пользовательскими типами постов WordPress - это простой вопрос установки нужных параметров в файле functions.php. Как только нужный сниппет будет установлен, вы сможете легко получить доступ к редактору Gutenberg в ваших пользовательских постах.

Динамические параметры $_GET

Этот пример показывает, как использовать параметры $_GET (из URL) для изменения запроса архива типа post. В данном примере предполагается, что существует тип поста 'event' и что его архив существует по адресу URL; www.website.com/events.

Тип поста event содержит поле select под названием 'city' со значениями 'melbourne' и 'sydney'. Если добавить параметр к url, запрос будет изменен, и будут показаны только те посты, которые соответствуют 'city': www.website.com/events?city=melbourne.

// FUNCTIONS.PHP

function my_pre_get_posts( $query ) {
	
	// do not modify queries in the admin
	if( is_admin() ) {
		
		return $query;
		
	}
	
	
	// only modify queries for 'event' post type
	if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'event' ) {
		
		// allow the url to alter the query
		if( isset($_GET['city']) ) {
			
    		$query->set('meta_key', 'city');
			$query->set('meta_value', $_GET['city']);
			
    	} 
		
	}
	
	
	// return
	return $query;

}

add_action('pre_get_posts', 'my_pre_get_posts');

Вывод по таксономии

Отображение всех постов пользовательского типа, сгруппированных по пользовательской таксономии.

Часто возникает ситуация, когда нам нужно вывести все посты пользовательского типа, сгруппированных по пользовательской таксономии.

Допустим, пользовательский тип записи называется member, а пользовательская таксономия называется member_groups. Задача перечислить всех участников, но сгруппировать их в соответствующие группы.

<?php
$member_group_terms = get_terms( 'member_group' );

foreach ( $member_group_terms as $member_group_term ) {
    $member_group_query = new WP_Query( array(
        'post_type' => 'member',
        'tax_query' => array(
            array(
                'taxonomy' => 'member_group',
                'field' => 'slug',
                'terms' => array( $member_group_term->slug ),
                'operator' => 'IN'
            )
        )
    ) );
    ?>
    <h2><?php echo $member_group_term->name; ?></h2>
    <ul>
    <?php
    if ( $member_group_query->have_posts() ) : while ( $member_group_query->have_posts() ) : $member_group_query->the_post(); ?>
        <li><?php echo the_title(); ?></li>
    <?php endwhile; endif; ?>
    </ul>
    <?php
    // Reset things, for good measure
    $member_group_query = null;
    wp_reset_postdata();
}

Или так:

<?php // Output all Taxonomies names with their respective items
$terms = get_terms('member_groups');
foreach( $terms as $term ):
?>                          
    <h3><?php echo $term->name; // Print the term name ?></h3>                          
    <ul>
      <?php                         
          $posts = get_posts(array(
            'post_type' => 'member',
            'taxonomy' => $term->taxonomy,
            'term' => $term->slug,                                  
            'nopaging' => true, // to show all posts in this taxonomy, could also use 'numberposts' => -1 instead
          ));
          foreach($posts as $post): // begin cycle through posts of this taxonmy
            setup_postdata($post); //set up post data for use in the loop (enables the_title(), etc without specifying a post ID)
      ?>        
          <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>    
        <?php endforeach; ?>
    </ul>                                                   
<?php endforeach; ?>

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.