Шорткод в WordPress

Шорткод (шоткод, shortcode, короткий код) WordPress — це конструкція в тексті, яка буде оброблена і замінена на вказаний код/текст. Обробляється шорткод спеціальною PHP функцією, вказаною під час реєстрації шорткоду.

Shortcode API — це набір простих функцій, які дозволяють розробникам тем і плагінів створювати свої шорткоди, які можна використовувати в контенті для виведення готових блоків контенту. Наприклад, це може бути форма контактів.

Наприклад, наступний Шорткод (у контенті запису) додасть фотогалерею:

У контенті обробляються лише відомі (зареєстровані в WordPress) шорткоди, тому що не можна обробляти всі конструкції виду [*], оскільки вони можуть бути використані в тексті або HTML. Тому:

 - буде перетворено, тому що шорткод зареєстровано

[no_name] - не буде перетворено, тому що шорткод не зареєстрований
Шорти можуть викликатися по-різному: 
[name]“self-closing” Одиночний шорткод без параметрів.
[name id=”123″ size=”medium”]“self-closing” Одиночний з параметрами.
[name]текст[/name]“enclosing” Контентний шорткод без параметрів. Отримує текстяк параметр.
[name size=”medium”]текст[/name]“enclosing” Контентний шорткод з параметрами.

Відео про шорткоди в WordPress:


Список шорткодів WordPress

У WordPress за замовчуванням реєструються такі шорткоди:


Синтаксис шорткоду

Шорткоди WordPress використовують Квадратні дужки [], тому що вони не є частиною будь-якої мови. Синтаксис виглядає так:

[name]

[name /]

[name attribute="value" /]

[name attr1='value1' attr2="value2" ]

[name]Контент шорткоду.[/name]

[name attr="value"]Контент шорткоду.[/name]

Самозакриття (self-closing)

Шорткод можна закрити слешем в кінці (такий слеш називається self-closing маркером).

[example /]

Пробіл перед маркером необов’язковий. Прогалини після маркера не допускаються. Такий маркер є суто косметичним і ні на що не впливає.

Контентні шорткоди не можуть використовувати self-closing маркер.


Ім’я шорткоду

Ім’я шорткоду не може містити такі символи [ ] < > & / ' " - x00-x20 s n t:

  • Квадратні дужки:[]
  • Кутові дужки:< >
  • Амперсанд:&
  • Коса риска:/
  • Невидимі символи: пробел, перевод строки,tab
  • Недруковані символи:x00 - x20
  • Лапки:' "

Тире -дозволяється у назві шорткоду і вона не викликає жодних конфліктів! Однак в офіційній документації сказано, що можуть бути конфлікти – це застаріла інформація.


Атрибути шорткоду

Атрибути вказувати не обов’язково, між ім’ям та атрибутами потрібна як мінімум одна прогалина. Якщо вказується кілька атрибутів, кожен атрибут повинен бути розділений принаймні одним пропуском.

Кожен атрибут повинен відповідати одному з цих форматів:

[name attribute = 'value']

[name attribute = "value"]

[name attribute = value]

[name "value" "value2"]

[name "value"]

[name value]

Пробіл допускається до та після знака =: attr = value, attr= value, attr =value.


Ім’я атрибуту

Може містити лише такі символи: 0-9 A-Z a-z _ -(пробіли в іменах заборонені):

  • Великі та малі літери: A-Za-z.
  • Числа: 0-9.
  • Нижнє підкреслення: _.
  • Дефіс: -.

Ім’я атрибуту може бути у будь-якому регістрі. Після парсингу ім’я завжди буде в нижньому регістрі: aTtR=valueтеж те, що і attr=value.


Значення атрибуту

Значення атрибута не може містити наступні символи [ ] " '.

