Имеется: сайт на Друпале, где опубликованные материалы могут комментировать незарегистрированные пользователи.
Задача: отображать Gravatar аватары в этих самых комментариях.
Ну, вроде ничего сложного. Однако из "коробки" (включая контрибные модули) у Drupal 8 сей фукнционал отсутствует.
Раньше (для Drupal 7, Drupal 6 и, если не изменяет память, для Drupal 5 тоже) был такой прекрасный модуль, как Gravatar integration, которым я все эти годы и пользовался.
Однако, дальнейшая поддержка этого модуля была прекращена, как и не будет порта на восьмерку. Нет, он не "забросился", а просто наравне с другими мелкими утилитарными модулями (User Pic Kit тот же) объединился в единый Avatar Kit. Ну и прекрасно.
Проблема только в том, что этот новый Avatar Kit оперирует исключительно зарегистрированными пользователями. Назначать какие-то аватары анонимным пользователям - нельзя. И это не баг, это фича. Ответ разработчика в соответствующей ветке на гитхабе:
Normally the picture field is filled with a picture for each user, but this can be a problem since anonymous aren't 100% users. The anonymous user also represents more than one person.
As an alternative, you can upload a picture to be the default image. But this picture will not vary per piece of anonymous submitted content.
Ок, надо писать модуль самому, получается. С другой стороны - это же своего рода темизация, тогда может лучше через эту самую темизацию и сделать, средствами темы.
Ну, темизация так темизация, так даже проще.
Смотрим, где там препроцессятся комментарии. В template_preprocess_comment. Отлично.
Идем в нашу тему, открываем файл MYTHEME.theme (или создаем, если его нет), добавляем следующее:
function MYTHEME_preprocess_comment(&$variables) {
$variables['author_email'] = '';
}
Так, ну что значит $variables['author_email'] - понятно, конечно. Таким образом мы добавляем новый элемент, который потом можно будет вставить в шаблон Twig-a через {{ author_email }}.
Непонятно другое, откуда нам e-mail автора взять, и где он вообще лежит? В документации нигде не сказано, нагуглить тоже не получается. Ок, включаем модуль Devel (не забывая также включить в настройках еще и поддержку Kint - так удобней) - и смотрим, что там вообще в этом $variables есть. Для этого модифицируем ранее добавленный код:
function bartik_preprocess_comment(&$variables) {
kint($variables);
$variables['author_email'] = '';
}
Чистим кэш, переходим на нашем сайте на любой опубликованный материал, где есть хотя бы один комментарий, и смотрим что там нам вывелось:
А вывелось много всего, аж глаза разбегаются. Кликаем на разные табы, свойства/методы, через Ctrl+F ищем что-нибудь с вхождением "email" - и наконец-то находим, элемент 'comment' Drupal\comment\Entity\Comment имеет публичный метод getAuthorEmail(). Судя по названию - то, что нужно.
К слову, Kint способен неплохо так "подвесить" компьютер, можно чуть уменьшить уровень глубины тогда, до куда он смотрит в $variables, по умолчанию стоит семерка (в файле с модулем Devel, Devel/kint/kint/config.default.php):
/** @var int max array/object levels to go deep, if zero no limits are applied */
$_kintSettings['maxLevels'] = 7;
Чем меньше значение - тем быстрее, что логично. Хотя иногда и приходится смотреть сильно "вглубь", но это иногда. Для наших текущих задач, например, четверочки - за глаза.
Правим код дальше:
function bartik_preprocess_comment(&$variables) {
$variables['author_email'] = md5(strtolower($variables['comment']->getAuthorEmail()));
}
Вызов Kint-a удалили, получили e-mail, привели его к нижнему регистру (у меня почему-то в базе емэйлы иногда с прописной записаны, может бага какая), ну и взяли от всего этого md5 хэш, который и нужен для Граватара.
Ок, теперь на руках вроде есть все, что надо. Идем править шаблоны Твига. Так, а какой вообще править-то? Опять дебажить, ну что за жизнь...
Идем в папку sites/default, ищем там файлик default.services.yml, создаем его копию в той же папке, переименовываем в просто services.yml (хотя если Друпал 8 "старый", то, возможно, этот переименованный файл уже существует - т. к. сие было раньше одним из требований при установке, теперь уже нет). Создали, переименовали, открываем. Ищем параметры дебаггера Твига, заменяем false на true:
twig.config:
# Twig debugging:
# @default false
debug: true
На продакшене это должно быть выставлено в false, что понятно.
В общем, поставили в true, обновили кэш, и открываем страничку нашего сайта с комментариями, запускаем DevTools, смотрим появившиеся комментарии к коду к нашим комментариям:
Так, comment.html.twig, получается. Логично.
Открываем этот самый comment.html.twig файл в папке с нашей темой. Если его нет - копируем из родительской темы, которая обычно Classy (classy/templates/comment.html.twig). Хотя можно и прямиком из ядрышка взять, /modules/comment/templates/comment.html.twig.
Открыли, значит, и редактируем. Ищем где там {{ user_picture }} и ниже/заместо вставляем код нашей аватарки:
{{ user_picture }}
<img src="https://www.gravatar.com/avatar/{{ author_email }}?d=mm&s=55" />
{{ author_email }} - это как раз то, что мы препроцессили в MYTHEME.theme файле. Вообще, все эти проблемы из-за необходимости брать md5 хэш, потому что напрямую взять в Твиге емэйл комментатора - без проблем. А вот функции хэширования недоступны (во всяком случае из коробки, хотя соответствующие плагины под разные фреймворки вроде как и есть).
Аргументы в конце ?d=mm&s=55 взяты из официальной документации Граватара, задают тип аватарки и ее размер.
К слову, если e-mail у некоторых комментаторов будет отсутствовать (поставили в настройках, что пользователь не обязан оставлять e-mail, например), то md5() будет браться от пустой строки, но это не проблема - Граватар в этом случае отдаст ожидаемую дефолтную заглушку.
Ну, вроде все сделали правильно. Идем проверять. Оставляем анонимный комментарий с валидным почтовым адресом, аватарка должна появиться.
Появилась! Ну что же, issue successfully closed.
PS
Пока писал пост, наткнулся на буквально недавно вышедший модуль Anonymous Comment User Info, который видимо таки добавляет возможность использовать кастомные аватары для анонимных пользователей. Но потестировать не получилось - требует PHP 7.1. А у меня на продакшене пятерка стоит, а на деве 7.0. Обновлять версию пхп ради этого прямо сейчас - желания нет никакого. Но вообще рано или поздно придется. Как минимум до шестого марта 2019-го года, когда Друпал уже официально перестанет поддерживать 5.x. Ну а пока и так сойдет.