WordPress как на ладони

Комплексные поля

Carbon Fields 1.6

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

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

Создание комплексного поля для статьи

Создание поля

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

Container::make( 'post_meta', 'Заметки автора статьи' )
		 ->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type=page)
		 ->add_fields( array(
						Field::make( 'complex', 'fio', 'Соавторы статьи' )
							->add_fields( array(
								Field::make( 'text', 'name', 'ФИО' )
									 ->set_width( 33 ),
								Field::make( 'text', 'spec', 'Специальность' )
									 ->set_width( 33 ),
							 )
							)
							->help_text( 'Перечислите всех, кто помогал Вам написать статью.' )
				) );

Соответственно, в комплексном поле можно использовать любое поле из списка доступных полей Carbon Fields.

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

Если использовать carbon_get_post_meta() таким образом:

$data = carbon_get_post_meta( $post->ID, 'fio', 'complex' );
print_r( $data );

/*
Array (
	[0] => Array
		(
			[_type] => _
			[name] => Василий Пупкин
			[spec] => Айтишник
		)

	[1] => Array
		(
			[_type] => _
			[name] => Елена Бессмертная
			[spec] => Дизайнер
		)

	[2] => Array
		(
			[_type] => _
			[name] => Иван Бровин
			[spec] => Программист
		)

)

На основе структуры данных пишем код вывода значений:

<?php

$table = carbon_get_post_meta( $post->ID, 'fio', 'complex' );

if ( ! empty( $table ) ): ?>

	<table>
		<thead>
			<tr>
				<th>ФИО</th>
				<th>Специальность</th>
			</tr>
		</thead>
		<tbody>
			<?php foreach ( $table as $tr ): ?>
			  <tr>
				  <td><?php echo $tr['name'] ?></td>
				  <td><?php echo $tr['spec'] ?></td>
			  </tr>
			<?php endforeach; ?>
		</tbody>
	</table>

<?php endif; ?>

Получаем html код на выходе:

<table>
  <thead>
	<tr>
	  <th>ФИО</th>
	  <th>Специальность</th>
	</tr>
  </thead>
  <tbody>
	<tr>
	  <td>Василий Пупкин</td>
	  <td>Айтишник</td>
	</tr>
	<tr>
	  <td>Елена Бессмертная</td>
	  <td>Дизайнер</td>
	</tr>
	<tr>
	  <td>Иван Бровин</td>
	  <td>Программист</td>
	</tr>
  </tbody>
</table>

Single Group (одиночное комплексное поле)

Пример такого поля был приведен выше. Для добавления комплексного поля используется метод

Field::make()->add_fields( $fields )
$fields
Массив с произвольными полями. Добавленные строки, состоящие из полей, можно сортировать, перетаскивая мышкой, а также дублировать или удалять. Данное поле ещё называют repeater (повторитель).

Пример

Field::make('complex', 'crb_test')
	->add_fields(array(
		Field::make('text', 'name', 'Имя'),
		Field::make('text', 'job_title', 'Работа'),
	))

Multiple groups (множественное комплексное поле)

Это поле позволяет пользователю из выпадающего списка выбрать то или иное одиночное комплексное поле, тем самым пользователь сам решает, в каком виде должен преподноситься контент. Данное поле ещё называют flexible content (гибкое содержимое).

Параметры

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

Field::make()->add_fields( $name, $label, $fields )
$name(строка) (обязательный)
Название комплексного поля (слоя). Используйте только буквы английского алфавита!
$label(строка)
Заголовок комплексного поля (слоя). Разрешается использования любых символов.
По умолчанию: $name
$fields(массив) (обязательный)
Нумерованный массив полей

Принцип создания множественного комплексного поле такой же, как и одиночного, только метод add_fields() вызывается несколько раз. Получается эдакая цепочка, где каждый вызываемый метод add_fields() создаёт новый вариант одиночного комплексного поля (слоя) для выбора.

Создание поля

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'post_meta', 'Предпочтения автора статьи' )
	->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type=page)
	->add_fields( array(
			Field::make('complex', 'sheet-preferences', 'Список')
				 ->add_fields('movie', 'Кино', array(
					 Field::make('text', 'name', 'Название фильма'),
					 Field::make('rich_text', 'description', 'Описание фильма')->set_width(70),
					 Field::make('image', 'poster', 'Постер')
						 ->set_width(30)
				 ))
				 ->add_fields('music', 'Музыка', array(
					 Field::make('text', 'name', 'Название трека')
						  ->set_width(70),
					 Field::make('file', 'music', 'Трек')
						  ->set_type('audio')
						  ->set_width(30)
				 ))
				 ->add_fields('poetry', 'Поэзия', array(
					 Field::make('text', 'writer', 'Писатель'),
					 Field::make('text', 'name', 'Название'),
					 Field::make('textarea', 'short-poem', 'Часть стихотворения'),
					 Field::make('text', 'url', 'Ссылка на полное стихотворение')
				 ))
		) );

Запрос в базу данных

Carbon Fields формирует следующий запрос для получения данных поля:

SELECT meta_key AS field_key, meta_value AS field_value
FROM wp_postmeta 
WHERE `meta_key` LIKE "_sheet-preferences_%"
AND `post_id`="1086"

На тестовом сайте с 22 000 строк в таблице *_postmeta такой запрос выполняется мгновенно (php7, HDD).

Хранение данных

Данные хранятся в таблице *_postmeta, причем каждое произвольное поле в отдельности:

Хранение данных множественного комплексного поля в БД

Рассмотрим вариант хранения данных поля, в котором мы выбрали "Музыка" и "Eddy - Need (Remix)".

_sheet-preferences_music-_name_0 - Eddy - Need (Remix)
  • _sheet-preferences - имя множественного комплексного поля. Как уже говорилось, Carbon Fields автоматически добавляет знак подчеркивания при сохранении имени большинства полей.
  • _music - имя одиночного комплексного поля (слоя)
  • Дефис - разделитель, отделяющий цепочку "контейнеров и слоев" от имени самого поля
  • _name - имя поля (в нашем случае поле "name" для ввода название песни)
  • _0 - позиция слоя в списке выбранных слоев. Как и в нумерованных массивах, 0 - это первый элемент.

Как видим, цепочка идёт от общего к частному. Получить данные можно с помощью функции carbon_get_post_meta() или другой, в зависимости от места использования множественного поля (посты, таксономии, настройки темы и т.д.) - все эти функции описаны в статье о контейнерах Carbon Fields.

$data_arr = carbon_get_post_meta( $post->ID, 'sheet-preferences', 'complex' );
print_r( $data_arr );

/*
Array (
	[0] => Array
		(
			[_type] => _music
			[music] => 976
			[name] => Eddy - Need (Remix)
		)

	[1] => Array
		(
			[_type] => _movie
			[description] => Рокки отошел от дел, занявшись ресторанным бизнесом и все еще тяжело переживает смерть своей жены Эдриан. Пытаясь развеять образовавшуюся пустоту, Бальбоа решает вернуться на ринг для боев местного значения с боксерами в легком весе. Но когда он соглашается выступить против действующего чемпиона-тяжеловеса Мэйсона Диксона, пресса неожиданно проявляет к возвращению Рокки пристальный интерес.
			[name] => Рокки Бальбоа
			[poster] => 9670
		)

	[2] => Array
		(
			[_type] => _poetry
			[url] => http://www.askbooka.ru/stihi/aleksandr-pushkin/ya-vas-lyubil-lyubov-eshchyo-byt-mozhet.html
			[name] => Я вас любил: любовь ещё, быть может...
			[short-poem] => Я вас любил: любовь ещё, быть может,
В душе моей угасла не совсем;
Но пусть она вас больше не тревожит;
Я не хочу печалить вас ничем.
			[writer] => Александр Пушкин
		)

	[3] => Array
		(
			[_type] => _poetry
			[url] => http://www.askbooka.ru/stihi/aleksandr-pushkin/pismo-tatyany-k-oneginu.html
			[name] => Письмо Татьяны к Онегину
			[short-poem] => Я к вам пишу - чего же боле?
Что я могу ещё сказать?
Теперь, я знаю, в вашей воле
Меня презреньем наказать.
			[writer] => Александр Пушкин
		)
)
*/

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

