Посмотрите в сторону OnTemplateGetFunctionClass, пример:
use Bitrix\Main\Event;
use Bitrix\Main\EventResult;
use Bitrix\Iblock\Template\Functions\FunctionBase;
(\Bitrix\Main\EventManager::getInstance())
->addEventHandler('iblock', 'OnTemplateGetFunctionClass', 'getFunctionClass');
function getFunctionClass(Event $event): EventResult
{
$parameters = $event->getParameters();
$functionClass = __NAMESPACE__ . '\\' . $parameters[0];
if (!class_exists($functionClass)) {
return new EventResult(EventResult::UNDEFINED);
}
return new EventResult(EventResult::SUCCESS, $functionClass);
}
class spell extends FunctionBase
{
// Вывод чисел с морфологией («рубль», «рубля», «рублей»)
// 321 {=spell 321 "товар" "" "а" "ов"} {=spell 321 "остал" "ся" "ось" "ось"} на складе
// 321 товар остался на складе
// number - свойство, содержащее число
// {=this.property.number} {=spell {=this.property.number} "товар" "" "а" "ов"} {=spell {=this.property.number} "остал" "ся" "ось" "ось"} на складе
public function calculate(array $parameters)
{
$n = intval($parameters[0]);
$word = strval($parameters[1]);
$forms[] = strval($parameters[2]);
$forms[] = strval($parameters[3]);
$forms[] = strval($parameters[4]);
$p = $n % 10 == 1 && $n % 100 != 11
? $forms[0]
: ($n % 10 >= 2 && $n % 10 <= 4
&& ($n % 100 < 10
|| $n % 100 >= 20) ? $forms[1] : $forms[2]);
return $n . ' ' . $word . ($forms[$p] ? $forms[$p] : end($forms));
}
}