Нотатки за значенням атрибута:

  • Лапки атрибута . Подвійні лапки "допускаються всередині значень в одинарних лапках 'і навпаки:[name foo='1 "2" 3' bar="4 '5' 6"]

  • Лапки атрибута . Конструкція шорткоду може використовувати подвійні або одинарні лапки для виділення значень атрибута, або взагалі їх не використовувати, якщо значення не має пробілу. [name foo='123' bar=456]теж що і [name foo="123" bar="456"].

  • Атрибут без імені . Ім’я атрибута не можна вказувати. У цьому випадку ім’я атрибута буде індексом масиву $atts . Наприклад [name 123], створить такі параметри: $atts = array( 0 => 123 ). Такі «позиційні» атрибути можна використовувати разом із звичайними, а лапки можна використовувати, коли значення містить пробіли або інші незвичайні символи.

  • Квадратні дужки . Так не можна: [name foo="[value]"].

  • Екранувати спец-символи в атрибутах можна за допомогою кодування HTML символів (HTML encoding).

  • HTML символи <та> підтримуються в атрибутах обмежено. Наприклад, цей шорткод не буде правильно працювати через символ > :

    [name value1="35" value2="25" compare=">"]

    Версія 4.0 вміє перевіряти HTML, так що наступний код працюватиме:

    [name description="<b>Greetings</b>"]

    Щоб повністю підтримувати HTML в атрибутах можна, спочатку кодувати значення, що вводяться користувачем, а потім декодувати при обробці.

  • Символи , що видаляються . Наступні символи, якщо вони не екрановані, будуть:

    • Нерозривний пробіл (No-break space): xC2xA0– Заміниться пробілом.
    • Безрозмірний Пробіл (Zero-width space): xE2x80x8B– Видалити.


Екранування

Екранування потрібне, коли шорткод зареєстрований, але його не потрібно обробляти, а потрібно показати як є. Не зареєстрований шорткод і так не оброблятиметься.

Для екранування потрібно обрамити шорткод ще одними квадратними лапками:

[[name attributes]]

[[name attributes]Будь-який HTML або Шорткоди.[/name]]

Інший варіант: замінити символи []їх HTML сутності &#91; &#93;. Наприклад [name], можна записати так: &#91;name&#93;.


Вкладені шорткоди

Парсинг шорткодів спрацьовує один раз для контенту. Це означає, що якщо в Контентному шорткоді є вкладений шорткод, він не буде оброблений:

[name]Foo: [my_name][/name]

Обробиться так:

<span class="caption">Foo: [my_name]</span>

Однакова назва

Парсер не зможе опрацювати вкладені шорткоди з однаковою назвою, тому що рівень вкладеності не підраховується. Таке обмеження прискорює обробку шорткодів:

[tag_a]
   [tag_a]
   [/tag_a]
[/tag_a]


Як це працює

При додаванні шорткоду через add_shortcode() шорткод додається до глобальної змінної $shortcode_tags (додається ім’я та функція-обробник).

На хуку do_shortcode() , яка шукає та обробляє всі шорткоди у контенті.

Усі знайдені шорткоди по черзі передаються у функцію do_shortcode_tag() . Ця функція обробляє дані знайдені регулярним і викликає додану в $shortcode_tags функцію-обробник шорткоду (з параметрами $attr, $content, $tag ).

Те, що повернула функція-обробник замінять шорткод у контенті.

До спрацювання функції do_shortcode() (до парсингу шорткодів) контент обробляється трьома ключовими функціями:

add_filter( 'the_content', 'do_blocks', 9);
add_filter( 'the_content', 'wptexturize');
add_filter( 'the_content', 'wpautop');

add_filter( 'the_content', 'do_shortcode', 11); // AFTER wpautop().

do_shortcode() парсить контент одним регулюванням get_shortcode_regex() , тому додавання ще одного шорткоду ніяк не уповільнює швидкість обробки – регулювання все одно буде відпрацьовувати.


Створення шорткоду

Для створення шорткоду використовується функція add_shortcode() . Вона приймає два параметри: ім’я шорткоду та назву PHP функції, яка оброблятиме шорткод.

Ось найпростіший PHP-код, який реєструє новий шорткод [foobar]:

add_shortcode('foobar', 'foobar_shortcode');

