1. Вступление
Мы уже писали о том, что в Joomla! 3.1 будет интегрирована новая система тегов, включающая следующие ключевые моменты:
- Мультиязычность
- Структура вложенных тегов
- Интеграция во все базовые компоненты
- Режим тегов (AJAX или вложенность)
- Создание тега на лету
- Легкая интеграция в любое расширение
Теги – это то, чего так не хватало в Joomla!
Мой (Roberto Sergua) вклад в сиситему тегов состоит в AJAX поле "tag" (тег). Имея опыт работы с другими системами тегов, я установил следующие требования к этому полю:
- AJAX поиск тега
- Вставка своего тега нажатием кнопок ENTER или ЗАПЯТАЯ
- Использование в качестве основы jQuery плагин chosen
- Не редактировать напрямую плагин chosen или любую другую библиотеку для возможности обновления (исключая переводы)
Эта статья описывает новое поле, а также новые библиотеки и инструменты разработчиков, добавленные в Joomla! 3.1.
2. Основное использование
Большинство расширений будут использовать стандартный режим использования поля, поэтому сэкономим время разработчикам и сначала опишем его.
Для использования системы тегов в расширении нужно просто определить новое поле в вашем XML-файле:
<field name="tags" type="tag"
label="JTAG" description="JTAG_DESC"
multiple="true"
/>
Ключом здесь является type="tag"
. И это все. Не нужно заботиться о зависимостях. Все остальное за вас сделает система.
Вот как происходит процесс рендеринга кнопки:
- Загрузка jQuery.
- Загрузка плагина chosen.
- Загрузка плагина ajax-chosen.
- Загрузка нашего JS кода для вставки кастомных тегов.
3. Режим поля
В настройках компонента com_tags вы найдете параметр для настройки режима поля: AJAX или Вложенность.
3.1. Автоматический режим
Если вы не укажите режим поля в определении поля тега, то ваше поле будем работать согласно глобальной настройке в com_tags. По умолчанию режим установлен в AJAX.
3.2. AJAX режим
- Поле ищет теги в момент их ввода пользователем в поле тега. Для запуска поиска необходим ввод минимум трех символов.
- Поле позволяет вставку своего тега путем его написания и нажатия кнопки ENTER или ЗАПЯТАЯ.
- Все несуществующие теги, вставленные в поле, создаются на лету в базе данных.
Чтобы принудительно использовать режим AJAX, вы должны определить его следующим образом:
<field name="tags" type="tag" mode="ajax"
label="JTAG" description="JTAG_DESC"
multiple="true"
/>
3.3. Режим вложенности
- Отображает теги в иерархическом порядке
- Кастомные теги не доступны
Чтобы принудительно использовать режим вложенности, вы должны определить его следующим образом:
<field name="tags" type="tag" mode="nested"
label="JTAG" description="JTAG_DESC"
multiple="true"
/>
4. Разрешение/Запрет кастомных (своих) тегов
Существуют случаи, когда вы захотите, чтобы пользователь мог выбрать теги, но не добавлять новые. Поле включает в себя дополнительный атрибут custom
, который принуждает поле разрешать/запрещать новые теги. Так как режим вложенности не позволяет добавлять новые теги, то эта настройка работает только для режима AJAX.
Если вы не укажите атрибут custom
, то поле будет разрешать добавлять теги по умолчанию.
Для разрешения добавления тегов:
<field name="tags" type="tag" custom="allow"
label="JTAG" description="JTAG_DESC"
multiple="true"
/>
Для запрета:
<field name="tags" type="tag" custom="deny"
label="JTAG" description="JTAG_DESC"
multiple="true"
/>
5. Дополнительные инструменты для разработчиков
Для внедрения AJAX поиска с chosen я решил использовать плагин ajax-chosen созданный автором Ryan LeFevre. Я подумал, что он мог бы стать прикольным аддоном для других расширений или базовых компонентов. Все что надо было сделать, это интегрировать и модифицировать его для возможности использования кастомных значений.
Я решил интегрировать ajax-chosen в качестве библиотеки без привязки к полю тег. Следующий раздел пояснит, как использовать интеграцию ajax-chosen и как создать свою систему тегов.
5.1. ajax-chosen
Новый метод ajaxchosen был добавлен в файл libraries/cms/html/formbehavior.php. Вот его определение:
/**
* Method to load the AJAX Chosen library
*
* If debugging mode is on an uncompressed version of AJAX Chosen is included for easier debugging.
*
* @param JRegistry $options Options in a JRegistry object
* @param mixed $debug Is debugging mode on? [optional]
*
* @return void
*
* @since 3.0
*/
public static function ajaxchosen(JRegistry $options, $debug = null)
{
}
Опции, которые допустимы в объекте JRegistry $options
, являются стандартными AJAX jQuery опциями, плюс некоторые специфические опции ajax-chosen:
minTermLength
: минимальное количество символов, которое необходимо напечатать, чтобы сработал ajax вызовafterTypeDelay
: через сколько секунд после остановки написания инициализировать ajax вызовjsonTermKey
: ajax-ключ запроса при поиске (по умолчанию "term")
Я также добавил опцию селектора, в который можно передать селектор объекта DOM для его автоматической инициализации в качестве ajax-chosen поля. Например: #js-myfield
В качестве примера мы можем взять вызов, который выполняет поле tag в файле libraries/cms/html/tag.php:
// Tags field ajax
$chosenAjaxSettings = new JRegistry(
array(
'selector' => $selector,
'type' => 'GET',
'url' => JURI::root() . 'index.php?option=com_tags&task=tags.searchAjax',
'dataType' => 'json',
'jsonTermKey' => 'like'
)
);
JHtml::_('formbehavior.ajaxchosen', $chosenAjaxSettings);
Довольно просто! AJAX результаты должны быть возвращены согласно документации ajax-chosen. Для стандартных результатов формат такой:
[{"value": 3, "text": "Ohio"}]
Для сгруппированных результатов:
[{
group: true,
text: "Europe",
items: [
{ "value": "10", "text": "Stockholm" },
{ "value": "23", "text": "London" }
]
},
{
group: true,
text: "Asia",
items: [
{ "value": "36", "text": "Beijing" },
{ "value": "20", "text": "Tokyo" }
]
}]
5.2. Кастомное поле тег
Беря за основу наше определение поля тег, очень просто создать свое поле тег. Например, если мы хотим использовать поле тег в своем расширении, но не хотим загружать данные из базовых таблиц.
В качестве примеры мы возьмем систему тегов K2. Он использует свою систему тегов с поисковым параметром "q". Хелпер для поля тег будет следующим:
/**
* This is just a proxy for the formbehavior.ajaxchosen method
*
* @param string $selector DOM id of the tag field
* @param boolean $allowCustom Flag to allow custom values
*
* @return void
*
* @since 3.1
*/
public static function k2tagsfield($selector='#jform_tags', $allowCustom = true)
{
// Tags field ajax
$chosenAjaxSettings = new JRegistry(
array(
'selector' => $selector,
'type' => 'GET',
'url' => JURI::root() . 'index.php?option=com_k2&task=item.tags',
'dataType' => 'json',
'jsonTermKey' => 'q'
)
);
JHtml::_('formbehavior.ajaxchosen', $chosenAjaxSettings);
// Allow custom values ?
if ($allowCustom)
{
JFactory::getDocument()->addScriptDeclaration("
(function($){
$(document).ready(function () {
// Method to add tags pressing enter
$('" . $selector . "_chzn input').keydown(function(event) {
// tag is greater than 3 chars and enter pressed
if (this.value.length >= 3 && (event.which === 13 || event.which === 188)) {
// Create the option
var option = $('');
option.text(this.value).val('#new#' + this.value);
option.attr('selected','selected');
// Add the option an repopulate the chosen field
$('" . $selector . "').append(option).trigger('liszt:updated');
this.value = '';
event.preventDefault();
}
});
});
})(jQuery);
"
);
}
}
Конечно система тегов K2 должна возвращать теги в ожидаемом формате.
В определении нашего поля мы добавим вызов хелпера в метод getInput
:
// Get the field id
$id = isset($this->element['id']) ? $this->element['id'] : null;
$cssId = '#' . $this->getId($id, $this->element['name']);
// Load the ajax-chosen customised field
JHtml::_('tag.k2tagsfield', $cssId, $this->allowCustom());
В файле libraries/cms/form/field/tag.php вы можете найти полное определение поля тег.
6. Работа кипит
Текущая реализация поля тег может и должна быть улучшена. Предложения и вклад приветствуются. Вот мини todo список того, чем вы можете помочь нам:
- Улучшение реюзабилити функции ajaxfield
- Отображение тегов в представлениях списков базовых компонентов
- Добавление возможности добавлять теги напрямую из представлений списков базовых компонентов
- Добавление дерева вложенных тегов на лету. Вы пишите "motor/bikes/ducati" и создается полное дерево тегов.