В ходе работы с сайтом часто возникает необходимость поменять текст на кнопке сабмита у определённой формы. К примеру, при создании ноды Article нас не устраивает стандартный текст и мы хотим отобразить там свой. Думаю, никто не будет спорить, что задача тривиальная. Однако прежде, чем приступить, условимся, что наш сайт работает на Drupal 8, а в качестве базовой темы оформления мы используем Bootstrap 3.

При таких начальных условиях кнопки на форме создания ноды выглядят следующим образом.



Начнём решать задачу - реализуем в кастомном модуле хук hook_form_FORM_ID_alter().

/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_node_article_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (isset($form['actions']['submit']['#value'])) {
    $form['actions']['submit']['#value'] = t('My custom text');
  }
}

Ну вот, кажется задача решена, идём проверять нашу форму...



На удивление, кнопка поменяла цвет и куда-то пропала иконка. Странно...темизацию ведь не трогали, дополнительные свойства кнопке не задавали. Пробуем решить проблему в лоб - смотрим разницу в классах и добавляем недостающие классы напрямую.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function my_module_form_node_article_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (isset($form['actions']['submit']['#value'])) {
    $form['actions']['submit']['#value'] = t('My custom text');
    $form['actions']['submit']['#attributes']['class'][] = 'btn-success';
    $form['actions']['submit']['#attributes']['class'][] = 'icon-before';
  }
}


Итак, цвет вернули, но иконка от добавления класса не появится, так как является отдельным DOM-элементом, который отсутствует в случае вышеуказанных изменений. Также в нашей кнопке теперь присутствуют мусорные классы, да и "велосипед" в хуке выглядит неважно.

На самом деле всё просто! Видите ли, дело в том, что для темизации кнопок Bootstrap напрямую проверяет в тексте кнопки наличие определённого текста или слова. Магия кроется в методах cssClassFromString() и glyphiconFromString() класса Bootstrap в файле src/Bootstrap.php. Первый отвечает за цвет, а второй - за иконку. Внимательно изучив код методов, можно видеть, что они вызывают хуки hook_bootstrap_colorize_text_alter() и hook_bootstrap_iconize_text_alter() соответственно. Реализовав данные хуки в подтеме, можно подсказать Bootstrap, какой цвет и иконку использовать для нужной кнопки. В корне темы присутствует файл bootstrap.api.php, в котором описано назначение хуков и приведены их примеры.

Перейдём в основной файл подтемы и реализуем вышеуказанные хуки.

/**
 * Implements hook_bootstrap_colorize_text_alter().
 */
function my_theme_bootstrap_colorize_text_alter(&$texts) {
  $texts['matches'][t('My custom text')->render()] = 'success';
}
 
/**
 * Implements hook_bootstrap_iconize_text_alter().
 */
function my_theme_bootstrap_iconize_text_alter(&$texts) {
  $texts['matches'][t('My custom text')->render()] = 'ok';
}


Получаем красивое и элегантное решение без "велосипедов".

Комментарии

А почему t(...)->render()?

Андрей Тымчук
Это позволяет учитывать переводы текста на кнопке.

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