function foobar_shortcode( $atts ){
	return 'Привіт! Я шорткод.';
}

Тепер [foobar] у контенті запису змінюватиметься на рядок: «Привіт! Я шорткод.


Атрибути шорткоду

Давайте додамо підтримку атрибутів шорткоду з прикладу вище. Для цього використовуємо функцію shortcode_atts() :

add_shortcode('foobar', 'foobar_shortcode');
function foobar_shortcode( $atts ) {

	$atts = shortcode_atts([
		'name' => 'Noname',
		'age' => 18,
	], $ atts);

	return "Мене звуть {$atts['name']} мені {$atts['age']} років";
}

Тепер [foobar name="Виктор" age="25"]у контенті змінитись на рядок: «Мене звуть Віктор мені 25 років».

shortcode_atts() визначає які у шорткоду можуть бути атрибути, задає їм дефолтні значення та видаляє непізнані атрибути.

shortcode_atts($defaults, $atts);
$defaults

Асоціативний масив, який описує можливі атрибути шорткоду (це ключі масиву) та їх дефолтні значення.

ВАЖЛИВО! Ключі масиву $defaults мають бути у lower-case . Не використовуйте camelCase або UPPER-CASE , тому що в $atts ключі завжди у lower-case .

$atts

Неочищений масив з даними, що були вказані у шорткоді. Вони порівнюватимуть із масивом вище.

$atts міститиме масив аргументів шорткоду, які були вказані користувачем.

Якщо вказати значення без назви параметра, вони будуть додані в індексні елементи масиву. Наприклад для шорткоду [name value attr="val2" val3]отримаємо:

Array (
	[0] => value
	[attr] => val2
	[1] => val3
)

Імена атрибутів (ключі масиву $atts ) завжди конвертуються на lower-case (нижній регістр), значення не обробляються. Наприклад, якщо ми вказали шорткод так [myshortcode FOO="BAR"], то $atts отримаємо [ 'foo' => 'BAR' ].

Розглянемо ще один приклад.

Нехай ми вказали у контенті шорткод [myname foo="456" bar="something"]. Тоді:

add_shortcode( 'myname', 'my_shortcode_handler' );

function my_shortcode_handler( $atts ) {

	/*
	$atts = [
		'foo' => 456,
		'bar' => 'something'
	]
	*/

	$ data = shortcode_atts ([
		'title' => 'My Title',
		'foo' => 123,
	], $ atts);

	/*
	$ data = [
		'title' => 'My Title',
		'foo' => 456
	]
	*/
}

З коду видно, що ми прийняли одні дані, а отримали після обробки інші. Що змінилося?

  • Отримане значення $atts[‘foo’] перезаписувало значення за промовчанням.
  • Отриманий елемент $atts[‘bar’] був видалений, тому що його немає у списку можливих аргументів.
  • Недостатній елемент $atts[‘title’] був доданий за замовчуванням.


Виведення функції оброблювача

Значення функції обробника шорткоду, що повертається, вставляється в контент запису замість самого шорткоду.

Результат функції-обробника шорткоду завжди повинен повертатись, а не виводитися на екран. Використовуйте return, а не echoфункції обробника.

Буфіризація висновку

Якщо в шорткоді використовується багато HTML коду, для зручності можна використовувати функцію ob_start() , щоб буферизувати висновок і потім його повернути:

function my_shortcode(){
	ob_start();

	?> <HTML> <here> ... <?php

	return ob_get_clean();
}


Контентні шорткоди

Приклади вище показували як створювати одиночні (self-closing) шорткоди: [name]. Але крім них є ще «контентні» (enclosing) шорткоди: [name]Контент[/name].

Для Enclosing шорткоду функція-обробник отримає другий параметр, що містить контент.

function my_shortcode( $atts, $content )

Зареєстрований шорткод завжди можна використовувати як одиночний або контентний, тому при реєстрації шорткоду бажано завжди вказувати значення за промовчанням для другого параметра $content .

