WordPress как на ладони
WordCamp Saint Petersburg 2018 wordpress jino

Carbon Fields 1.6 — контейнеры

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

Ниже описаны все возможные контейнеры Carbon Fields и их опции. В примерах создания контейнера есть примеры создания полей этого контейнера, так как без них он не имеет смысла.

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

Использование

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

Чтобы создать новый контейнер, используется метод make():

Container::make( $type, $title );
$type(строка) (обязательный)
Тип контейнера, определяющий предназначение группы полей и место отображения полей (в постах, таксономиях и т.д., см. ниже).
$title(строка) (обязательный)
Имя контейнера. Должно быть уникально в пределах WordPress.

Пример

Код создаст в постах типа page (страницы) поле с картой Google, поле с выбором произвольного виджета и поле для выбора изображения из медиабиблиотеки

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make('post_meta', 'Custom Data')
	->show_on_post_type('page')
	->add_fields(array(
		Field::make('map', 'crb_location')->set_position(37.423156, -122.084917, 14),
		Field::make('choose_sidebar', 'crb_custom_sidebar'),
		Field::make('image', 'crb_photo'),
	));

Post Meta (произвольные поля, метаполя)

Контейнер для расширения страницы редактирования постов (записи, страницы, произвольные типы постов). Введенные значения хранятся для каждого поста отдельно и добавляются по принципу работы функции add_post_meta.

Параметры отображения

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

Типы постов

Для одного типа записи:

->show_on_post_type('page')

Для нескольких типов записей:

->show_on_post_type(array('page', 'my_custom_post_type', 'post'))

Страницы и подстраницы

Отображение группы полей для отдельных страниц определяется путём (slug) или ID страницы

// Общий вид
->show_on_page( $page_path|$page_id )
// ID любой страницы
->show_on_page(17)
// Путь (slug) родительской страницы
->show_on_page('parent-page')
// Путь (slug родительской + slug её самой) подстраницы
->show_on_page('parent-page/sub-page')

Отображение группы полей для всех дочерних страниц определяет slug родительской страницы

->show_on_page_children('parent-page')

Шаблоны страниц

Отображение группы полей на страницах, использующих определенный шаблон

$template_path - это путь к файлу шаблона (или файлам)

// Общий вид
->show_on_template($template_path)
// Один шаблон в корне папки с темой
->show_on_template('about_us.php')
// Один шаблон в произвольной папке относительно папки с темой
->show_on_template('templates/contact.php')
// Несколько шаблонов
->show_on_template( array('about_us.php', 'templates/contact.php') )

Так же можно скрыть контейнер на страницах, использующих определенный шаблон(ы). Используется метод hide_on_template точно также, как и show_on_template.

->hide_on_template($template_path)

Форматы постов

Отображение группы полей в зависимости от формата поста (aside, chat, gallery, link, image, quote, status, video, audio).

// Общий вид
->show_on_post_format($post_format)
// Отображение контейнера в постах формата "Видео"
->show_on_post_format('video')
// Отображение контейнера в постах формата "Видео" или "Аудио"
->show_on_post_format( array( 'image', 'video' ) )

Вложенность

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

$level - это уровень вложенности, начиная от 1 и увеличивающийся при переходе вглубь иерархического дерева. На примере страниц:

// Общий вид
->show_on_level($level)
// Отобразить контейнер на родительских страницах (parent-pages)
->show_on_level(1)
// Отобразить контейнер на странице, вложенной в родительскую страницу (parent-pages/sub-page)
->show_on_level(2)
// Отобразить контейнер на странице, вложенной в другую страницу, которая вложена в родительскую страницу (parent-pages/sub-page/sub-sub-page)
->show_on_level(3)

Рубрики и произвольные таксономии

Группу полей можно отобразить в отдельной рубрике, указав её slug:

// Общий вид
->show_on_category( $category_slug )
// Частный случай
->show_on_category('news')

или для произвольного элемента таксономии:

// Общий вид
->show_on_taxonomy_term( $term_slug, $taxonomy )
// аналоги примера выше
->show_on_taxonomy_term('news', 'category')
// Произвольный терм (таксономия fruits с термом apple)
->show_on_taxonomy_term('apple', 'fruits')