Теперь остается перебрать данный массив, а благодаря ключу _type решить, какой слой какой внешний вид будет иметь. Выводится значения полей будут в том порядке, какой вы определили в админке.

<?php
// Получаем данные
$data_arr = carbon_get_post_meta( $post->ID, 'sheet-preferences', 'complex' );

// Проверяем их наличие
if ( ! empty( $data_arr ) ): ?>

	<div class="box-list">

		<?php foreach ( $data_arr as $cnt => $item ): ?>

			<div class="box-item box-<?php echo $cnt + 1; ?> box<?php echo $item['_type']; ?>">

				<?php if ( $item['_type'] == '_movie' ): ?>

					<div class="poster">
						<?php
						// Выводим миниатюру средних размеров, передав ID файла (вложения)
						echo wp_get_attachment_image( $item['poster'], 'medium');
						?>
					</div>

					<div class="content">

						<div class="name">
							<h2><?php echo $item['name']; ?></h2>
						</div>

						<div class="description">
							<?php echo $item['description']; ?>
						</div>

					</div>

				<?php endif; ?>

				<?php if ( $item['_type'] == '_music' ):

					// Выводим аудиоплеер WordPress, передав ID файла (песни)
					echo wp_playlist_shortcode( [ 'ids'   => $item['music'] ] );

				endif; ?>

				<?php if ( $item['_type'] == '_poetry' ): ?>

					<div class="name">

						<h2><?php echo $item['name']; ?></h2>

						<div class="writer"><?php echo $item['writer']; ?></div>

						<q class="short-poem"><?php echo $item['name']; ?></q>

						<a href="<?php echo $item['url']; ?>">Читать произведение полностью</a>

					</div>

				<?php endif; ?>

			</div>

		<?php endforeach; ?>

	</div>