Або можна використовувати перевірку empty( $content )для поділу обробки даних Контентного та Одиночного шорткодів. Тобто. виходить один шорткод можна використовувати як два різні, залежно від того, як він був використаний.

Розглянемо приклад:

add_shortcode( 'name', 'my_shortcode' );

function my_shortcode( $atts, $content ) {
	return '<span class="caption">' . $content . '</span>';
}

Тепер якщо написати шорткод так:

[name]My Caption[/name]

Отримаємо такий результат:

<span class="caption">My Caption</span>

$content передається в функцію без будь-якої очистки, тому в ньому може бути HTML:

[name]<a href="<a class="external" href="http://example.com/" rel="nofollow">http://example.com/</a>">My Caption< /a>[/name]

Отримаємо:

<span class="caption">
	<a href="http://example.com/">My Caption</a>
</span>

Іноді навпаки, коли HTML неприпустимо, потрібно очищати висновок, видаляючи всі HTML теги функцією wp_strip_all_tags() .

Атрибути у Контентному шорткоді

У Контентному шорткоді можна як і в Одиночному, вказати атрибути. Наприклад дозволимо атрибут class :

function my_shortcode( $atts, $content ) {

	$ data = shortcode_atts ([
		'class' => 'caption',
	], $ atts);

	return '<span class="' . esc_attr( $a['class'] ) . '">' . $content . '</span>';
}

/*
[name class="headline"]My Caption[/name]

<span class="headline">My Caption</span>
*/

Вкладені шорткоди

Якщо у Контентному шорткоді є вкладений шорткод, він не буде оброблений.

[tag_a]
   [tag_b size="24"]
	  [tag_c]
   [/tag_b]
[/tag_a]

Тому якщо все ж таки потрібно обробити шорткод всередині шорткоду, то при обробці контенту першого шорткоду, потрібно використовувати функцію do_shortcode() , щоб обробити вкладені шорткоди.

function my_shortcode( $atts, $content ) {
	return '<span class="caption">' . do_shortcode($content). '</span>';
}


Видалення шорткоду

Для видалення (де-реєстрації) використовується Функція remove_shortcode($name) .

Для видалення шорткоду з контенту є функція strip_shortcodes($content)

Видаляти шорткод потрібно після того, як він був доданий, тому викликати цю функцію краще під час події init .

Для прикладу, давайте уявімо, що плагін реєструє шорткод [awesome], а нам він заважає. Видалимо його так:

add_action( 'init', 'unregister_shortcodes', 20);
function unregister_shortcodes(){
	remove_shortcode('awesome');
}

Також у Shortcode API є функція, яка видаляє всі зареєстровані шорткоди разом: див. remove_all_shortcodes() .


PHP Функції

add_shortcode()Додає новий шоткод та хук для нього.
shortcode_atts()Обробляє атрибути (параметри) шорткоду: додає значення за промовчанням, коли потрібно і видаляє невідповідні атрибути.
remove_shortcode()Видаляє зареєстрований шорткод.
remove_all_shortcodes()Видаляє всі зареєстровані шоткоди.
do_shortcode()Знаходить у переданому тексті зареєстровані шорткоди та обробляє їх.
apply_shortcodes()Це нова назва (аліас) функції do_shortcode() .
has_shortcode()Перевіряє чи в переданому тексті вказаний шоткод.
shortcode_exists()Перевіряє, чи зареєстрований вказаний шоткод.
strip_shortcodes()Видаляє/вирізує всі шоткод з переданого тексту (контенту).

Повний перелік функцій .


нотатки

wpautop

Шорткод обробляються після того, як контент запису буде оброблений функцією wpautop() . Тому рядок, що повертається з функції-обробника вже не буде оброблятися цією функцією.

wpautop() розпізнає зареєстровані шорткоди та не обробляє їх (не додає p або br теги навколо або всередині).

wptexturize

Шорткод обробляються після того, як контент запису буде оброблений функцією wptexturize() . Вона обробляє незареєстровані шорткоди як звичайний текст і замінює в ньому лапки.

