В ходе работы с сайтом часто возникает необходимость поменять текст на кнопке сабмита у определённой формы. К примеру, при создании ноды 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()?