<?php endif; ?>

Сгенерированный html код:

<div class="box-list">
  <div class="box-item box-1 box_music">
	<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->
	<div class="wp-playlist wp-audio-playlist wp-playlist-light">
	  <div class="wp-playlist-current-item"></div>
	  <audio controls="controls" preload="none" width="618"></audio>
	  <div class="wp-playlist-next"></div>
	  <div class="wp-playlist-prev"></div>
	  <noscript>
		<ol>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/Eddy-Need-Remix.mp3'>Eddy - Need (Remix)</a></li>
		</ol>
	  </noscript>
	  <script type="application/json" class="wp-playlist-script">{"type":"audio","tracklist":true,"tracknumbers":true,"images":true,"artists":true,"tracks":[{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/Eddy-Need-Remix.mp3","type":"audio\/mpeg","title":"Eddy - Need (Remix)","caption":"","description":"","meta":{"artist":"Eddy","album":"Remix","genre":"Dance","year":"2011","length_formatted":"4:34"},"image":{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2017\/04\/Eddy-Need-Remix-mp3-image.jpg","width":555,"height":550},"thumb":{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2017\/04\/Eddy-Need-Remix-mp3-image-150x150.jpg","width":150,"height":150}}]}</script>
	</div>
  </div>
  <div class="box-item box-2 box_movie">
	<div class="poster">
	  <img width="211" height="300" src="http://wp-test.ru/wp-content/uploads/2013/03/Rokii-Balboa-211x300.jpg" class="attachment-medium size-medium" alt="" srcset="http://wp-test.ru/wp-content/uploads/2013/03/Rokii-Balboa-211x300.jpg 211w, http://wp-test.ru/wp-content/uploads/2013/03/Rokii-Balboa.jpg 703w" sizes="(max-width: 211px) 100vw, 211px" />                    
	</div>
	<div class="content">
	  <div class="name">
		<h2>Рокки Бальбоа</h2>
	  </div>
	  <div class="description">
		Рокки отошел от дел, занявшись ресторанным бизнесом и все еще тяжело переживает смерть своей жены Эдриан. Пытаясь развеять образовавшуюся пустоту, Бальбоа решает вернуться на ринг для боев местного значения с боксерами в легком весе. Но когда он соглашается выступить против действующего чемпиона-тяжеловеса Мэйсона Диксона, пресса неожиданно проявляет к возвращению Рокки пристальный интерес.                        
	  </div>
	</div>
  </div>
  <div class="box-item box-3 box_poetry">
	<div class="name">
	  <h2>Я вас любил: любовь ещё, быть может...</h2>
	  <div class="writer">Александр Пушкин</div>
	  <q class="short-poem">Я вас любил: любовь ещё, быть может...</q>
	  <a href="http://www.askbooka.ru/stihi/aleksandr-pushkin/ya-vas-lyubil-lyubov-eshchyo-byt-mozhet.html">Читать произведение полностью</a>
	</div>
  </div>
  <div class="box-item box-4 box_poetry">
	<div class="name">
	  <h2>Письмо татьяны к онегину</h2>
	  <div class="writer">Александр Пушкин</div>
	  <q class="short-poem">Письмо татьяны к онегину</q>
	  <a href="http://www.askbooka.ru/stihi/aleksandr-pushkin/pismo-tatyany-k-oneginu.html">Читать произведение полностью</a>
	</div>
  </div>
</div>

Nested Complex Fields (Вложенные комплексные поля)

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

Когда это может пригодится? Вернемся к примеру выше, где мы дали возможность автору статьи добавлять комплексное поле "Музыка". В нем он указывал название песни и прикреплял аудиофайл из медиабиблиотеки. А что если пользователь захочет указать альбом и прикрепить к нему несколько музыкальных произведений? Ему придется несколько раз выбирать слой "Музыка", причем название альбома ему некуда вписать. Затем во фронт-энде с помощью функции wp_playlist_shortcode() мы отображали аудиоплеер с выбранной песней. А если слоев с музыкой будет много? Будет куча аудиоплееров на странице, у которых в плейлисте по 1 песне.

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

Отображение вложенного комплексного поля

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

Рассмотрим вариант, когда пользователь можно выбрать - добавить одну песню или альбом.

  1. Создадим множественное комплексное поле, которое будет иметь ещё 2 комплексных поля (слоя).

  2. Первое комплексное поле будет одиночным и содержать два поля: название песни и аудиофайл.

  3. Второе поле будет множественным и содержать 3 поля: 1 - текстовое поле для названия альбома, 2 - поле для изображения альбома, 3 - одиночное комплексное поле, состоящее из повторяющегося поля для загрузки файла.

Схема

Пример схемы вложенного комплексного поля

Создание поля

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'post_meta', 'Предпочтения автора статьи' )
	->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type = page)
	->add_fields( array(
		Field::make( 'complex', 'sheet-preferences', 'Какой музыкой Вы вдохновлялись при написании статьи?' )
			 ->add_fields( 'single_song', 'Одна песня', array(
				 Field::make( 'text', 'name-song', 'Название песни' )
					  ->set_width( 70 ),
				 Field::make( 'file', 'file-song', 'Файл' )
					  ->set_type( 'audio' )
					  ->set_width( 30 )
			 ) )
			 ->add_fields( 'music_albums', 'Музыкальный альбом', array(
				 Field::make( 'image', 'cover', 'Обложка альбома' )
					  ->set_width( 30 ),
				 Field::make( 'text', 'name-album', 'Название альбома' )
					  ->set_width( 70 ),
				 Field::make( 'complex', 'list_songs', 'Список песен' )
					  ->add_fields('item_song','Песня', array(
						  Field::make( 'file', 'file-song', 'Файл' )
							   ->set_type( 'audio' )
					  ) )
			 ) )
	) );

Хранение данных

Правильное хранение данных вложенного комплексного поля в БД

// Получаем данные
$data_arr = carbon_get_post_meta( $post->ID, 'sheet-preferences', 'complex' );
print_r( $data_arr );

// Выведет
Array
(
	[0] => Array
		(
			[_type] => _single_song
			[file-song] => 976
			[name-song] => Eddy - Need (Remix)
		)

	[1] => Array
		(
			[_type] => _single_song
			[file-song] => 9675
			[name-song] => Heavy Love - Andrew Rayel Ft Kye Sones
		)

	[2] => Array
		(
			[_type] => _music_albums
			[cover] => 9688
			[list_songs] => Array
				(
					[0] => Array
						(
							[_type] => _item_song
							[file-song] => 9673
						)

					[1] => Array
						(
							[_type] => _item_song
							[file-song] => 9677
						)

					[2] => Array
						(
							[_type] => _item_song
							[file-song] => 9681
						)

					[3] => Array
						(
							[_type] => _item_song
							[file-song] => 9680
						)

					[4] => Array
						(
							[_type] => _item_song
							[file-song] => 9676
						)

					[5] => Array
						(
							[_type] => _item_song
							[file-song] => 9672
						)

				)

			[name-album] => Andrew Rayel - Moments
		)

)

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

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

Пример вывода значений вложенного комплексного поля на основе аудиозаписей

Тогда код в шаблоне будет такой:

<?php
// Получаем данные
$data_arr = carbon_get_post_meta( $post->ID, 'sheet-preferences', 'complex' );

// Проверяем их наличие
if ( ! empty( $data_arr ) ): ?>

	<div class="box-list">

		<h2>Музыка, которой вдохновлялся автор при написании статьи</h2>

		<?php foreach ( $data_arr as $cnt => $item ): ?>

			<div class="box-item box-<?php echo $cnt + 1; ?> box<?php echo $item['_type']; ?>">

				<?php if ( $item['_type'] == '_single_song' ): ?>

					<h3><?php echo $item['name-song']; ?> <sup><i>песня</i></sup></h3>

					<div class="single-player">
						<?php
						// Выводим аудиоплеер WordPress, передав ID файла (песни)
						echo wp_playlist_shortcode( [ 'ids'   => $item['file-song'], 'tracklist' => false ] );
						?>
					</div>

				<?php endif; ?>

				<?php if ( $item['_type'] == '_music_albums' ): ?>

					<h3><?php echo $item['name-album']; ?> <sup><i>альбом</i></sup></h3>

					<?php
					// Создаем массив с ID аудиофайлов
					$songs_id = [];
					foreach ($item['list_songs'] as $song){
						$songs_id[] = $song['file-song'];
					}

					// Выводим аудиоплеер WordPress, передав ID файлов (песен)
					echo wp_playlist_shortcode( [ 'ids'   => $songs_id ] );
					?>

				<?php endif; ?>

			</div>

		<?php endforeach; ?>

	</div>

<?php endif; ?>

А полученный html будет выглядеть так:

<div class="box-list">
  <h2>Музыка, которой вдохновлялся автор при написании статьи</h2>
  <div class="box-item box-1 box_single_song">
	<h3>Eddy - Need (Remix) <sup><i>песня</i></sup></h3>
	<div class="single-player">
	  <!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->
	  <div class="wp-playlist wp-audio-playlist wp-playlist-light">
		<div class="wp-playlist-current-item"></div>
		<audio controls="controls" preload="none" width="618"></audio>
		<div class="wp-playlist-next"></div>
		<div class="wp-playlist-prev"></div>
		<noscript>
		  <ol>
			<li><a href='http://wp-test.ru/wp-content/uploads/2013/03/Eddy-Need-Remix.mp3'>Eddy - Need (Remix)</a></li>
		  </ol>
		</noscript>
		<script type="application/json" class="wp-playlist-script">{"type":"audio","tracklist":false,"tracknumbers":true,"images":true,"artists":true,"tracks":[{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/Eddy-Need-Remix.mp3","type":"audio\/mpeg","title":"Eddy - Need (Remix)","caption":"","description":"","meta":{"artist":"Eddy","album":"Remix","genre":"Dance","year":"2011","length_formatted":"4:34"},"image":{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2017\/04\/Eddy-Need-Remix-mp3-image.jpg","width":555,"height":550},"thumb":{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2017\/04\/Eddy-Need-Remix-mp3-image-150x150.jpg","width":150,"height":150}}]}</script>
	  </div>
	</div>
  </div>
  <div class="box-item box-2 box_single_song">
	<h3>Heavy Love - Andrew Rayel Ft Kye Sones <sup><i>песня</i></sup></h3>
	<div class="single-player">
	  <div class="wp-playlist wp-audio-playlist wp-playlist-light">
		<div class="wp-playlist-current-item"></div>
		<audio controls="controls" preload="none" width="618"></audio>
		<div class="wp-playlist-next"></div>
		<div class="wp-playlist-prev"></div>
		<noscript>
		  <ol>
			<li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_heavy_love_with_max_vangeli_feat._kye_sones.mp3'>Heavy Love</a></li>
		  </ol>
		</noscript>
		<script type="application/json" class="wp-playlist-script">{"type":"audio","tracklist":false,"tracknumbers":true,"images":true,"artists":true,"tracks":[{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_heavy_love_with_max_vangeli_feat._kye_sones.mp3","type":"audio\/mpeg","title":"Heavy Love","caption":"","description":"\u00abHeavy Love\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel Ft Kye Sones. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 8 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel Ft Kye Sones","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"4:46"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}}]}</script>
	  </div>
	</div>
  </div>
  <div class="box-item box-3 box_music_albums">
	<h3>Andrew Rayel - Moments <sup><i>альбом</i></sup></h3>
	<div class="wp-playlist wp-audio-playlist wp-playlist-light">
	  <div class="wp-playlist-current-item"></div>
	  <audio controls="controls" preload="none" width="618"></audio>
	  <div class="wp-playlist-next"></div>
	  <div class="wp-playlist-prev"></div>
	  <noscript>
		<ol>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_back_to_the_moment.mp3'>Back To The Moment</a></li>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_ill_be_there_feat._eric_lumiere.mp3'>I'll Be There</a></li>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_my_reflection_feat._emma_hewitt.mp3'>My Reflection</a></li>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_moments.mp3'>Moments</a></li>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_home_feat._jonathan_mendelson.mp3'>Home</a></li>
		  <li><a href='http://wp-test.ru/wp-content/uploads/2013/03/andrew_rayel_-_all_systems_down_feat._khomha.mp3'>All Systems Down</a></li>
		</ol>
	  </noscript>
	  <script type="application/json" class="wp-playlist-script">{"type":"audio","tracklist":true,"tracknumbers":true,"images":true,"artists":true,"tracks":[{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_back_to_the_moment.mp3","type":"audio\/mpeg","title":"Back To The Moment","caption":"","description":"\u00abBack To The Moment\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 12 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"3:54"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}},{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_ill_be_there_feat._eric_lumiere.mp3","type":"audio\/mpeg","title":"I'll Be There","caption":"","description":"\u00abI'll Be There\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel Ft Eric Lumiere. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 2 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel Ft Eric Lumiere","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"5:51"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}},{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_my_reflection_feat._emma_hewitt.mp3","type":"audio\/mpeg","title":"My Reflection","caption":"","description":"\u00abMy Reflection\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel Ft Emma Hewitt. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 6 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel Ft Emma Hewitt","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"4:47"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}},{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_moments.mp3","type":"audio\/mpeg","title":"Moments","caption":"","description":"\u00abMoments\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 1 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"3:21"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}},{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_home_feat._jonathan_mendelson.mp3","type":"audio\/mpeg","title":"Home","caption":"","description":"\u00abHome\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel Ft Jonathan Mendelsohn. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 9 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel Ft Jonathan Mendelsohn","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"4:08"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}},{"src":"http:\/\/wp-test.ru\/wp-content\/uploads\/2013\/03\/andrew_rayel_-_all_systems_down_feat._khomha.mp3","type":"audio\/mpeg","title":"All Systems Down","caption":"","description":"\u00abAll Systems Down\u00bb \u0438\u0437 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 \u00abMoments WEB\u00bb \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f Andrew Rayel. \u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: 2017. \u0422\u0440\u0435\u043a 3 \u0438\u0437 16. \u0416\u0430\u043d\u0440: Trance.","meta":{"artist":"Andrew Rayel","album":"Moments WEB","genre":"Trance","year":"2017","length_formatted":"4:36"},"image":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64},"thumb":{"src":"http:\/\/wp-test.ru\/wp-includes\/images\/media\/audio.png","width":48,"height":64}}]}</script>
	</div>
  </div>