Позиционирование контейнера

Подробную информацию о параметрах позиции можно найти в функции add_meta_box.

Контекст

Место где должен показываться блок: normal (по умолчанию), advanced или side

->set_context('normal')

Приоритет

Приоритет блока для показа выше или ниже остальных блоков: high (по умолчанию), core, default или low

->set_priority('high')

Примеры

Получить значение поля можно с помощью функции:

carbon_get_post_meta( $id, $name, $type = null )
$id(число) (обязательный)
ID поста, произвольные поля которого нужно получить.
$name(строка) (обязательный)
Название опции, значение которого нужно получить.
$type(строка)
Если нужно получить значение сложного поля (содержит в себе массив данных), то укажите complex.

Создадим контейнер для записей

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

Добавление контейнера для записей

В пользовательском файле:

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'post_meta', 'Author\'s note' )
	 ->show_on_post_type('post') // этот метод можно не писать, так как show_on_post_type('post') по умолчанию
		 ->add_fields(array(
			 Field::make('text', 'crb_author_description'),
			 Field::make('complex', 'crb_places')->add_fields(array(
				 Field::make('text', 'title'),
				 Field::make('image', 'photo')->set_value_type('url')
			 ))
		 ));

В шаблоне темы:

echo carbon_get_post_meta(get_the_ID(), 'crb_author_description');

$slides = carbon_get_post_meta(get_the_ID(), 'crb_places', 'complex');

if ( $slides ) {
	foreach ($slides as $slide) {
		echo '<p>' . $slide['title'] . '</p>';
		echo '<img src=" '. $slide['photo'] . '">';
	}
}

Если шаблон отображения метаполей используется в цикле, то вместо carbon_get_post_meta() можно использовать carbon_get_the_post_meta(), чтобы не указывать ID поста:

echo carbon_get_the_post_meta('crb_author_description');

$slides = carbon_get_the_post_meta('crb_places', 'complex');

Читайте подробнее о том, что такое цикл в WordPress

Хуки

После сохранения произвольных полей Carbon Fields вызывает хук carbon_after_save_post_meta, благодаря которому можно совершить какие-то действия:

add_action('carbon_after_save_post_meta', 'crb_after_save_event');
function crb_after_save_event( $post_id ) {
	if ( get_post_type($post_id) == 'post' ) {
		// Делаем свои дела
	}
}

Theme Options (настройки темы)

Для создания страниц настроек, где задействуется вся мощь API настроек (опций) WordPress, используются контейнеры настроек темы.

Одна страница с настройками

По умолчанию, в панели админки появится пункт Theme Options, который будет вести на главную страницу настроек:

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'theme_options', 'Theme Options' )
	->add_fields(array(
		Field::make('text', 'crb_facebook_url'),
		Field::make('textarea', 'crb_footer_text')
	));

Данная страница будет иметь slug admin.php?page=crbn-theme-options.php и выглядеть так:

Создание страницы настроек темы или плагина

Если использовать кириллицу, например make('theme_options', 'Пульт'), то slug страницы настроек примет вид admin.php?page=crbn-Пульт.php.

Несколько страниц с настройками

Можно создать несколько страниц с настройками, причем не важно, будут ли они входить в состав пунктов самого WordPress или произвольных (например страниц плагинов).

use Carbon_Fields\Container;
use Carbon_Fields\Field;

// Родительская страница настроек
Container::make( 'theme_options', 'Basic Options' )
		 ->add_fields(array(
			 Field::make('header_scripts', 'crb_header_script'),
			 Field::make('footer_scripts', 'crb_footer_script'),
		 ));

// Подстраница настроек, входящая в страницу 'Basic Options'
Container::make( 'theme_options', 'Social Links' )
		 ->set_page_parent('Basic Options')  // Название родительской страницы настроек
		 ->add_fields(array(
			Field::make('text', 'crb_facebook_link'),
			Field::make('text', 'crb_twitter_link')
		));

