Расширяемость
Carbon Fields 1.6- Контейнеры
- Произвольные поля
- Комплексные поля
- Расширяемость
Функционал Carbon Fields легко расширяется, так как библиотека написана в стиле ООП. Можно наследовать классы контейнеров или полей, привнося в них свои идеи и решая более широкий круг задач, чем доступен из коробки.
На стороне клиента работает JavaScript библиотека Backbone. Использование Backbone обеспечило Carbon Fields прочной основой для создания масштабируемого приложения.
Чтобы лучше понять, как работает библиотека, предлагаем шаг за шагом создать новый тип поля. На github.com вы найдете заготовку такого поля, которую остается лишь отредактировать под себя.
Шаблоны - как изменить шаблон (вид) поля в Carbon Fields?
Данная библиотека активно использует шаблонизатор Underscore. В каждом классе произвольного поля есть метод template
, который использует шаблон Underscore
.
Примеры
Новое поле
use Carbon_Fields\Field; class Example_Field extends Field { // Основной шаблон function template() { ?> <input id="{{{ id }}}" type="text" name="{{{ name }}}" value="{{ value }}" class="regular-text" /> <span>Это пример поля. </span> <?php } }
Некоторые поля имеют более одного шаблона. В этих случаях дополнительные шаблоны должны быть добавлены отдельными методами и зарегистрированы через метод
add_template( $name, $callback )
use Carbon_Fields\Field; class Example_Field extends Field { function admin_init() { // Добавляем шаблон описания $this->add_template($this->get_type() . '-Description', array($this, 'template_description')); } ... // Шаблон описания function template_description() { ?> <div class="carbon-description {{{ value ? '' : 'hidden' }}}"> <p>Какая-нибудь подсказка для пользователя.</p> </div> <?php } }
Новый контейнер
При именовании страницы настроек темы кириллицей ссылка на неё не транслитерируется, что некоторым разработчикам не нравится. Чтобы это исправить, создадим новый контейнер, который будет наследовать существующий контейнер.
В папке с контейнерами /carbon-fields/core/Container/ создаем файл My_Theme_Options_Container.php:
<?php namespace Carbon_Fields\Container; class My_Theme_Options_Container extends Theme_Options_Container { protected function clear_string( $string ) { $string = sanitize_title ( $string ); return preg_replace( array( '~ +~', '~[^\w\d-]+~u', '~-+~' ), array( '-', '-', '-' ), strtolower( remove_accents( $string ) ) ); } }
В пользовательском файле пишем, например:
Container::make( 'my_theme_options', 'Мой пульт' ) ->add_fields( array( Field::make( 'text', 'crb_facebook_url' ), Field::make( 'textarea', 'crb_footer_text' ) ) );
И теперь вместо ссылки:
/wp-admin/admin.php?page=crbn-Мой-пульт.php
Которая, как известно, при отправке кому-то будет выглядеть так:
/wp-admin/admin.php?page=crbn-%D0%9C%D0%BE%D0%B9-%D0%BF%D1%83%D0%BB%D1%8C%D1%82.php
Станет такой (при условии работы плагинов транслитерации):
/wp-admin/admin.php?page=crbn-moj-pult.php
Синтаксис шаблонов
Выполнить произвольный код JavaScript.
<# ... #>
Вставить значение.
{{ ... }}
Вставить значение в виде очищенного HTML.
{{{ ... }}}
Переменные шаблона
Чтобы переменные были доступны в шаблоне, используется PHP метод to_json(). Вот пример добавления двух новых переменных (количество строк и высота поля):
// PHP класс поля Textarea class Textarea_Field extends Field { protected $height = 170; protected $rows = 0; ... function to_json($load) { $field_data = parent::to_json($load); $field_data = array_merge($field_data, array( 'rows' => $this->rows, 'height' => $this->height, )); return $field_data; } }
Переменные шаблона также могут быть добавлены с помощью JavaScript путем расширения объекта templateVariables
. Это следует сделать на событии field:beforeRender
. Пример:
// File Field Backbone View carbon.fields.View.File = carbon.fields.View.extend({ initialize: function() { carbon.fields.View.prototype.initialize.apply(this); this.on('field:beforeRender', this.loadDescriptionTemplate); }, ... /** * Loads the description template and sets it as a variable ("description") for the base template */ loadDescriptionTemplate: function() { var type = this.model.get('type'); var descTemplate = carbon.template(type + '-Description'); _.extend(this.templateVariables, { description: descTemplate(this.templateVariables) }); } });
Хуки в Carbon Fields
Это механизм, позволяющий включать собственные классы и функциональность в нужное время в нужном месте.
Если плавайте в теме хуков, советуем прочитать обучающую статьи о том, как работают хуки в WordPress.
Основные
(action) carbon_register_fields
Вызывается до регистрации полей.
(action) carbon_after_register_fields
Вызывается после того, как все поля зарегистрированы.
Шаблоны
(filter) carbon_template( $html, $name )
Применяется к шаблону html перед тем, как поместить его в футер админки.
(filter) carbon_template_{template-name}( $html )
Такой же, как carbon_template
, только можно указать имя шаблона.
Контейнер для опций темы
(filter) carbon_{container-title}_button_label( $label )
Позволяет изменить текст кнопки "Сохранить изменения" на произвольный.
Объявление фильтра в коде Carbon Fields:
$filter_name = 'carbon_' . str_replace( '-', '_', sanitize_title( $this->title ) ) . '_button_label'; $button_label = apply_filters( $filter_name, __( 'Save Changes', 'carbon-fields' ) );
Пример создания контейнера:
// Создаем страницу настроек темы Container::make( 'theme_options', 'My Options' ) ->add_fields(array( Field::make( 'text', 'facebook_url', 'Ссылка на Фейсбук' ), Field::make( 'textarea', 'footer_text', 'Текст в футере' ) ));
Пример изменения текста кнопки на основе примера выше:
// Изменяем текст кнопки "Сохранить изменения" add_filter( 'carbon_my_options_button_label', function( $label ){ return 'Сохранить мои настройки'; });
Данный метод может отработать не так, как ожидалось, если использовать кириллицу при указании имени контейнеру, к примеру:
// Создаем страницу настроек под названием "Опции" Container::make('theme_options', 'Опции') // В коде плагина посмотрим, какой $label формируется $filter_name = 'carbon_' . str_replace( '-', '_', sanitize_title( $this->title ) ) . '_button_label'; var_dump( $filter_name ); // Получим string(50) "carbon_%d0%be%d0%bf%d1%86%d0%b8%d0%b8_button_label" // Если использовать такие плагины Cyr to Lat и подобные, получим string(26) "carbon_optsii_button_label" // Изменяем текст кнопки "Сохранить изменения" на основе предыдущего примера add_filter('carbon_optsii_button_label', function($label){ return 'Сохранить мои настройки'; });
Универсальное решение проблемы - использовать такую же конструкцию, что и в самом плагине:
add_filter( 'carbon_' . str_replace( '-', '_', sanitize_title( 'Опции' ) ) . '_button_label', function($label){ return 'Сохранить мои настройки'; });
Поля для взаимоотношений и ассоциаций
(filter) carbon_relationship_title( $title, $name, $id, $type, $subtype )
Позволяет изменять заголовок элементов отношения / ассоциации. Полезно при реализации пользовательских отношений / связей. Принимает следующие параметры:
$title
- заголовок пункта$name
- имя поля$id
- ID поста, таксономии и т.д.$type
- основной тип объекта (post, term, user, comment и т.д)$subtype
- подтип, дополняющий основной (page, post, category и т.д)
// Сделаем текст пунктов курсивом add_filter( 'carbon_relationship_title', function($title){ return "<i>{$title}</i>"; }); // Сделаем текст пунктов курсивом только у относящихся к постам (записям, страницам и т.д.) add_filter('carbon_relationship_title', 'change_carbon_relationship_title', 10, 5); function change_carbon_relationship_title($title, $name, $id, $type, $subtype){ return ( $type == 'post' ) ? "<i>{$title}</i>" : $title; } // Сделаем текст пунктов курсивом и поменяем его цвет, в зависимости от принадлежности add_filter('carbon_relationship_title', 'change_carbon_relationship_title', 10, 5); function change_carbon_relationship_title($title, $name, $id, $type, $subtype){ $color = 'black'; // Записи if ( $subtype == 'post' ) $color = 'indigo'; // Страницы if ( $subtype == 'page' ) $color = 'green'; // Пользователи if ( $type == 'user' ) $color = 'orange'; // Комментарии if ( $type == 'comment' ) $color = 'red'; // Рубрики if ( $subtype == 'category' ) $color = 'blue'; return "<i style='color: {$color};'>{$title}</i>"; }
(filter) carbon_relationship_comment_length( $number, $name )
Заголовок элемента, относящийся к комментарию строится из части его текста. Данный хук позволяет изменить количество символов, видимых из текста комментария в элементе. Принимает следующие параметры:
- int
$number
- количество символов (по умолчанию 30) - string
$name
- Имя поля отношения / ассоциации.
Пусть у нас есть поле взаимоотношений под именем my_association и
// Меняем количество знаков у заголовка комментария function change_relationship_comment_length($number, $name){ return 20; } add_filter('carbon_relationship_comment_length', 'change_relationship_comment_length', 10, 2); /** * Меняем количество знаков у заголовка комментария только у поля ``my_association``. * * Не забывайте - плагин добавляет нижнее подчеркивание к имени поля при сохранении. */ function change_relationship_comment_length($number, $name){ if( $name = '_my_association' ) $number = 15; return $number; } add_filter('carbon_relationship_comment_length', 'change_relationship_comment_length', 10, 2);
(filter) carbon_relationship_options_{name}_post_{post_type}( $options )
Позволяет изменять доступные параметры поля отношений или ассоциаций с именем {name}
и типом поста {post_type}
.
К примеру, мы создали поле ассоциаций с именем my_association и указали отображаться в типе поста page (на страницах), тогда имя фильтра будет:
// Для страницы carbon_relationship_options__my_association_post_page
Фильтр в коде плагина объявлен следующим образом:
$args = apply_filters( $filter_name, array( 'post_type' => $type['post_type'], 'posts_per_page' => -1, 'fields' => 'ids', 'suppress_filters' => false, ) ); $posts = get_posts( $args );
Это значит, что мы можем вмешаться в запрос путем изменения его параметров, к примеру ограничить загрузку постов по количеству:
add_filter('carbon_relationship_options__my_association_post_page', 'change_carbon_relationship_options', 10, 1); function change_carbon_relationship_options( $options ){ $options['posts_per_page'] = 3; return $options; }
Обратите внимание на двойное подчеркивание __
в названии хука. Напоминаем, при сохранении Carbon Fields в начало имени поля дописывает одно нижнее подчеркивание. При составлении названия хука используется префикс в виде нижнего подчеркивания для отделения составных частей. В итоге префикс и начало имени поля дают нам двойное нижнее подчеркивание.
(filter) carbon_relationship_options_{name}_taxonomy_{taxonomy}( $options )
Принцип работы, как и у предыдущего фильтра. Позволяет изменять доступные параметры поля отношения / ассоциации с именем {name}
из таксономии {taxonomy}
.
Всё тот же пример с полем my_association
:
carbon_relationship_options__my_association_taxonomy_category
Объявление хука в коде плагина:
$args = apply_filters( $filter_name, array( 'hide_empty' => 0, 'fields' => 'id=>name', ) ); $terms = get_terms( $type['taxonomy'], $args );
(filter) carbon_relationship_options_{name}_user( $options )
Всё работает по тем же правилам, что и предыдущие подобные хуки.
Объявление хука в коде плагина:
$args = apply_filters( $filter_name, array( 'fields' => 'ID', ) ); $users = get_users( $args );
Изменение параметров может пригодится, к примеру, когда нужно исключить самого себя из списка ассоциаций:
add_filter('carbon_relationship_options__my_association_user', 'change_carbon_relationship_options_user', 10, 1); function change_carbon_relationship_options_user( $options ){ $options['exclude'] = get_current_user_id(); return $options; }
(filter) carbon_relationship_options_{name}_comment( $options )
Работает по тем же правилам, что и предыдущие подобные хуки.
Объявление хука в коде плагина:
$args = apply_filters( $filter_name, array( 'fields' => 'ids', ) ); $comments = get_comments( $args );
(filter) carbon_relationship_options( $options, $name )
Общий фильтр, через который проходит весь массив опций полей для ассоциаций и связей.
Переменная $name
имя поля с подчеркиванием в начале, к примеру _my_association
.
В переменной $options находится весь массив данных, вот выдержка из подобного массива:
[0] => Array ( [id] => 1 [title] => admin [type] => user [subtype] => user [label] => user [is_trashed] => [edit_link] => http://wp-test.ru/wp-admin/profile.php ) [1] => Array ( [id] => 2 [title] => user1 [type] => user [subtype] => user [label] => user [is_trashed] => [edit_link] => http://wp-test.ru/wp-admin/user-edit.php?user_id=2 ) [2] => Array ( [id] => 16 [title] => Ello! Pretend you're reading t... [type] => comment [subtype] => comment [label] => comment [is_trashed] => [edit_link] => http://wp-test.ru/wp-admin/comment.php?action=editcomment&c=16 )
К примеру, не прибегая к редактирования файла перевод вы можете изменить label
на любой желаемый в соответствии с type
. А может хотите на основе type
добавить в массив новые данные и потом использовать их в шаблоне вывода поля в админке.
Поле для Gravity Form
(filter) crb_gravity_form_options($options)
Фильтр даёт возможность изменить параметры выпадающего списка, в котором пользователь выбирает ту или иную форму, предоставляемую плагином Gravity Form. О данном поле читайте в статье о произвольных полях Carbon Fields.
add_filter('crb_gravity_form_options', 'crb_my_gravity_form_options'); function crb_my_gravity_form_options($options) { // Изменит дефолтный текст "Нет формы" $options[0] = 'Не отображать форму'; return $options; }
Поле для карты Google
(filter) carbon_map_api_key($api_key)
У плагина есть свой ключ для работы с API картами Google, но если вам нужно использовать собственный - данный фильтр поможет:
add_action( 'carbon_map_api_key', 'crb_get_gmaps_api_key' ); function crb_get_gmaps_api_key( $api_key ) { return 'впишите сюда свой ключ'; }