</div>

Неправильное создание поля

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

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

Container::make( 'post_meta', 'Предпочтения автора статьи' )
		 ->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type = page)
		 ->add_fields( array(
						Field::make( 'complex', 'sheet-preferences', 'Какой музыкой Вы вдохновлялись при написании статьи?' )
							 ->add_fields( 'single-song', 'Одна песня', array(
								 Field::make( 'text', 'name-song', 'Название песни' )
									  ->set_width( 70 ),
								 Field::make( 'file', 'file-song', 'Файл' )
									  ->set_type( 'audio' )
									  ->set_width( 30 )
							 ) )
							 ->add_fields( 'music-albums', 'Музыкальный альбом', array(
								 Field::make( 'image', 'cover', 'Обложка альбома' )
									  ->set_width( 30 ),
								 Field::make( 'text', 'name-album', 'Название альбома' )
									  ->set_width( 70 ),
								 Field::make( 'complex', 'list-songs', 'Список песен' )
									  ->add_fields('item-song','Песня', array(
										  Field::make( 'file', 'file-song', 'Файл' )
											   ->set_type( 'audio' )
									  ) )
							 ) )
					) );

Хранение данных вложенного комплексного поля в БД в неправильном виде

Array
(
	[0] => Array
		(
			[_type] => _single
			[song-_file-song] => 976
			[song-_name-song] => Eddy - Need (Remix)
		)

	[1] => Array
		(
			[_type] => _single
			[song-_file-song] => 9675
			[song-_name-song] => Andrew Rayel Ft Kye Sones - Heavy Love
		)

	[2] => Array
		(
			[_type] => _music
			[albums-_cover] => 9688
			[albums-_list-songs] => Array
				(
					[0] => Array
						(
							[_type] => _item
							[song-_file-song] => 9681
						)

					[1] => Array
						(
							[_type] => _item
							[song-_file-song] => 9680
						)

					[2] => Array
						(
							[_type] => _item
							[song-_file-song] => 9676
						)

					[3] => Array
						(
							[_type] => _item
							[song-_file-song] => 9678
						)

					[4] => Array
						(
							[_type] => _item
							[song-_file-song] => 9673
						)

					[5] => Array
						(
							[_type] => _item
							[song-_file-song] => 9672
						)

				)

			[albums-_name-album] => Andrew Rayel - Moments
		)

)

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

Методы

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

add_fields( $fields )

Этот метод идентичен методу add_fields() у класса Container, где $fields - массив полей. То есть мы как бы в родительский контейнер помещаем дочерний контейнер с набором полей. Метод add_fields() можно вызывать по цепочки, тем самым увеличивать количество дочерних контейнеров.

set_layout( $layout )

Метод set_layout определяет макет контейнера, который имеет 3 вида:

  • grid (по умолчанию) - список комплексных полей в виде сетки. Каждое поле в группе отображается с новой строки и помечается. Такой вид макета комплексных полей в основном вы ведите в примерах.
  • tabbed-horizontal - Группы полей отображаются в виде горизонтальных вкладок
  • tabbed-vertical - Группы полей отображаются в виде вертикальных вкладок

set_min( $min )

Минимальное количество рядов. Должно быть больше 0. По умолчанию -1 (без ограничений). Метод set_min должен быть вызван после метода add_fields.

Доверять данному методу не стоит, если вы на этом ограничении строите логику своего web-приложения.

Если указать, к примеру, set_min(2), то первая группа полей сразу будет отображена. Если ничего не заполнить, то запись сохраняется без проблем. Если же заполнить первую группу полей и попробовать сохранить запись, то контейнер с полями будет обведен в красную рамку без каких-либо других намеков на то, что надо добавить вторую группу полей - это сбивает с толку пользователей, потому используйте метод help_text(), чтобы рассказать им о своих ограничениях. Если же заполнить первую группу полей, добавить вторую и ничего в ней не заполнить - запись беспрепятственно сохранится.

set_max( $max )

Максимальное количество рядов. Должно быть больше 0. По умолчанию -1 (без ограничений). Метод set_max должен быть вызван после метода add_fields().

setup_labels( $labels )

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

  • plural_name — заголовок для множественного числа. По умолчанию entries (элементы)
  • singular_name — заголовок для единственного числа. По умолчанию entry (элемент)

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

use Carbon_Fields\Container;
use Carbon_Fields\Field;

$assistants_labels = array(
	'plural_name'   => 'помощников',
	'singular_name' => 'помощника',
);

Container::make( 'post_meta', 'Дополнительные данные статьи' )
		 ->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type = page)
		 ->add_fields( array(
						Field::make( 'complex', 'assistants', 'Помощники' )
							 ->setup_labels( $assistants_labels )
							 ->help_text( 'Укажите всех, кто помогал Вам написать статью.' )
							 ->add_fields( array(
								 Field::make( 'text', 'name', 'Как зовут помощника?' )
									  ->help_text( 'Имя и Фамилия помощника или просто никнейм' ),
								 Field::make( 'textarea', 'contribution', 'Чем помог?' )
									  ->help_text( 'Какой вклад внес помощник?' ),
							 ) )
					) );

set_header_template( $template )

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

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

use Carbon_Fields\Container;
use Carbon_Fields\Field;