Щоб цього не відбувалося, шорткод можна обернути в тег <code> або <pre> . Текст усередині цих тегів wptexturize() не обробляє. Приклад:

[name attr=“value”]

<code>[name attr="value"]</code>

Або можна додати шорткод до списку шорткодів, що не-текстуруються. Робиться це через хук no_texturize_shortcodes .

Різні функції для одного шорткоду

Якщо зареєструвати два шорткоди з однаковими назвами, але різними функціями-обробниками, то застосовуватиметься остання функція. Тобто. спрацює шорткод доданий останнім.

add_shortcode( 'name', 'name_shortcode' );
add_shortcode( 'name', 'noname_shortcode' );

function name_shortcode(){
	return 'name shortcode';
}

function noname_shortcode(){
	return 'noname shortcode';
}

/*
[name] у контенті виведе рядок "noname shortcode"
*/

Одна функція для різних шорткодів

add_shortcode( 'foo', 'my_function');
add_shortcode('bar', 'my_function');

Якщо два шорткоду використовують одну і ту ж функцію-обробник, то в коді можна отримати назву (ім’я) поточного шорткоду – воно передається в функцію-обробник у третьому параметрі:

function my_shortcode( $attr, $content, $tag ){

	if( 'foo' === $tag ){
		// Обробка шорткоду [foo]
	}

	elseif( 'bar' === $tag ){
		// Обробка шорткоду [bar]
	}

}

Змішаний виклик одного шорткоду

Парсер не вміє обробляти змішаний виклик одного шорткоду, коли він викликається як Self-closed та Enclosing. Наприклад:

[name attr='non-enclosing' /] просто текст [name]текст шорткоду[/name]

Замість того, щоб розпарити цей рядок як два шорткоду розділені рядком просто текст. Парсер зрозуміє це як єдиний контентний шорткод із текстом просто текст [name]текст шорткода.

Незареєстровані шорткоди

Деякі автори плагінів не реєструють шорткод, наприклад, щоб вимкнути вкладений шорткод доти, доки не буде викликана функція оброблювача батьківського шорткоду. Це може призвести до того, що шорткоди стануть неробочими. Наприклад:

[tag_a unit="north"]
   [tag_b size="24"]
	  [tag_c color="red"]
   [/tag_b]
[/tag_a]

Якщо не реєструвати шорткод tag_bі tag_c, то wptexturize() перетворить код на наступний, ще до того як шорткод tag_aбуде оброблений:

[tag_a unit="north"]
   [tag_b size=”24”]
	  [tag_c color=”red”]
   [/tag_b]
[/tag_a]

Незареєстровані шорткоди будуть вважатися звичайним текстом, який не має особливого значення. Щоб шорткод мав значення для wptexturize(), його можна додати до списку через хук no_texturize_shortcodes :

add_shortcode('tag_a', 'my_tag_a_handler');
add_filter( 'no_texturize_shortcodes', 'ignore_tag_a');

function ignore_tag_a( $list ) {
	$list[] = 'tag_a';
	return $list;
}

Незакриті шорткоди

У деяких випадках аналізатор шорткодів не може коректно працювати з одним шорткодом, який використовується як одиночний і контентний шорткод. Наприклад, у цьому випадку синтаксичний аналізатор правильно ідентифікуватиме тільки другий екземпляр шорткоду:

[tag]
[tag]
   CONTENT
[/tag]

Однак так проаналізує обидва:

[tag]
   CONTENT
[/tag]
[tag]

Шорткод в атрибуті HTML тега

Починаючи з версії 4.2.3, були накладені обмеження на використання шорткодів усередині HTML тегів. Наприклад, наступний шорткод не працюватиме коректно, оскільки він вкладений в атрибут скрипту:

<a onclick="[tag]">

Обійти це можна, створивши шорткод, який виводить весь необхідний HTML, а не тільки одне значення.

[link onclick="tag"]

Тести Shortcode API

Тести з цікавими прикладами помилок та незвичайного синтаксису можна знайти за цим посиланням: https://unit-tests.svn.wordpress.org/trunk/tests/shortcode.php

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *