Kama_Post_Meta_Box – створюємо метаполя для записів
У цій статті я поділися класом Kama Post Meta Box , за допомогою якого можна швидко створювати метаполі для записів, просто вказавши їх у вигляді масиву. Виходить свого роду конструктор. До того ж цей варіант автоматично очищає дані при збереженні і в деяких випадках може захистити від злому сайту.
Статтю на цю тему я вже писав: ” Блок довільних полів в адмінці WordPress своїми руками “. Правда було це давно, але стаття, як і раніше, актуальна і може стати в нагоді, коли потрібно створити довільні поля для запису, без використання плагінів. Однак у тому варіанті все потрібно робити вручну, включаючи створення HTML кожного поля форми – це не зручно. Також той варіант вимагає певних знань: вміння працювати з хуками і т.д.
Покажу приклад, як легко можна створити довільні поля для записів. Допустимо, нам потрібно створити 4 SEO поля: title, description, keywordsі robotsдля всіх типів записів. Для створення метабоксу потрібно викликати клас Kama_Post_Meta_Box із передачею йому параметрів:
post_type_options (рядок) Масив. Опції типу запису, які повинні мати тип запису, щоб метабокс відобразився. See переривчастий параметр https://wp-doc.com/get_post_types
priority (рядок) Пріоритет блоку для показу вище або нижче інших блоків (‘high’ або ‘low’).
context (рядок) Місце, де повинен показуватися блок (‘normal’, ‘advanced’ або ‘side’).
disable_func (callback) Функція відключення метабоксу під час виклику самого метабоксу. Якщо поверне щось крім false/null/0/array(), то метабокс буде відключений. Передає об’єкт посту.
cap (рядок) Назва права користувача, щоб показувати метабокс.
save_sanitize (callback) Функція очищення полів, що зберігаються в БД. Отримує два параметри: $metas – всі поля для очищення і $post_id.
theme (рядок) Тема оформлення: table , line , grid . АБО масив патернів полів: css, fields_wrap, field_wrap, title_patt, field_patt, desc_before_patt. ЯКЩО Масив вказується так: [ ‘desc_before_patt’ => ‘<div>%s</div>’ ] (за овнову буде взято тему line). ЯКЩО Масив вказується так: [ ‘table’ => [ ‘desc_before_patt’ => ‘<div>%s</div>’ ] ] (за овнову буде взята тема table). АБО змінити тему можна через фільтр ‘kp_metabox_theme’ (зручний для загальної зміни теми для всіх метабоксів).
fields (масив) Метаполя. Власне самі метаполя. Список можливих ключів масиву для кожного поля.
type (рядок) Тип поля: textarea, select, checkbox, radio, image, wp_editor, hidden, sep_*. Або базові: text, email, number, url, tel, color, password, date, month, week, range. ‘sep’ – візуальний роздільник, йому потрібно вказати title і можна вказати ‘attr’=>’style=”свої стилі”‘ . ‘sep’ – щоб зручніше вказувати тип ‘sep’ почніть ключ поля з sep_ : ‘sep_1’ => [ ‘title’=>’Розділювач’ ]. Для типу image можна вказати тип значення, що зберігається в options : ‘options’=>’url’. Типово тип = id. За промовчанням ‘text’.
title (рядок) Заголовок метаполя.
desc (рядок|callback) Опис для поля. Можна вказати функцію/замикання, вона отримає параметри $post, $meta_key, $val, $name.
desc_before (рядок|callback) Аліас $desc.
desc_after (рядок|callback) Теж що $desc, тільки виводитиметься внизу поля.
placeholder (рядок) Атрибут placeholder.
id (рядок) Атрибут id. За замовчуванням $this->opt->id .’_’. $key.
class (рядок) Атрибут class: додається до input, textarea, select. Для checkbox, radio у обертаючий label.
attr (рядок) Будь-який рядок. Атрибути HTML тегу елемент форми (input).
wrap_attr (рядок) Будь-який рядок. Атрибути HTML тега, що обертає поле: style=”width:50%;” .
val (рядок) Стандартне значення, якщо немає збереженого.
options (рядок) масив: array(‘значення’=>’назва’) – варіанти для типів ‘select’, ‘radio’. Для ‘wp_editor’ стіне аргументами. Для ‘checkbox’ стане значенням атрибута value:. Для ‘image’ визначає тип значення, що зберігається в метаполі: id (ID вкладення), url (url вкладення).
callback (callback) Назва функції, що відповідає за виведення поля. Якщо зазначено, то жоден параметр не враховується і за висновок повністю відповідає вказана функція. Отримає параметри: $args, $post, $name, $val, $rg, $var
sanitize_func (callback) Функція очищення даних при збереженні – назва функції або Closure. Вкажіть ‘none’, щоб не очищати дані… Працює тільки якщо не встановлено глобальний параметр ‘save_sanitize’… Отримає параметр $value – значення поля, що зберігається.
output_func (callback) Функція обробки значення перед виведенням у поле. Отримає параметри: $post, $meta_key, $value – об’єкт запису, ключ, значення метаполів.
update_func (callback) Функція збереження значення метаполя. Отримає параметри: $post, $meta_key, $value – об’єкт запису, ключ, значення метаполів.
disable_func (callback) Функція вимкнення поля. Якщо не false/null/0/array() – щось поверне, поле не буде виведено. Отримує параметри: $post, $meta_key
cap (рядок) Назва права користувача, щоб бачити та змінювати поле.
нотатки
Назви довільних полів
Довільні поля, що створюються, матимуть назву/ключ, що складається з об’єднання основного ID і вказаного ключа метаполя: {id}_{meta_key}(див. приклад нижче).
Найпростіший спосіб дізнатися назву довільного поля – це подивитися у вихідний код. Для цього фокусуємося на потрібному полі, натискаємо правою кнопкою і дивимося значення атрибута name у вихідному коді елемента:
Отримання довільних полів
Отримувати створені поля для використання у темах та плагінах потрібно стандартною функцією WordPress: get_post_meta() :
// Отримаємо значення поля 'my_meta_key' у запису 25
$ my_filed = get_post_meta(25, 'my_meta_key', 1);
echo $my_filed;
Права
Блок/метабокс буде показаний лише користувачам, які мають право редагувати поточний запис.
Збереження метаполів працюватиме лише для користувачів, які можуть редагувати поточний запис.
Приклади створення різних довільних полів
#1 Демонстрація створення всіх видів метаполів
Цей приклад показує як створювати всі типи метаполів, що підтримуються: ‘text’, ‘textarea’, ‘select’, ‘checkbox’, ‘radio’, ‘wp_editor’, ‘hidden’ та інші: ’email’, ‘number’, ‘phone ‘, ‘password’ і т.д. (Обробляються як поле ‘text’).
class_exists('Kama_Post_Meta_Box') && new Kama_Post_Meta_Box(
array(
'id' => 'my',
'title' => 'Мої довільні поля',
'fields' => array(
'text_field' => array(
'title' => 'Текстове поле'
),
'number_field' => array(
'type'=>'number', 'title'=>'Числове поле', 'desc'=>'Число від 0 до 5', 'attr'=>'min="0" max="5"'
),
'textarea_field' => array(
'type'=>'textarea', 'title'=>'Велике текстове поле', 'desc'=>'Опис чогось. Можна використовувати html теги.
),
'select_field' => array(
'type'=>'select', 'title'=>'Виберіть значення', 'options'=>array(''=>'Нічого не вибрано', 'val_1'=>'Вибір 1', 'val_2'= >'Вибір 2')
),
'select_field2' => array(
'type'=>'select', 'title'=>'Виберіть значення 2', 'options'=>array('Вибір 1', 'Вибір 2'), 'desc'=>'Вибір, де не вказується значення value для тегів option'
),
'checkbox_field' => array(
'type'=>'checkbox', 'title'=>'Галочка', 'desc'=>'позначте, якщо хочете :)'
),
'checkbox_field2' => array(
'type'=>'checkbox', 'desc'=>'< тільки опис для галочки, без заголовка'
),
'radio_field' => array(
'type'=>'radio', 'title'=>'Перемикач', 'desc'=>'Виберіть одне з значень', 'options'=>array(''=>'Нічого не вибрано', 'good' =>'добре', 'bad'=>'погано')
),
'radio_field2' => array(
'type'=>'radio', 'desc'=>'Перемикач без заголовка', 'options'=>array(''=>'Не вибрано', 'good'=>'добре', 'bad'=> 'погано')
),
'wp_editor_field' => array(
'type'=>'wp_editor', 'title'=>'Текстове поле з редактором TinyMce'
),
'wp_editor_field2' => array(
'type'=>'wp_editor', 'title'=>'Текстове поле з редактором WordPress, без TinyMce', 'options'=>array('tinymce'=>0) // Список налаштувань: http://wp- kama.ru/function/wp_editor
),
'hidden_field' => array(
'type'=>'hidden', 'val'=>'foo'
),
'' => array('type'=>'text', 'title'=>''), // заготівля
),
)
);
В результаті з’явиться такий метаблок на сторінці редагування будь-якого типу запису.
А при збереженні будуть створені такі довільні поля:
#2 Блоки для зазначених типів записів
Коли потрібно створити метабокс з метаполями тільки для зазначених типів запису, вкажіть параметр 'post_type' => array('post','page'), у якому перерахуйте потрібні типи записів.
class_exists('Kama_Post_Meta_Box') && new Kama_Post_Meta_Box(
array(
'id' => 'my',
'title' => 'Мої довільні поля',
'post_type' => array('page', 'my_type') // показувати тільки на сторінках типу: page і my_type
'fields' => array(
'text_field' => array( 'title' => 'Текстове поле' ),
),
)
);
#3 Своя функція виведення поля
Коли можливостей класу недостатньо і потрібно створити поле, яке матиме якийсь особливий висновок, використовуйте параметр callbackдля поля, що створюється.
У цьому випадку можна налаштувати виведення поля як завгодно. Для прикладу давайте створимо кілька полів, які зберігатимуться у полі special_fieldу вигляді масиву.
Всі дані зберігатимуться у полі my_special_fieldу вигляді масиву array( 'box1'=>'яблоки', 'box1'=>'апельсины', 'box1'=>'груши' ).
#4 Точні назви полів без префікса
Коли потрібно, щоб назви метаполів були такі самі, які ви вказали, додайте в початок idнижнє підкреслення _.
Це може знадобитися, якщо у вас є метаполя і вам потрібно підлаштуватися під їх назви. У цьому випадку префікс, який додається для назви кожного метаполя, буде зайвим.
Наприклад, у вас вже є метаполя: foo, bar, views, titleі для них потрібно створити метабокс:
class_exists('Kama_Post_Meta_Box') && new Kama_Post_Meta_Box(
array(
'id' => '_my', // "_" - означає, що id не буде додаватися в назву поля
'title' => 'Мої точні довільні поля',
'fields' => array(
'foo' => array( 'title' => 'Поле foo' ),
'bar' => array( 'title' => 'Поле bar' ),
'views' => array( 'title' => 'Поле views' ),
'title' => array( 'title' => 'Поле title' ),
),
)
);
Отримаємо такий метабокс:
#5 Очищення значень перед збереженням
Клас автоматично очищає всі поля та захищає від XSS атак. Але іноді може бути потрібно очистити певне поле якось особливо. У цьому випадку вкажіть функцію очищення у параметрі 'save_sanitize'або використовуйте фільтр "kpmb_save_sanitize_{id}". Якщо вказана функція або хук очищення, то клас ніяк не очищає дані, що зберігаються, очищення всіх полів має бути у вашій функції очищення.
Допустимо, ми створюємо поле в якому всі символи повинні бути великими, а якщо вони вказані як малі, то автоматично перетворимо їх у великі і збережемо:
class_exists('Kama_Post_Meta_Box') && new Kama_Post_Meta_Box(
array(
'id' => 'my',
'title' => 'Мої довільні поля',
'save_sanitize' => 'my_metabox_sanitize_function',
'fields' => array(
'foo_field' => array( 'title'=>'Деякі поля' ),
'for_esc' => array( 'title'=>'Спеціальне поле', 'desc'=>'Поле, яке має містити тільки великі символи.' ),
),
)
);
// функція очищення всіх полів
function my_metabox_sanitize_function( $metas, $post_id ){
/*
$metas = поля, що зберігаються в масиві
$post = ID запису
*/
// Очищаємо потрібне поле
foreach( $metas as $key => & $val ){
// наше поле
if( $key == 'my_for_esc' )
$ val = mb_strtoupper ($ val);
// всі інші поля
else
$ val = sanitize_text_field ($ val);
}
return $metas;
}
В результаті отримаємо:
Ще один приклад функції очищення
Такий підхід використовується у класі, якщо не вказати функцію очищення. Він очищає за допомогою wp_kses() та обробляє масив та всі вкладені масиви.
#6 Теми оформлення: налаштування html та css кожного поля
Можна вказати, як повинні виводитися поля в метабоксі. Для цього є параметр theme– тема оформлення.
У цьому параметрі можна вказати рядок або масив:
table(за замовчуванням) – поля будуть виведені у табличній формі.
line– Поля будуть виведені лініями. На всю ширину метабоксу, де йде заголовок поля, а під ним саме поле.
grid– подя будуть виведені у вигляді таблиці.
array()– вказуючи масив, ви можете самі визначити всі види тегів, що обертають, для кожного елемента поля. У масиві можна вказати такі параметри:
css– CSS стилі метабоксу. Наприклад: ‘.my_field{ margin:1em; }’
fields_wrap– Формат обгортки всього метаблоку (всіх полів)
field_wrap— формат обгортки поля (разом із заголовком та полем)
title_patt– Формат обгортки заголовка поля
field_patt– Формат обгортки самого поля (тільки input …)
desc_patt– Формат обгортки опису поля
class_exists('Kama_Post_Meta_Box') && new Kama_Post_Meta_Box(
array(
'id' => 'my',
'title' => 'Мої довільні поля',
'theme' => array(
'css' => '.my_field_wrap{ margin-bottom:1em; } .my_field_desc{ opacity:0.5; } .my_field_tit{ font-weight:bold; margin-bottom:.3em; }',
'fields_wrap' => '%s',
'field_wrap' => '<div class="my_field_wrap %1$s">%2$s</div>', // '%2$s' буде замінено на html поля
'title_patt' => '<div class="my_field_tit">%s</div>', // '%s' буде замінено на заголовок
'field_patt' => '%s',
'desc_patt' => '<span class="my_field_desc">%s</span>', // '%s' буде замінено на текст опису
),
'fields' => array(
'text_field' => array(
'title' => 'Текстове поле'
),
'number_field' => array(
'type'=>'number', 'title'=>'Числове поле', 'desc'=>'Число від 0 до 5', 'attr'=>'min="0" max="5"'
),
'textarea_field' => array(
'type'=>'textarea', 'title'=>'Велике текстове поле', 'desc'=>'Опис чогось. Можна використовувати html теги.
),
'select_field' => array(
'type'=>'select', 'title'=>'Виберіть значення', 'options'=>array(''=>'Нічого не вибрано', 'val_1'=>'Вибір 1', 'val_2'= >'Вибір 2')
),
'checkbox_field' => array(
'type'=>'checkbox', 'title'=>'Галочка', 'desc'=>'позначте, якщо хочете :)'
),
'radio_field' => array(
'type'=>'radio', 'title'=>'Перемикач', 'desc'=>'Виберіть одне з значень', 'options'=>array(''=>'Нічого не вибрано', 'good' =>'добре', 'bad'=>'погано')
),
'wp_editor_field2' => array(
'type'=>'wp_editor', 'title'=>'Текстове поле з редактором WordPress, без TinyMce', 'options'=>array('tinymce'=>0) // Список налаштувань: http://wp- kama.ru/function/wp_editor
),
'' => array('type'=>'text', 'title'=>''), // заготівля
),
)
);
В результаті отримаємо такий метабокс:
#7 Як виглядає тема grid
new Kama_Post_Meta_Box( [
'id' => '_recept',
'title' => 'Рецепт (короткий опис)',
'theme' => 'grid',
'post_type' => ['post'], // не виводити типів записи
'fields' => [
'text_field' => array(
'title' => 'Текстове поле'
),
'hidden' => array(
'title' => 'hiddentitle',
'type' => 'hidden'
),
'image' => array(
'title' => 'Малюнок',
'type' => 'image'
),
'number_field' => array(
'type'=>'number', 'title'=>'Числове поле', 'desc'=>'Число від 0 до 5', 'attr'=>'min="0" max="5"'
),
'textarea_field' => array(
'type'=>'textarea', 'title'=>'Велике текстове поле', 'desc'=>'Опис чогось. Можна використовувати html теги.
),
'select_field' => array(
'type'=>'select', 'title'=>'Виберіть значення', 'options'=>array(''=>'Нічого не вибрано', 'val_1'=>'Вибір 1', 'val_2'= >'Вибір 2')
),
'checkbox_field' => array(
'type'=>'checkbox', 'title'=>'Галочка', 'desc'=>'позначте, якщо хочете :)'
),
'radio_field' => array(
'type'=>'radio', 'title'=>'Перемикач', 'desc'=>'Виберіть одне з значень', 'options'=>array(''=>'Нічого не вибрано', 'good' =>'добре', 'bad'=>'погано')
),
'sep_1' => [ 'title'=>'Довга пропозиція для роздільника' ],
'wp_editor_field2' => array(
'type'=>'wp_editor', 'title'=>'Текстове поле з редактором WordPress, без TinyMce', 'options'=>array('tinymce'=>0) // Список налаштувань: http://wp- kama.ru/function/wp_editor
),
],
]);
Отримаємо:
#8 Блоки з однаковими ID
Клас дозволяє створювати два та більше різних блоки з однаковими id. Наступний приклад створить 2 різних блоки метаполя яких матимуть однаковий префікс my_:
Іноді потрібно включити метабокс для однієї рубрики, але не включати інший. Для таких “пізніх” перевірок відключення метабоксу є параметр: disable_func.
У цей параметр потрібно передати назву функції, яка спрацьовуватиме перед виведенням метабоксу і відключатиме його, якщо спрацьовує описану в функції умову. Також замість назви функції можна передати анонімну функцію (замикання). Далі, якщо вказана функція щось повертає, то метабокс буде відключений.
Нині ж приклади.
1. Метабокс запису для зазначеної рубрики
Допустимо нам потрібно вивести метабокс, лише якщо запис перебуває у рубриці з ID = 2, тобто. його потрібно приховати для всіх рубрик крім 2:
2. Метабокс записи для всіх рубрик крім зазначеного
Тепер зворотний приклад: скажімо потрібно показувати метабокс, коли запис перебуває у будь-якій категорії, крім категорії 2, тобто. для категорії 2 його потрібно вимкнути.
new Kama_Post_Meta_Box( array(
'id' => 'mybox',
'title' => 'Вигляд для всіх рубрик, крім 2',
'post_type' => 'post',
'disable_func' => function($post){
if( in_category(2, $post) ) return 'відключити';
},
'fields' => array(
'fname' => array( 'type'=>'text', 'title'=>'Поле-поле' ),
),
)));
Перевірка може бути будь-якої необов’язково категорії, це можуть бути таксономії або довільні поля або ще щось.
#10 Створення своїх полів
Для створення своїх полів потрібно розширити клас Kama_Post_Meta_Box_Fields і вказати новий клас як робочий через хук kama_post_meta_box__fields_class :