Container::make( 'post_meta', 'Дополнительные данные статьи' )
		 ->show_on_post_type( 'page' )// отобразим контейнер только на страницах (post_type = page)
		 ->add_fields( array(
						Field::make( 'complex', 'donate', 'Пожертвования' )
							 ->help_text( 'Укажите всех, кто материального помог во время написания статьи.' )
							 ->add_fields( array(
								 Field::make( 'text', 'name', 'Имя' ),
								 Field::make( 'text', 'money', 'Сколько пожертвовал?' ),
								 Field::make( "radio", "currency", "В какой валюте?" )
									  ->add_options( array(
										  'uah' => 'Гривны',
										  'usd' => 'Доллары',
										  'byn' => 'Белорусские рубли',
										  'rub' => 'Российские рубли',
									  ) )
							 ) )
							 ->set_header_template('
									<# if (name) { #>
										{{ name }} {{ money ? "пожертвовал " + money : "" }} {{ currency ? " " + currency : "" }}
									<# } #>
								 ')
					) );

Хранилище данных

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

Наглядный пример хранения данных комплексного поля приведен в примерах к множественному комплексному полю.

Чтобы иметь возможность отличать значение поля, используется специальный формат ключей: meta_key или option_name:

{complex_field_name}_{group_name}-{field_name}_{number}
  • complex_field_name - Имя комплексного поля, переданного в Field::make().

  • group_name - Имя группы передается add_fields() или "", если присутствует только одна группа.

  • field_name - Имя поля в группе, переданное в Field::make().

  • number - Определяет номер строки, для которой это значение является частью.

Имена комплексных полей и их подполей именуются, начиная со знака подчеркивания, потому реальный формат получаемого имени поля следующий:

_{complex_field_name}_{group_name}-_{field_name}_{number}
11 комментариев
    Войти