Drupal → Простая вставка в текст динамического контента (без использования PHP filter)

08.10.2016

Часто нужно вставить в середину содержимого ноды или блока какой-нибудь контент, сгенерированный с помощью php, например вьюху или переменную. Для решения задачи можно либо вывести контент используя php фильтр, либо сделать str_replace() в preprocess функции, либо накидать простой текстовый фильтр, заменяющий токены [function:function_name] на результат выполнения функции:

/**
 * Implements hook_filter_info().
 */
function modulename_filter_info() {
  $filters['token_function'] = array(
    'title' => t('Replace [function:*] to function result'),
    'process callback' => 'modulename_filter_process',
    'cache' => FALSE,
  );

  return $filters;
}

/**
 * Filter process callback.
 */
function modulename_filter_process($text, $filter, $format, $langcode, $cache, $cache_id) {
  $text = preg_replace_callback('/\[function:(.+?)\]/', function ($matches) {
    $token_params = explode(':', $matches[1]);
    $function = 'token_function__' . preg_replace('/[^a-z0-9_]/', '', $token_params[0]);

    if (function_exists($function)) {
      $arguments = isset($token_params[1]) ? explode(',', $token_params[1]) : array();
      return call_user_func_array($function, $arguments);
    }

    return $matches[0];
  }, $text);

  return $text;
}

Использование:

1. Включить фильтр в настройках нужного текстового формата.

2. Написать функцию с префиксом token_function__, например:

function token_function__current_date($format = 'r') {
  return date($format);
}

3. Добавить в текст токен в формате [function:FUNCTION_NAME], например [function:current_date].

Profit.

Дополнения:

Передать аргументы в функцию можно третьим параметром через запятую [function:FUNCTION_NAME:ARG1,ARG2], например [function:current_date:d.m.Y].

Для фильтра лучше создать отдельный текстовый формат, которым сможет пользоваться только администратор и только в определённых нодах/блоках, так как фильтр отключает кэширование текста, прошедшего через формат.

Код доступен в виде модуля (есть версия для Drupal 8).

Написанное актуально для
Drupal 7
Похожие записи

Комментарии

Андрей
09.01.2018, 18:54

Приветствую, всемогущий :)
Пример рабочий, сомнений нет. Дату выводит красиво ровно там, где стоит токен. Но вот мне нужна не дата, а содержимое обычного блока и я меняю функцию

function token_function__current_date($format = 'r') {
  return date($format);
}

на

function token_function__block_8() {
  $block = module_invoke('block', 'block_view', '8');
  print render($block['content']);
}

и тут возникает проблема. Содержимое токена(блока) выводится не в нужном месте, а сразу после открывающего тега body.

Прошу помощи в решении. Спасибо.

Андрей
09.01.2018, 18:59

Гениально! Сработало :) Спасибо, большое.

Гость
24.05.2018, 11:02

[function:webform:70] - не работает
[function:webform:70,true] - работает

Добавить комментарий