В БУС пока нет полных рабочих примеров. Только встроенная фабрика.
Кому интересно, прошу под кат.
[spoiler]
В качестве примера возьмём простейшую функцию - аналог left из BASIC.
Она возвращает заданное количество символов с начала строки.
{=my_left this.DetailText 150} |
Префикс my_ я добавил чтобы не пересечься с будущими возможными расширениями набора встроенных функций.
А вот собственно код для файла init.php:
//Подключаем модуль инфоблоков if (\Bitrix\Main\Loader::includeModule('iblock')) { //регистрируем обработчик события \Bitrix\Main\EventManager::getInstance()->addEventHandler( "iblock", "OnTemplateGetFunctionClass", array("FunctionMyLeft", "eventHandler") ); //подключаем файл с определением класса FunctionBase //это пока требуется т.к. класс не описан в правилах автозагрузки include_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/iblock/lib/template/functions/fabric.php"); class FunctionMyLeft extends \Bitrix\Iblock\Template\Functions\FunctionBase { //Обработчик события на вход получает имя требуемой функции //парсер её нашел в строке SEO public static function eventHandler($event) { $parameters = $event->getParameters(); $functionName = $parameters[0]; if ($functionName === "my_left") { //обработчик должен вернуть SUCCESS и имя класса //который будет отвечать за вычисления return new \Bitrix\Main\EventResult( \Bitrix\Main\EventResult::SUCCESS, "\\FunctionMyLeft" ); } } //собственно функция выполняющая "магию" public function calculate($parameters) { $result = $this->parametersToArray($parameters); //последний параметр - длина строки $length = array_pop($result); //а вот собственно left return substr(implode(" ", $result), 0, $length); } } } |
Всем успехов и удачи!
P.S.
Не получается поместить такой обработчик в модуль.
При регистрации события как в примере - событие регистрируется с параметром $version=2 в /bitrix/modules/main/lib/eventmanager.php;150
А если регистрировать событие при инсталляции модуля - то событие регистрируется с параметром $version=1 в /bitrix/modules/main/lib/eventmanager.php;155
И в результате если регистрировать событие в модуле - в eventHandler прилетает $event==="function_name" которое ни разу не object и получается ошибка
Может я ошибаюсь, тогда поправьте - как правильно с помощью нового API зарегистрировать событие при установке модуля
2. Работает.
1. Заработало
2. Вы правы, работает. Это общий глюк что при настройке в инфоблоке механизм предпросмотра пытается брать указанные в шаблоне характеристики из инфоблока (где их нет). Было бы здорово если бы при настройке в инфоблоке для предпросмотра результата использовались первые секции/элементы соответственно.
удобногокрасивого(А вот сегодня меня посетила мысль, что можно сделать выбор элемента/раздела для предпросмотра.
Пусть даже его значение (пока) не будет схораняться, но это будет намного лучше чем ничего.
calculate к нему не применим.
Механизма расширения "объектов" пока не предусмотрено.
PS можно подумать над этим.
Ну и в идеях написал по поводу расширения возможностей —
\Bitrix\Main\EventManager::registerEventHandler - не работает
А как еще заставить отдавать строку текстом без entities, html_entity_decode - не сильно помогает.
В коде страницы все равно вылазит.
А если в форме редактирования вставить тот же текст (форматированный) - то все хорошо, не преобразует.
Зачем?
SEO-возможности это инструмент, который на достаточно низком уровне дает функциональность работы над полями. Высокоуровневных возможностей в нем мало.
Мы выпустили модуль в МП для них.
Возможность применения пользовательских функций при заполнении SEO-полей — это здорово, приятно, красиво. И очень нужно SEOшникам.
Осталось только написать сами функции, что мы и сделали.
Представляем вашему вниманию новый модуль в маркетплейсе —
После установки
1. Удаление html-сущностей
Иногда при использовании в seo-шаблоне анонсного или другого поля с html внутри мы можем увидеть следующую картину. Html-сущности не интерпретируются и портят всю красоту текста.
Для удаление тегов в данном случае нужно использовать функцию iv_strip:
Пример: {=iv_strip this.PreviewText}
Результат:
2. Условие Если — то — иначе
С нашими SEO-фильтрами вы можете предотвратить ситуацию, когда одно из свойств окажется незаполненным.
Пример: {=iv_ifelse this.property.FREE_DELIVERY "Free delivery: #" "No free delivery" }
Первый аргумент — тестируемое свойство (пусто/не пусто). Второй — что вывести в случае если условие не пусто (можно использовать # чтобы подставить значение самого свойства. Третий аргумент — что вывести в случае, если условие пусто.
3. Ограничение длины выводимого текста по символам
Мы помним, что в поле “description” (как рекомендует Яндекс) следует размещать не более 150 символов. Остальные не учитываются. Пользуйтесь на здоровье, у нас есть SEO-фильтр #PRO.
Ограничение длины выводимого текста применяется для символов, а не по словам, как в стандартном фильтре limit. При этом не режутся слова, те выводятся слова до тех пор пока итоговая длина не станет больше указанной
Пример: {=iv_limit_chars this.PreviewText 20}
4. Округление числа и округление цены
Так как цена — это не просто число, но и валюта, и разделитель целой/дробной части, разделитель разрядов, итд, мы учитываем эти настройки при ее округлении. То есть, из текста получаем числовое значение цены, его округляем в соответствии с указанным правилом, потом опять “оборачиваем” в текст.
Настройки следует применять аккуратно, чтобы не ввести никого в заблуждение)
4.1. Классическое
Пример: {=iv_round this.property.INT_PROPERTY 2}
4.2. Округление числа в меньшую сторону
Пример: {=iv_floor this.property.INT_PROPERTY}
4.3. Округление числа в большую сторону
Пример: {=iv_ceil this.property.INT_PROPERTY}
4.4. Округление цены (учитываются настройки валют в соотв. модуле)
Пример: {=iv_round_price this.catalog.price.BASE 0}
4.5. Округление цены в меньшую сторону
Пример: {=iv_floor_price this.catalog.price.BASE}
4.6. Округление цены в большую сторону
Пример: {=iv_ceil_price this.catalog.price.BASE}
Я так понимаю стандартным функционалом нельзя. А как можно с программным вмешательством ?
К примеру, такой шаблон
сейчас я получаю массив из двух параметров: первый Название фирмы, а второй пустая строка.
функцию вызывают так (на вкладке SEO, поле заголовок элемента)
class
FunctionBondsoftPriceFormatFunctionMyPriceFormat extends \Bitrix\Iblock\Template\Functions\FunctionBaseВ функцию addEventHandler вы передаёте именно "FunctionMyPriceFormat", а не "FunctionBondsoftPriceFormat"
2. параметры функции calculate желательно обработать. Например:
Хотелось бы немного доработать. чтобы при отсутствии описания добавлять стандартный сео шаблон в виде "имя_раздела имя_элемента в нашем интернет-магазине"
p.s.: Понял, что берётся просто описание из главной страницы сайта (заданное в .section) только не понял почему наследуется на внутреннюю папку (/catalog/) ну да фиг с ним. получается что если описания нет, функция ничего не выводит (оставляет пустой тег). а в шаблоне каталога, видимо, настроено что сео обновляется только если свойство заполнено... так что главный вопрос остался актуален.
public function calculate(array $parameters)
И получается $result = $this->parametersToArray($parameters); не обязательно? Или у нас может быть массив массивов, которые надо разложить на простой массив?
Минимальная и максимальная цена.
Еще тернарная операция с проверкой на пустоту
Сейчас в инфоблоке iblock_element_property.70 есть свойство типа строка с разными значениями веса изделия, например, 0.12, 1.12 и т.д.
Т.е. если есть свойство инфоблока iblock_element_property.70 и его значение меньше числа 0.30, то выводить значение свойства PROPERTY_183. если больше либо равно 0.30, то выводить значение другого свойства PROPERTY_184 из другого инфоблока, как это реализовать в пользовательской функции, зарегистрировать обработчик события этой функции в файле init.php и использовать ее в шаблоне?