// Добавление подпункта (подстраницы) в раздел "Внешний вид"
Container::make( 'theme_options', 'Customize Background' )
		 ->set_page_parent('themes.php') // slug страницы "Внешний вид" в админке
		 ->add_fields(array(
			Field::make('color', 'crb_background_color'),
			Field::make('image', 'crb_background_image')
		));

Чтобы добавить вложенную страницу настроек, используется метод

set_page_parent( $parent )
$parent

Название родительской страницы настроек, если она создавалась через Carbon Fields

ID (он же slug в данном случае) страницы верхнего уровня в сайдбаре админки. Является параметром $parent_slug у add_submenu_page().

Права доступа к страницам настроек

По умолчанию доступ к страницам настроек имеют пользователи с возможностью edit_themes. Чтобы изменить этот параметр, используйте метод:

set_page_permissions( $permission )
$permission
роль/возможность пользователя. Полный список возможностей смотрите в описании параметра $capability у функции current_user_can(). Так понятно, кому будут доступны страницы настроек в зависимости от установленного права.

Иконка для родительского пункта меню

Изменить иконку родительского пункта меню можно с помощью метода:

set_icon( $icon )
$icon
класс от иконочного шрифта dashicons или путь к иконке-картинке.
use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'theme_options', 'Basic Options' )
	->set_icon('dashicons-carrot')
	->add_fields(array(
		Field::make('text', 'crb_test_field'),
	));

Напомню, что иконки можно указывать только родительским пунктам меню!

Вывод значений

Чтобы вывести значения полей настроек (опций) используется функция

carbon_get_theme_option( $name, $type = null )
$name(строка) (обязательный)
Название произвольного поля, значение которого нужно получить.
$type(строка)
Если нужно получить значение сложного поля (содержит в себе массив данных), то укажите complex.

Пример

<p>Копирайт <?php echo carbon_get_theme_option('crb_copyright'); ?></p>
<p>
	Адреса офисов компании:
	<?php 
	$address_lines = carbon_get_theme_option('crb_addresses', 'complex');
	foreach ($address_lines as $line) {
		echo $line . '<br/>';
	}
	?>
<p>

Хук после сохранения опций

Как и в случае с Post Meta, после сохранения опций темы вызывается хук carbon_after_save_theme_options, который позволяет изменять данные или делать что-то еще после сохранения.

Term Meta (таксономии)

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

Метаданные терминов сохраняются в базе в таблице $wpdb->termmeta

Напомню, что произвольные таксономии легко создаются плагином Custom Post Type UI или с помощью функции register_taxonomy.

Пример создания метаполей таксономии

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'term_meta', 'Настройки Term' )
		 ->show_on_taxonomy( 'category' ) // По умолчанию, можно не писать
		 ->add_fields( array(
			 Field::make( 'color', 'title_color', 'Цвет заголовка' ),
			 Field::make( 'image', 'thumb', 'Миниатюра' ),
		 ) );

На странице таксономии category (рубрики) теперь будут отображаться два поля: выбор цвета и загрузка миниатюры.

Тут мы добавили два поля:

  • Значения поля для выбора цвета используем, как цвет заголовка рубрики.
  • Значение поля для картинки используем как миниатюру рубрики.

Для прикрепления метаполей к конкретной таксономии, использовался метод

show_on_taxonomy( $taxonomy )
$taxonomy(строка/массив) (обязательный)
Название таксономии, которое указывается в функции register_taxonomy параметром $taxonomy или массив названий таксономий.
По умолчанию: category

Специально для создания миниатюр у терминов таксономий, есть отдельный, хороший код миниатюры для элементов таксономий.

Видимость по вложенности

Можно указать на каком уровне вложенности таксономии показывать контейнер с помощью метода

show_on_level( $level )
$level
уровень вложенности таксономии
// Общий вид
->show_on_level($level)
// Показать только в родительских таксономиях (1 уровень вложенности) (Фрукты)
->show_on_level(1)
// Показать только в таксономиях 2 уровня (Фрукты->Яблоки / Фрукты->Груши / Фрукты->Сливы),
->show_on_level(2)
// Показать только в таксономиях 3 уровня (Фрукты->Яблоки->Сорта / Фрукты->Яблоки->Рецепты / Фрукты->Яблоки->Болезни)
->show_on_level(3)

