Давно уже меня просили написать пост про создание страниц настроек с использованием Settings API, но всё никак не доходили до него руки. Ну что же, вот и дошли.
Прежде всего не забывайте, страницы настроек и настройки темы в Theme Customizer – две разные вещи. Если вы хотите знать, чем они отличаются и заодно научиться добавлять опции в Theme Customizer, то рекомендую этот урок.
Кроме того, свои приколы по добавлению страниц настроек есть у WooCommerce – об этом тоже на сайте отдельный урок.
Обычно, в похожих уроках авторы любят рассматривать все функции по отдельности — в таких случаях их ну очень неудобно копировать и можно запутаться что к чему. Поэтому в конце урока я решил предоставить вам полностью готовый к использованию код — просто вставьте его сами знаете, куда, и страница настроек сразу появится у вас в админке. Ну а потом вы уже сможете отредактировать в ней поля, либо добавить свои собственные.
Ну, а если вам хочется разобраться в этом вместе со мной по шагам, то погнали!
Хорошая новость – вы можете разместить вашу страницу настроек абсолютно где угодно в меню в админке – это может быть как элемент меню верхнего уровня, так и вложенный в уже существующий элемент меню, например в «Инструменты» или в «Настройки».
Рассмотрим оба случая!
Для этого можно воспользоваться функцией add_menu_page() и только ей. Про неё следует помнить, что она должны находиться внутри хука admin_menu
, иначе у вас просто возникнут проблемки.
Пример:
add_action( 'admin_menu', 'true_top_menu_page', 25 ); function true_top_menu_page(){ add_menu_page( 'Настройки слайдера', // тайтл страницы 'Слайдер', // текст ссылки в меню 'manage_options', // права пользователя, необходимые для доступа к странице 'true_slider', // ярлык страницы 'true_slider_page_callback', // функция, которая выводит содержимое страницы 'dashicons-images-alt2', // иконка, в данном случае из Dashicons 20 // позиция в меню ); } function true_slider_page_callback(){ echo 'привет'; }
Если у вас возникают вопросы по параметрам функции, то они все у меня описаны в документации функции add_menu_page().
При вставке этого кода, надеюсь, вы знаете, куда, у вас появится меню в админке и даже отдельная страница для него:
Но вполне возможно, что для добавления своей страницы настроек вы не хотите перегружать админку новыми элементами, поэтому вы можете захотеть добавить свою страницу настроек в уже какой-то существующий пункт меню – логичнее всего конечно же в «Настройки».
Для этого вы можете воспользоваться функцией add_submenu_page(), либо какой-либо из альтернативных функций, в зависимости от того, куда будете добавлять вложенный пункт меню.
Пробуем видоизменить код выше:
add_action( 'admin_menu', 'true_top_menu_page', 25 ); function true_top_menu_page(){ add_submenu_page( 'options-general.php', 'Настройки слайдера', // тайтл страницы 'Слайдер', // текст ссылки в меню 'manage_options', // права пользователя, необходимые для доступа к странице 'true_slider', // ярлык страницы 'true_slider_page_callback' // функция, которая выводит содержимое страницы ); } function true_slider_page_callback(){ echo 'привет'; }
В итоге:
Теперь, вместо того, чтобы выводить «привет» в нашей колбэк-функции, мы добавим в неё следующее:
function true_slider_page_callback(){ echo '<div class="wrap"> <h1>' . get_admin_page_title() . '</h1> <form method="post" action="options.php">'; settings_fields( 'true_slider_settings' ); // название настроек do_settings_sections( 'true_slider' ); // ярлык страницы, не более submit_button(); // функция для вывода кнопки сохранения echo '</form></div>'; }
В этом коде я использовал функции:
После обновления кода, страница примет вид:
Если на этом моменте вам уже стало страшно, то возможно стоит рассмотреть возможность создания страниц настроек при помощи плагина Carbon Fields. Урок об этом тоже есть!
Для добавления поля нам понадобится целых… 5 функций! 🙃
На самом деле может показаться, что очень жёстко, но давайте попробуем!
Все эти функции весело отправляются в хук admin_init
.
add_action( 'admin_init', 'true_slider_fields' ); function true_slider_fields(){ // регистрируем опцию register_setting( 'true_slider_settings', // название настроек из предыдущего шага 'number_of_slider_slides', // ярлык опции 'absint' // функция очистки ); // добавляем секцию без заголовка add_settings_section( 'slider_settings_section_id', // ID секции, пригодится ниже '', // заголовок (не обязательно) '', // функция для вывода HTML секции (необязательно) 'true_slider' // ярлык страницы ); // добавление поля add_settings_field( 'number_of_slider_slides', 'Количество слайдов в слайдере', 'true_number_field', // название функции для вывода 'true_slider', // ярлык страницы 'slider_settings_section_id', // // ID секции, куда добавляем опцию array( 'label_for' => 'number_of_slider_slides', 'class' => 'misha-class', // для элемента <tr> 'name' => 'number_of_slider_slides', // любые доп параметры в колбэк функцию ) ); } function true_number_field( $args ){ // получаем значение из базы данных $value = get_option( $args[ 'name' ] ); printf( '<input type="number" min="1" id="%s" name="%s" value="%d" />', esc_attr( $args[ 'name' ] ), esc_attr( $args[ 'name' ] ), absint( $value ) ); }
printf()
и sprintf()
это две PHP-функции, которые очень часто используются в разработке на WordPress. Вы можете почитать о них в PHP-документации. Например в примере выше мы видим первый параметр, который представляет собой строку-шаблон, в ней все вхождения %s
и %d
будут заменены на следующие параметры функции в соответствующем порядке, где %s
должно представлять собой строковое значение, а %d
– целое число. Кроме того, я добавил очистку absint(), потому что мы также должны исключить отрицательные числа.
Итак:
Если в предыдущем коде вы сделаете несколько изменений, а именно:
// регистрируем опцию register_setting( 'media', 'number_of_slider_slides', 'absint' ); // добавляем секцию без заголовка add_settings_section( 'slider_settings_section_id', 'Настройка слайдера', '', 'media' ); // добавление поля add_settings_field( 'number_of_slider_slides', 'Количество слайдов в слайдере', 'true_number_field', 'media', 'slider_settings_section_id',
То наша опция слайдера появится в Настройки > Медиафайлы:
Также вы можете воспользоваться и другими идентификаторами стандартных страниц настроек:
general
– Общие,writing
– Написание,reading
– Чтение,discussion
– Обсуждение,media
– Медиафайлы,permalink
– Постоянные ссылки;Последний шаг – при нажатии на кнопку «Сохранить изменения» неплохо бы сообщить об этом пользователю!
add_action( 'admin_notices', 'true_custom_notice' ); function true_custom_notice() { if( isset( $_GET[ 'page' ] ) && 'true_slider' == $_GET[ 'page' ] && isset( $_GET[ 'settings-updated' ] ) && true == $_GET[ 'settings-updated' ] ) { echo '<div class="notice notice-success is-dismissible"><p>Слайдер сохранён!</p></div>'; } }
Получаем совсем красоту в итоге:
Также не могу не рассказать вам про то, как настроить валидацию полей. Для этого нам понадобится использовать две функции settings_errors() для вывода ошибок и add_settings_error() для добавления ошибки. Обе эти функции привязаны к друг к другу при помощи первого параметра-идентификатора, который должен совпадать, например settings_errors( 'hey-error' )
и add_settings_error( 'hey-error', ... )
. Попробуем это реализовать!
Прежде всего подготовим в нашем коде место для вывода ошибок. Для этого я возьму код из второй части урока и добавлю там функцию settings_errors() непосредственно в то место, где я хочу вывести ошибки! Например:
function true_slider_page_callback(){ echo '<div class="wrap"> <h1>' . get_admin_page_title() . '</h1> <form method="post" action="options.php">'; settings_errors( 'true_slider_settings_errors' ); // ярлык – любой settings_fields( 'true_slider_settings' ); ...
Здесь мы возвращаемся к функции register_setting() из третьего шага, в котором мы регистрировали опцию настроек:
// регистрируем опцию register_setting( 'true_slider_settings', // название настроек из предыдущего шага 'number_of_slider_slides', // ярлык опции 'absint' // функция очистки );
Меняем название функции очистки (у меня это absint()) на любую кастомную функцию, которую мы сейчас и создадим:
// регистрируем опцию register_setting( 'true_slider_settings', // название настроек из предыдущего шага 'number_of_slider_slides', // ярлык опции 'true_validate' // функция валидации );
И создаём эту функцию:
function true_validate( $input ) { // сначала можно сразу же очистить $input = absint( $input ); if( $input < 2 ) { // добавляем свои условия валидация add_settings_error( 'true_slider_settings_errors', 'malo-slides', // часть ID, добавляемый к сообщению об ошибке id="setting-error-malo-slides" 'В слайдере должно быть хотя бы два слайда иначе это и не слайдер вовсе!', 'error' // может быть success, warning, info ); // получаем и возвращаем старое значение поля, если валидация не прошла $input = get_option( 'number_of_slider_slides' ); } return $input; }
Теоретически, мы можем не отображать уведомление о сохранении полей, если существуют ошибки:
add_action( 'admin_notices', 'true_custom_notice' ); function true_custom_notice() { // получаем ошибки $settings_errors = get_settings_errors( 'true_slider_settings_errors' ); // если они есть, то уведомление о сохранении выводить не будем if ( ! empty( $settings_errors ) ) { return; } ...
На этом всё! Мы молодцы!
Также рекомендую свой видеокурс по созданию темы WordPress на основе готовой вёрстки.
Решил в качестве небольшого бонуса не только объединить все сниппеты код в один, но и превратить их в PHP-класс. Да, в этом коде нет валидации, только очистка.
class trueOptionsPage{ public $page_slug; public $option_group; function __construct() { // это у нас используется много где, поэтому давайте вынесем как отдельное свойство $this->page_slug = 'true_slider'; $this->option_group = 'true_slider_settings'; add_action( 'admin_menu', array( $this, 'add' ), 25 ); add_action( 'admin_init', array( $this, 'settings' ) ); add_action( 'admin_notices', array( $this, 'notice' ) ); } function add(){ add_menu_page( 'Настройки слайдера', 'Слайдер', 'manage_options', $this->page_slug, array( $this, 'display' ), 'dashicons-images-alt2', 20 ); } function display() { echo '<div class="wrap"> <h1>' . get_admin_page_title() . '</h1> <form method="post" action="options.php">'; settings_fields( $this->option_group ); do_settings_sections( $this->page_slug ); submit_button(); echo '</form></div>'; } function settings(){ register_setting( $this->option_group, 'number_of_slider_slides', 'absint' ); add_settings_section( 'slider_settings_section_id', '', '', $this->page_slug ); add_settings_field( 'number_of_slider_slides', 'Количество слайдов в слайдере', array( $this, 'field' ), $this->page_slug, 'slider_settings_section_id', array( 'label_for' => 'number_of_slider_slides', 'class' => 'misha-class', 'name' => 'number_of_slider_slides', ) ); } function field( $args ){ // получаем значение из базы данных $value = get_option( $args[ 'name' ] ); printf( '<input type="number" min="1" id="%s" name="%s" value="%s" />', esc_attr( $args[ 'name' ] ), esc_attr( $args[ 'name' ] ), absint( $value ) ); } function notice() { if( isset( $_GET[ 'page' ] ) && $this->page_slug == $_GET[ 'page' ] && isset( $_GET[ 'settings-updated' ] ) && true == $_GET[ 'settings-updated' ] ) { echo '<div class="notice notice-success is-dismissible"><p>Слайдер сохранён!</p></div>'; } } } new trueOptionsPage();
Так получилось, что когда мои англоязычные читатели и клиенты говорят слово «frontend», то они подразумевают непосредственно страницы самого сайта, не считая админку. Хм, не уверен, что это 100% правильно, но пусть будет так.
Для того, чтобы получить значение какой-либо опции настроек WordPress достаточно использовать функцию get_option(). На этом всё, до свидания.
Рассмотрим на нашем примере. В саму функцию нам нужно передать единственный параметр – ярлык (ключ) опции, который мы задавали, когда добавляли поле (строчки 8 и 22).
// регистрируем опцию register_setting( 'true_slider_settings', // название настроек из предыдущего шага 'number_of_slider_slides', // ярлык опции
// добавление поля add_settings_field( 'number_of_slider_slides',
Воспользуемся этим ярлыком, чтобы получить значение опции:
$num_slides = get_option( 'number_of_slider_slides' ); echo 'Количество слайдов: ' . $num_slides;
Про очистку тоже помним, да?
$num_slides = get_option( 'number_of_slider_slides' ); echo 'Количество слайдов: ' . absint( $num_slides );
Или вот так:
echo sprintf( 'Количество слайдов: %d', get_option( 'number_of_slider_slides' ) );
Возможно, что тут вам захочется почитать про документацию PHP-функции sprintf()
, но если коротко: то в шаблоне %d
– целое число, %s
– строка.
Также хотел обратить ваше внимание на то, что если в вашей теме или плагине вы используете несколько полей настроек, то вам необязательно использовать отдельные строчки в базе данных для хранения значений каждого из них.
То есть да, вы вполне можете зарегистрировать каждое значение, как отдельную опцию, вот так:
register_setting( 'true_option_group', 'color' ); register_setting( 'true_option_group', 'size' ); register_setting( 'true_option_group', 'quantity' );
Но возможно, что будет легче и эффективнее использовать всего лишь одну опцию и хранить все значения сразу в ней. Тогда нам будет достаточно одного-единственного вызова функции register_setting().
register_setting( 'true_option_group', 'true_option' );
Но что же дальше? А вот что. Допустим дальше мы создаём колбэк-функцию вывода поля цвета color
:
function field(){ // получаем массив значений опции из базы данных $options = (array) get_option( 'true_option' ); printf( '<input type="text" name="true_option[color]" value="%s" />', esc_attr( $options[ 'color' ] ); ); }
То же самое произойдёт и при выводе опции где-либо на сайте, т.е сначала получаем всю группу опций: $options = (array) get_option( 'true_option' );
а затем обращаемся к интересующему нас элементу массива $options[ 'color' ]
.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Спасибо за статью. У меня вот какой вопрос, при разработке тем одни авторы используют Theme options, другие же Theme Customizer, при этом, и первые и вторые решают с помощью них одни и те же задачи, есть вообще между ними какое то функциональное разграничение, что определяет: какой из способов более приемлем для той или иной темы?
Одно и то же это, если я правильно понял вопрос.
В попытках хоть как то разобраться в этом вопросе наткнулся на ребят активно дискутирующих на эту тему (если автор сайта не будет против ссылка на статью перелагается ): http://wordpress.stackexchange.com/questions/97929/settings-api-vs-theme-customizer
В целом я пришел к выводу, что это не совсем одно и тоже, но такое впечатление неизбежно возникает из за некоторого функционального перекрытия, в общем эта тема — бездна.
Всё, я понял суть вопроса :)
Options API — нужно для добавления настроек через тему или плагин.
Theme Customizer же настроек не добавляет, он позволяет просмотреть изменения уже существующих настроек «вживую» на сайте.
« Theme Customizer же настроек не добавляет », почему же? Если правильно понял то вот так можно через
можно добавить любые поля по настройке темы и ввода данных:
и да, как вы и сказали, в отличи от Theme options, Theme Customizer — позволяет тут же просмотреть изменения
Ну значит на следующей неделе пост будет про Theme Customizer :)
Это здорово. И в полку недоумевающих явно пребудет :)
А что у вас за плагин для комментирования записей в этом блоге?
Собственная разработка.
На ваш взгляд лучше использовать сторонние комментарии на wordpress или стандартные тоже подойдут? Есть ли у стандартных какие-то недостатки?
Хороши и стандартные, и disqus / vk / facebook.
Спасибо за очередную полезную статью. Не-могли опубликовать пост, ли что то вроде того как добавить поле для логотипа, что-бы можно было загрузить картинку?
Пожалуйста :)
А он уже есть, вот тут.
а как это сюда добавить?
Боюсь, что придётся пошаманить. Если вы более-менее хорошо знаете PHP, то проблем у вас не возникнет.
Может пост. :D
Да, надо будет дополнить/изменить старый пост про загрузчик изображений :)
Спасибо.. Когда примерно ждать?
Как будет время.
в true_option_display_settings добавить:
использовать аналогично:
Здравствуйте, Михаил! Говорят, кто ищет тот найдёт. Нашёл Ваш сайт, чему очень рад, хотя многое не понимаю о чём разговор продвинутых. Однако буду учиться. Тем более, что Вам в личку написал про проблемы с сайтом! Подписку оформил.
Привет. Не совсем понял как применять эти поля в самом шаблоне. Не понятно как добавить свое поле и что при этом можно менять а что нет. Честно говоря - ничего не понятно) готовый код так пугает.
Здравствуйте Михаил, такой вопрос, может подскажите, хочу сделать сброс настроек на дефолтные, но не пойму как перезаписать можно, почему-то так
Не перезаписывает, может я что-то не так делаю? или с помощью какой функции можно перезаписать.
Создал кнопку такую
Хочу по клику устанавливать в дефолтные настройки.
Может есть вообще упрощенный вариант? Буду признателен за помощь.
Здравствуйте!
Спасибо Михаил, все работает! )
Михаил, спасибо за статью. Но сейчас возникла необходимость использовать чекбокс. Ранее, я использовал другой аналогичный способ (theme-option.php) и там у меня получилось использовать чекбокс. Тут я не пойму как. Чекбокс должен вывести текст, если он включен. Буду очень благодарен за ответ.
А пример чекбокса не работает?
Добрый день, Михаил!
Спасибо за статью, за ваши труды, очень пригодилось!
У меня вопрос, как мне между секциями настроек вставить свой HTML код, описание настроек, в общем информационный блок?
с уважением, Александр
Добрый день!
Да можете просто в
switch
добавить к примеру:Спасибо! Не подумал, что можно 'info' указать и будет счастье!
Не робыт! :(
Дико извиняюсь за свою ограниченность, но как мне теперь текст текстового поля из настроек вывести в шаблон?
Что-то не выходит... :(
Пишу так:
Так ведь в статье написано, как правильно, в самом низу :)
Прошу прощения. виноват!
Михаил, а не подскажете, как можно реализовать, что бы после выбора настройки в селекте появлялись настройки согласно выбранному?
Сделал добавление секции с настройками по выбору селекта, вот только она появляется после сохранения настроек, а вот как сделать, что бы она появлялась сразу после выбора?
Вот в чем вопрос!
Понимаю, что нужно использовать JS, но в этом я уж совсем тяжко...
Может поможете?
Ну что я могу сказать, нужно разбираться в JS/jQuery
Ок, скрипт я смогу написать, а куда мне его вставить и каким образом лучше всего это сделать?
Вот скрипт и разметка http://pastebin.com/KFAQpuZG , что позволяет открывать или скрывать содержимое. Не подскажете, как его внедрить можно?
Скрипты в админку WP добавляйте через хук
admin_footer
.Михаил, скрипты подключил, вот ни как допетрить не могу как мне скрывать поля настроек, как их заключить в див?
В принципе само поле настроек во второй колонке могу скрыть, а вот как скрыть с название настройки из первой колонки, не пойму?
Почитайте про такие методы jQuery, как
parent()
,next()
,prev()
,find()
.Почитал, вашу мысль понял, я не селен в JS, но вроде из прочтенного ни чего сложно, будем пилить!
Как говорят: "Пилите, Шура, они же золотые!"...
Спасибо, ваш сайт прям превращается в домовую книгу!
У вас всё получится!
Не знаю, что такое домовая книга, но спасибо:)
Домовая книга - это книга с рецептами к которой сразу обращаются, в случае чего, еще ее называют поваренной
Ок, буду знать. Рад, что мой сайт как книга рецептов)
Без понятия, почему яндекс на меня АГС повесил///
Михаил, что делаю не так, не могу включить чекбоксом это:
???
Во я тупень, разобрался, нужно было не глобал писать, а
:)))
:))
Михаил, сделал по вашему коду два плагина, но вот ерунда какая получается, настройки обоих плагинов отображается вместе в каждом плагине, а если один из них деактивирую, то соответственно пропадают настройки того. который деактивировал!
Функции, секции, настройки и т.д. т.п., не совпадают, все уникальные!
А переменная
$true_page
совпадает?Нет! На обоих плагинах нет совпадений, все уникально! Они имеют одинаковую структуру и все...
Интересно, высылайте мне их по email.
Отправил! Спасибо за желание помочь!
Как-то можно задать значения по умолчанию? Например, чтобы чекбокс скарзу после установки темы был активирован. Если да, то не подскажете как?
Тогда лучше всего обновить настройки после активации темы хуком
after_switch_theme
.Приветствую, Михаил! Отличное решение. Вопрос: если настройки записываются в бд, то как их удалить при удалении плагина? Где почитать об этом?
Приветствую! Спасибо!
Где почитать не знаю (по крайней мере в рунете), но на словах могу объяснить — просто на хук удаления плагина вешаем функцию
delete_option()
.Миш, если найдешь минутку, подскажи, пожалуйста, как лучше:
Часть настроек используется в шапке сайта и часть настроек - в подвале. Получается, что два раза необходимо выполнить get_option('true_options'). Как этого избежать?
И подвал и шапка — это функции внутри какого-то файла, например
index.php
, поэтому настройки можно записать в глобальную переменную в самом начале файла и потом обращаться к ней из подвала / шапки (теоретически).Привет, почему может выдавать ошибку
Fatal error: Cannot redeclare true_options()
в on line 10
Привет. Уже есть класс с таким названием :)
Привет! Подскажи два момента по данному функционалу:
1. Откуда берутся переменные $args, $type, $input
2. Зачем нужна функция extract($args); если в переменной $args ничего нет
Или как-то не правильно понимаю как это работает
Привет!
Функция add_settings_field() передаёт параметры в колбэк функцию true_option_display_settings() в виде переменной $args.
Ага, понял. Вот только почему $args? Она же нигде не определена, по логике должна быть переменная $true_field_params или что-то не так понимаю?
Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.
А как жне всякие колор пикеры, вроде в ВП есть стандартный
Да, есть
Предлагаю добавить в код все возможные варианты, чтобы использовать как болванку. Уж у меня точно в закладках будет.
А как на такой странице запустить wp_query?
Да как обычно внутри
true_option_page()
И это типа удобно?! Жесть. Никакого контроля, неудобно нифига. Нормально не сверстать.
А что подразумевается под "контролем"? очень интересно знать
Михайил подскажите пожалуйста, как между секциями настроек вставить свой HTML код, описание настроек, в общем информационный блок?
Добавление в switch ничего не меняет:
Нужно что-то еще менять?
Все допер, нужно прописать новую переменную и затем ее вызвать.
Здравствуйте. Скажите как изменить вывод в админке. В частности, не таблицей сделать вывод
А можно ли как то создавать эти поля или разделы не вручную в каком то цикле? К примеру я бы хотел иметь настройки для атрибутов товаров woocommerce. Я могу вызвать в цикле все атрибуты. Но создать таким образом поля на странице настроек не удается.
Вывожу атрибуты вот так:
А почему не получается? Ну я в том плане – что конкретно
Добрый день, Михаил! Подскажите пожалуйста - что необходимо добавить или переделать в ваш код, чтобы в "кастомное" поле можно было сохранять как, положительные, так и отрицательные десятичные (и или) целые числа ??? (Например: "-10.2" "929.5" "1000.1" "-120" и т.д. но числа более 99999 и менее чем -99999 - не будет ). И чтобы в админке тоже отображались в том виде в котором сохранил? Я попробовал добавляь условие в input - когда выводит и type="prise" и type="number" ничего не получается. Убрал функцию очистки "absint" - с отрицанием числа и сохраняет и выводит в админку. Попробовал после этого с точкой число сохранить (то есть с дробным числом) - полез в БД ... В БД это число так и сохраняется с дробной частью (то что после точки) - а вот в админку плагина выводится только целое число. Сделал "var_dump ($value = get_option( $args[ 'name' ] )); //($value = get_option( $args[ 'name' ] ));" - мне так же показало что число вывелось с дробной частью - а в админке только то что до точки.
Как это исправить?
Весь ответ на мой вопрос - это отключить проверку
"absint"
и сроке кода на вывод данных из БД - там где input - нужно просто поменятьvalue="%d"
наvalue="%f"
. Спасибо, Михаил за ваш блог, за ваши материалы. Мира и добра вашей команде!Спасибо, взаимно! 🙏🏼
Добрый день, возник вопрос такой.
Я обычно создавал настройки для темы через произвольные поля Carbon Fields или ACF, не когда не пробывал создавать через Options API, Customizer API. Вот подумал попробывать такой вариант тоже. и тут вопросы
1. Скажите а в чем разница между Options API и Customizer API ?
2. Подерживает ли Options API и Customizer API Polylang смогу ли я сделать переводы для них ?
3. Если делать через Carbon Fields или ACF, там можно и галерею создавать и ассоциации(типо потягивает уже готовые записи, связь делать) можно ли такое делать Options API и Customizer API ? или там много надо писать JS ?
Добрый день,
1. Я бы не стал использовать customizer api, на мой взгляд это какой-то определённый путь, по которому хотели пойти WordPress, но передумали.
2. Да, это возможно, но вероятно потребуется Polylang PRO.
3. Ну немножко придётся написать JS, пару десятков строчек.