Вывод значений полей

Для получения значений полей контейнера используется функция

carbon_get_term_meta( $term_id, $name, $type = null )
$term_id(число) (обязательный)
ID таксономии
$name(строка) (обязательный)
Название произвольного поля, значение которого нужно получить.
$type(строка)
Если нужно получить значение сложного поля (содержит в себе массив данных), то укажите complex.

Пример вывода метаполей таксономий

<?php
// Получаем ID таксономии
$term_id = get_queried_object_id();

// Получаем значение поля для ввода цвета
$term_title_color = carbon_get_term_meta( $term_id, 'crb_title_color' );

// получим ID картинки из метаполя термина
$term_thumbnail_id = carbon_get_term_meta( $term_id, 'crb_thumb');

// ссылка на полный размер картинки по ID вложения
$term_thumbnail_url = wp_get_attachment_image_url( $term_thumbnail_id, 'full' );
?>

<!-- выводим миниатюру рубрики на экран -->
<img src="<?php echo $term_thumbnail_url; ?>" alt="" />

<!-- задаём стиль оформления заголовка рубрики -->
<style>
	h1{
		color: <?php echo $term_title_color; ?>;
	}
</style>

Хук после сохранения метаполей терминов

Как и в случае с Post Meta, после сохранения данных таксономии вызывается хук carbon_after_save_term_meta, который позволяет делать что-либо после сохранения метаданных. Хук передает параметр $term_id, который содержит ID текущего термина таксономии.

User Meta (пользователи)

Контейнер User Meta позволяет размещать метаполя на странице добавления и редактирования учетной записи пользователя. Данные для каждого пользователя сохраняются отдельно в точности как функция add_user_meta, т.е. в таблице wp_usermeta.

Пример создания контейнера

Создадим контейнер на странице создания/редактирования пользователя, состоящий из двух полей:

  • названия города проживания
  • и улицы с номером дома
use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'user_meta', 'Address' )
		 ->add_fields(array(
			 Field::make('text', 'crb_city', 'City'),
			 Field::make('text', 'crb_street', 'Street'),
		 ));

Видимость на основе роли пользователя

По умолчанию контейнер виден всем пользователям, но с помощью метода show_on_user_role() можно точно указать, кому будет виден контейнер.

show_on_user_role( $role )
$role(строка/массив)
Роль пользователей или массив ролей.

Пример указания роли

// Общий вид
->show_on_user_role($role)
// Показать контейнер только при добавлении/редактировании пользователя с ролью редактора
->show_on_user_role('editor')
  • О ролях и возможностях пользователя читайте в описании к функции current_user_can.

  • Если роль не соответствует заявленной, заголовок контейнера всё равно отображается.

  • Если указать контейнеру отображать поля для subscriber (подписчика) и зайти на страницу добавления нового пользователя, то WordPress по умолчанию в выпадающем списке ролей отображает "Подписчик", что не даёт javascript плагина отработать должным образом и поля контейнера не видны. Приходится выбрать другую роль, а затем снова выбрать "Подписчик", чтобы поля отобразились.

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

Для получения значений полей контейнера используется функция

carbon_get_user_meta( $user_id, $name, $type = null )
$user_id(число) (обязательный)
ID пользователя.
$name(строка) (обязательный)
Название произвольного поля, значение которого нужно получить.
$type(строка)
Если нужно получить значение сложного поля (содержит в себе массив данных), то укажите complex.

Пример

<!-- Простое поле -->
<p>Author address: <?php echo carbon_get_user_meta(get_the_author_meta('ID'), 'crb_street'); ?></p>

<!-- Сложное (комплексное) поле -->
<?php 
$phone_numbers = carbon_get_user_meta(get_the_author_meta('ID'), 'crb_phone_numbers', 'complex');
foreach ($phone_numbers as $phone) {
	echo $phone['country_code'] . '-' . $phone['number'];
}
?>

Хук

Как и в случае с Post Meta, после сохранения данных пользователя вызывается хук carbon_after_save_user_meta, который позволяет производить любые операции после того как данные были сохранены. В вызываемую функцию передается переменная $user_id, содержащая ID пользователя.

Comment Meta (комментарии)

Контейнер Comment Meta позволяет добавлять метаданные на странице редактирования комментария. Данные для каждого комментария сохраняются в таблицу wp_commentmeta см. add_comment_meta.

Пример создания метаполей комментария

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'comment_meta', 'Comment Information' )
	->add_fields(array(
		Field::make('text', 'crb_comment_rating', 'Comment Rating'),
		Field::make('text', 'crb_comment_additional_info', 'Additional Comment Information'),
	));

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

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

Вывод значений полей

Для получения значений полей контейнера используется функция:

carbon_get_comment_meta( $comment_id, $name, $type = null )
$comment_id(число) (обязательный)
ID комментария.
$name(строка) (обязательный)
Название произвольного поля, значение которого нужно получить.
$type(строка)
Если нужно получить значение сложного поля (содержит в себе массив данных), то укажите complex.

Пример

$comments = get_comments(array(
	'post_id' => get_the_ID(),
));

foreach ( $comments as $comment ) {
	$comment_additional_info = carbon_get_comment_meta($comment->comment_ID, 'crb_comment_additional_info');
	$comment_rating = carbon_get_comment_meta($comment->comment_ID, 'crb_comment_rating');

	if ( !empty($comment_additional_info) ) {
		echo $comment->comment_ID . ' info: '. $comment_additional_info;
	}

	if ( !empty($comment_rating) ) {
		echo 'Rating: ' . $comment_rating;
	}
}

Widgets (виджеты)

Контейнеры для виджетов используются для создания своих виджетов с настройками. Каждый виджет определяется как PHP класс. Пользовательский класс виджета должен расширять класс Widget и реализовать методы __construct() и front_end().

В конструкторе класса должен быть вызван метод

setup( $name, $description, $fields, $classname )
$name(строка) (обязательный)
Имя виджета, отображаемое в админке.
$description(строка) (обязательный)
Описание виджета, отображаемое в админке.
$fields(массив) (обязательный)
Массив полей.
$classname(строка)
Укажите атрибут собственного класса для виджета.

Создание контейнера для виджета

<?php
use Carbon_Fields\Widget;
use Carbon_Fields\Field;

class AboutMeWidget extends Widget {

	// Создание контейнера (виджета) и полей
	function __construct() {
		$this->setup(
			'Обо мне',
			'Расскажите о себе, добавив заголовок, фотографию и любой контент',
			array(
				Field::make( 'text', 'title', 'Заголовок' ),
				Field::make( 'image', 'photo', 'Фото' ),
				Field::make( 'rich_text', 'content', 'Контент' )
			),
			'my-css-class-for-widget' );

		$this->print_wrappers = false;
	}

	// Отображение информации во фронт-энде
	function front_end( $args, $instance ) {

		if ( ! empty( $instance['title'] ) ) {
			echo $args['before_title'] . $instance['title'] . $args['after_title'];
		}

		if ( ! empty( $instance['photo'] ) ) {
			$photo_url = wp_get_attachment_image_url( $instance['photo'], 'full' );
			echo "<img class='post-thumbnail' src='$photo_url' alt='' />";
		}

		if ( ! empty( $instance['content'] ) ) {
			echo wpautop( $instance['content'] );
		}

	}
}

// Сообщаем о нашем виджете движку
add_action( 'widgets_init', 'load_widgets' );
function load_widgets() {
	register_widget( 'AboutMeWidget' );
}

Метод front_end( $args, $instance ) отвечает за HTML код виджета во внешней части сайта. Здесь у вас есть доступ ко всем значениям виджета, определенных в конструкторе через экземпляр класса $instance.

После определения класса важно зарегистрировать новый виджет во время хука widgets_init. Код класса и вызов хука можно вставить в файл functions.php.

Параметры виджета

Параметры виджета (например, ширину) можно настроить, добавив определение $form_options в начале класса виджета. Пример:

protected $form_options = array(
	'width' => 500
);

Теперь виджет при разворачивании будет занимать 500px по ширине, а не ширину панели виджетов.

Если нужно отключить оболочку виджета по умолчанию, которые идут в боковой панели, в свойстве $this->print_wrappers нужно указать false. Делается это в методе __construct(). Пример:

function __construct() {
	$this->setup('Widget Title', __('Widget Description'), array(
		Field::make('text', 'title', 'Title')->set_default_value('Hello World!'),
	));

	$this->print_wrappers = false;
}

Создание виджетов в Carbon Fields очень похоже на стандартное создание виджетов в WordPress. см. register_widget()

Nav Menu (меню)

Контейнеры меню используются для расширения экранов редактирования меню дополнительными полями. Произвольные поля хранятся отдельно как для постов в таблице wp_postmeta.

Контейнеры меню не поддерживают следующий функционал:

  • Сложные (комплексные) произвольные поля.
  • Параметры видимости: все контейнеры видны во всех пунктах меню.
  • Позиционирование: контейнеры выводятся в порядке их инициализации.
use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make('nav_menu', 'Мои настройки меню')
		 ->add_fields(array(
			 Field::make('color', 'color', 'Цвет'),
		 ));

Вывод значений

Значения каждого пункта меню могут быть получены с помощью уже известной нам функции:

carbon_get_post_meta( $nav_menu_item_ID, $name )
$nav_menu_item_ID(строка) (обязательный)
ID пункта меню.
$name(строка) (обязательный)
Имя поля.

Напомню, что каждый пункт меню является записью типа nav_menu_item со статусом publish (опубликовано). Поэтому дополнительные данные пункта меню хранятся в произвольных полях.

Произвольный Walkers или Walker Filters

Чтобы использовать значения из Меню, нужно использовать пользовательский Walker или фильтр по умолчанию, расположенный по адресу wp-includes/nav-menu-template.php.

Пример Walkers

/**
 * Location:
 *  wp-includes/nav-menu-template.php
 *  source: Walker_Nav_Menu
 */
class Crb_Main_Menu_Walker extends Walker_Nav_Menu {
	public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
		if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
			$t = '';
			$n = '';
		} else {
			$t = "\t";
			$n = "\n";
		}
		$indent = ( $depth ) ? str_repeat( $t, $depth ) : '';

		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
		$classes[] = 'menu-item-' . $item->ID;

		$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );

		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
		$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

		$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth );
		$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

		$output .= $indent . '<li' . $id . $class_names .'>';

		$atts = array();
		$atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
		$atts['target'] = ! empty( $item->target )     ? $item->target     : '';
		$atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
		$atts['href']   = ! empty( $item->url )        ? $item->url        : '';

		// Добавить пользовательский цвет ссылкам
		$crb_color = carbon_get_post_meta($item->ID, 'color');
		$atts['style'] = ! empty( $crb_color ) ? 'color: ' . $crb_color . '; ' : '';
		// --- END ---

		$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );

		$attributes = '';
		foreach ( $atts as $attr => $value ) {
			if ( ! empty( $value ) ) {
				$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
				$attributes .= ' ' . $attr . '="' . $value . '"';
			}
		}

		$title = apply_filters( 'the_title', $item->title, $item->ID );
		$title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );

		$item_output = $args->before;
		$item_output .= '<a'. $attributes .'>';
		$item_output .= $args->link_before . $title . $args->link_after;
		$item_output .= '</a>';
		$item_output .= $args->after;

		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
	}

} // Walker_Nav_Menu

Пример фильтра, делающий то же самое

// Добавить пользовательский цвет ссылкам
add_filter('nav_menu_link_attributes', 'crb_nav_menu_link_attributes', 10, 4);
function crb_nav_menu_link_attributes($atts, $item, $args, $depth) {
	$crb_color = carbon_get_post_meta($item->ID, 'color');
	$atts['style'] = ! empty( $crb_color ) ? 'color: ' . $crb_color . '; ' : '';

	return $atts;
}

Оба приведенных выше примера сформируют следующий html-код:

<div class="menu-main-menu-container">
	<ul id="menu-main-menu" class="menu">
		<li id="menu-item-23" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23">
			<a href="#" style="color: #2020f3; ">Sample Page</a>
		</li>
		<li id="menu-item-24" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-24">
			<a href="#" style="color: #f94c4c; ">Sample Page</a>
		</li>
		<li id="menu-item-26" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-26">
			<a href="#" style="color: #81d742; ">Sample Page</a>
		</li>
	</ul>
</div>

Tabs (вкладки)

Carbon Fields позволяет с помощью метода add_tab() распределять произвольные поля по вкладкам.

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make('post_meta', 'Настройки записи')
		 ->show_on_post_type( 'page' )
		 ->add_tab('Любимые вещи автора статьи', array(
			 Field::make('text', '_crb_first_name', 'Фраза'),
			 Field::make('image', '_crb_last_name', 'Картина'),
			 Field::make('file', '_crb_position', 'Песня'),
		 ))
		 ->add_tab('Извещения', array(
			 Field::make('text', '_crb_email', 'Электронная почта'),
			 Field::make('text', '_crb_phone', 'Номер телефона'),
		 ));
campusboy 2728youtube.com/c/wpplus
Активный пользователь wp-kama.ru. WordPress-разработчик. Разработка сайтов и лендингов. Доработка существующих проектов. Сопровождение ресурсов.
Редакторы: Kama 5192
Carbon Fields 1.6 — контейнеры 73 коммента
Полезные 1 Вопросы 2 Все
  • Проманалась я с виджетом и отказалась от него. Слишом сложно для меня. Пошла другим путём. Поставила виджет с php, запихала туду код, но и он не работает как надо. Чё-т я совсем тупка. Вот код:

    <?php
    $myposts = new WP_Query( array('tax_query' => 
    array(array('taxonomy' => 'post_format', 'field' => 
    'slug', 'terms' => 'post-format-aside', 'category_name' => 'theatre'))) );
    if ( $myposts->have_posts() ) { while ( $myposts->have_posts() ) { $myposts->the_post(); ?>
    <a href="<?php the_permalink(); ?>" class="title fa fa-slideshare"><?php the_title(); ?></a>
    <?php
    $events = carbon_get_post_meta( $post->ID, 'event_options' );
    foreach ( $events as $event ) {?>
    <div class="date fa fa-calendar-alt"><?php echo $event['event_date'];?> <?php echo $event['event_time'];?></div>
    <?php $address = $event['event_adress'];
    foreach ( $address as $adres ) { ?>
    <a href="" data-toggle="modal" data-target="#modalAdress
    <?php echo $adres['id']?>" class="adress fa fa-map-marker-alt" title="Адрес проведения спектакля «
    <?php echo get_the_title($event['id']); ?>
    »"><?php echo get_the_title($adres['id']); ?></a>
    <?php }}}} wp_reset_postdata();?>

    И В футер положила код модального окна.

    <?php
    $places = carbon_get_post_meta( $post->ID, 'event_options' );
    if ( $places ) {
    foreach ( $places as $place ) {
    $address = $place['event_adress'];
    foreach ( $address as $item ) {
    ?>
    <div class="modal fade adress" id="modalAdress<
    ?php echo $item['id']?>
    " tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
    <div class="modal-header text-center">
    <h4 class="modal-title w-100 font-bold"><?php echo get_the_title($item['id']); ?></h4>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">x</span></button>
    </div>
    <div class="modal-body mx-3">
    <?php echo carbon_get_post_meta($item['id'], 'venue_adress');?>
    <br/><br/>
    <iframe src="https://www.google.com/maps/embed?pb=
    <?php echo carbon_get_post_meta($item['id'], 'venue_location');
    ?>" width="100%" height="80%" frameborder="0" style="border:0" allowfullscreen></iframe>
    </div>
    <div class="modal-footer d-flex justify-content-center">
    <button class="btn btn-block" data-dismiss="modal" aria-label="Close">
    Закрыть</button></div>
    </div>
    </div>
    </div>
    <?php }}}?>

    Постоянно выводятся все штатные данные из записей: id, ссылка, заголовок, краткий текст. А данные из CF полей выводятся только на страницах целевых записей. Во всех остальных адресах эти данные пропадают. А мне край нужен этот виджет. Помогите, пожалуйста!

    Ответить2 месяца назад #
    • campusboy2728 cайт: www.youtube.com/c/wpplus

      Я слабо представляю, что Вы там делаете, но по фразе:

      А данные из CF полей выводятся только на страницах целевых записей. Во всех остальных адресах эти данные пропадают

      Могу предположить, что вы получаете их, передавая динамический ID. Вот на записях, где поля есть эти - они выводятся. Может тогда стоит жёстко передать ID записи, где хранятся нужные данные?

      2
      Ответить2 месяца назад #
      • Огромное спасибо! Вы мне опять помогли. ) Действительно, стоило лишь определить id записи и подставить его в вывод CF, как всё заработало. Ещё раз спасибо!

        UPD Не. Не получается. Поломалось в другом месте.

        Ответить2 месяца назад #
  • И снова проблема с кириллицей. Причём, внезапно. Работало, работало и вдруг отвалилось. Код нового раздела в админке. Вы мне давали уже правильный, огромное спасибо. Но ВП опять капризничает. Вот такая ошибка Fatal error: Call to a member function add_tab() on a non-object in 'путь до темы'\inc\fields.php on line 10
    Код прежний:

    add_action( 'carbon_fields_register_fields', 'cg_theme_options' );
    function cg_theme_options() 
    {Container::make( 'theme_options', 'Пульт' )
    		 ->add_tab( 'Контакты', array(
    			 Field::make( 'text', 'cg_tw', 'Твиттер' ),
    		 ) )
    		 ->add_tab( 'Подключения', array(
    			 Field::make( 'textarea', 'vk_group', 'VK Группа' ),
    		 ) )
    		 ->add_tab( 'СЕО', array(
    			 Field::make( 'header_scripts', 'header_google_analytics', 'Код счётчика Гугл.Аналитикс' ),
    		 ) );
    }

    Все остальные кастомные поля с кириллицей в названиях полей работают без проблем.

    Ответить2 месяца назад #
    • campusboy2728 cайт: www.youtube.com/c/wpplus

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

      Container::make( 'theme_options', 'Пульт' )

      лучше

      Container::make( 'theme_options', 'pult', 'Пульт' )
      2
      Ответить2 месяца назад #
  • По координатам хочу определить страну. Здесь есть пример. Думал через скрытое поле (пустое), а потом через "// Делаем свои дела" изменить на нужное или есть что попроще?
    Только вот тоже: есть ли возможность сделать текстовое(например) поле скрытым? Или пускай человек пишет в поле что хочет, а исправит скрипт?
    Спасибо.

    Ответить2 месяца назад #
  • Bosssaite

    здравствуйте

    как правильно добавить дополнительную строку
    а именно Field::make('text', 'night-meals', 'Год рождения на документе?')

    		Field::make('select', 'set_tovar', 'Категория Пропажи')
    			->set_options(array('0' => 'Выберите тип Пропажи'))
    		->set_required(true)
    			->add_options(array(
    				'documentudl' => 'Документы, удостоверяющие личность',
    				'no' => 'Автодокументы',
    				'0' => 'Выберите тип Пропажи',
    			)),
    
    			 Field::make('text', 'night-meals', 'ФИО на документе?')
    
    			 Field::make('text', 'night-meals', 'Год рождения на документе?')
    				  ->set_conditional_logic(array(
    					  'relation' => 'AND',
    					  array(
    						  'field' => 'set_tovar',
    						  'value' => 'documentudl',
    					  )
    				  )),
    
    			 Field::make('text', 'night-meals-not', 'Почему?')
    				  ->set_conditional_logic(array(
    					  'relation' => 'AND',
    					  array(
    						  'field' => 'set_tovar',
    						  'value' => 'no',
    					  )
    				  )),
    Ответить7 дней назад #

Здравствуйте, !

Ваш комментарий
Предпросмотр