Drupal → Мои Best Practices

15.02.2015

Мои лучшие практики при разработке сайтов на друпале:

  1. Добавляю в машинные имена полей название бандла, например — field_news_image вместо field_image. Исключение для полей, которые используются одновременно в нескольких бандлах.

  2. Избегаю использование одного поля в разных бандлах. Т.е. вместо одного поля field_image на несколько бандлов, создаю в каждом бандле по полю field_bundle_image. Но конечно многое зависит от архитектуры, бывают и исключения.

  3. Машинные имена multi-value полей пишу в единственном числе, например field_image вместо field_images. Бывают случаи когда в ходе разработки приходится делать поле single-value, и "s" на конце начинает резать глаз.

  4. Машинные имена словарей в единственном числе — category, tag.

  5. В каждом друпал сайте есть custom модуль с именем custom_main, в который складываются служебные функции, реализации хуков, альтер-функции и так далее.

  6. Если какой-то функционал требует 3-4 функции в модуле custom_main, то он выносится в отдельный custom модуль.

  7. Если custom модуль будет использоваться только на текущем сайте, то в имя модуля добавляется префикс custom_, чтобы не заморачиваться с выбором имени и возможными конфликтами. Пример таких модулей — custom_checkout или custom_profile.

  8. Custom модули создаются одной drush командой — vendor/bin/drush generate module.

  9. Как понятно из прошлого пункта — drush, drush и ещё раз drush. Основные кейсы — включение модулей, создание модулей, запуск update.php.

  10. Модули рассортированы по подпапкам:
    contrib — модули, скачанные с помощью composer
    custom — кастомные модули
    sandbox — модули, скачанные из песочница drupal.org
    manual — остальные модули, скачанные вручную

  11. Использую SASS вместо альтера/препроцесса/переопределения_шаблонов где это возможно. Пример — вместо альтера формы и добавления кнопке класса btn-warning, пишу в scss файле: .form .button { @include btn-warning; }. Не люблю лишней разметки/классов/атрибутов и стараюсь этого избегать.

  12. Переопределяю шаблоны только если не удаётся реализовать задуманное с помощью preprocess и alter-а.

  13. Не держу в themename.theme кода отвечающего за функционал и бизнес логику. Для это есть модуль custom_main.

  14. Не стоит увлекаться дисплеями Views. Как правило любое сложное представление следует выносить в отдельный View, а не делать его дисплеем уже существующего. В дисплеях очень легко намудрить с переопределением. Конечно есть и исключения, когда сделать отдельный view технически невозможно.

  15. Стараюсь использовать формат вывода Content в представлениях, вместо Fields.

  16. Своя базовая тема. Её в любой момент можно изменить/допилить.

  17. Выношу часто используемые кейсы в базовую тему. Например можно добавить в базовую тему опцию "Скрывать заголовок на главной", которая позволит одним кликом убирать h1 с главной страницы.

  18. По возможности решаю задачи уже установленным набором модулей или своим кодом. Если задача не решается текущими модулями и требует больших временных затрат, то можно воспользоваться contrib-ом. Стараюсь не плодить сущностей (читай модулей).

  19. Структура директорий с файлами:
    sites/default/files/public — папка для общедоступных файлов
    sites/default/files/public/upload — файлы залитые пользователями
    sites/default/files/public/upload/images — картинки в подпапках
    sites/default/files/public/upload/inline — файлы вставленные в текст, например с помощью OCUpload
    sites/default/files/private — приватная директория
    sites/default/files/temp — временная директория

  20. Приемлемое время загрузки страницы — меньше 800 ms. Если больше, то приходится разбираться почему и по возможности устранять причину или искать альтернативные решения задачи.

  21. Свой установочный профиль. Позволяет за пару минут развернуть настроенный и готовый к разработке сайт.

  22. Нашёл решение задачи, на которое потратил больше 5 минут? Напиши решение в блог, потом сам себе спасибо скажешь :) А в комментах может и чего лучше посоветуют.

  23. Все ajax формы делаются по принципу Progressive enhancement, т.е. сначала форма делается рабочей даже с отключённым js, а дальше навешивается ajax функционал. AJAX Framework чертовски нелогичен и в нём легко запутаться если работать по принципу Graceful degradation.

  24. Активно использую CSS3. Все дизайн-решения которые можно сделать с помощью CSS должны делаться с помощью CSS, а не картинок. Закруглённые углы, тени, градиенты, множественные бэкграунды, анимация, трансформация — всё уже можно использовать, времена IE6/7/8, Opera 10, Firefox 3 давно закончились. caniuse.com расскажет о поддержке браузерами того или иного свойства.

  25. Если какой-то функционал требует больше нескольких сот строчек CSS кода, то код выносится в отдельный файл.

Bad Practices.

Похожие записи

Комментарии

28. Использую github для хранения и обновления custom модулей. Проще один раз в день делать push по крону, чем после краха HDD восстанавливать данные.

Сначала тоже заморачивался со своей темой,потом начал пользоваться Zen Theme. Намного меньше сил тратиться на поддержку и создание.

Если на одном хостинге много сайтов использую bash, update_drupal.sh:

#!/bin/bash
#Check update
drush -y --root=/path/to/drupal/dir1 rf
echo ""
echo "..."
#Run update
echo "Site name"
drush -y --root=/path/to/drupal/dir1 up
echo ""

Или один сайт, тот же баш и крон в помощь.
#!/bin/bash
drush -y --root=/var/www/site/ rf && drush -y --root=/var/www/site/ up

29. Использую yui-compressor для сжатия css.

servekon, брат, да ты Америку открыл! Неужели ты вслепую скриптом, через крон, контрибные модули обновляешь? Могу пожелать только удачи. )))
Насчёт темы zen, она конечно штука мощная, но в ней много лишнего. Я, как и автор данного поста давно сделал свою тему, адаптировал её под html5 и использую, как мне угодно. Все получается очень читенько. Да и подключить что угодно можно, хоть less, хоть scss.

И ещё, зачем же ты в bash скрипта столько эхо используешь, для красоты вывода??? Вообще это чуть по другому делается, например дабавлением \n в конце. К тому же процесс фоновый, зачем лишнее, все равно ни кто не увидит)))

2 PazitiFF:
1. А в чём проблема обновления contrib модулей? Очень часто security fixes выходят по ночам(МСК), да есть вероятность, что что-то поломается. Но это бывает очень-очень редко, если только у криворукого программиста было что-то критичное завязано на эти модули, и завязано неправильно.
2. эхо сделал, потому что иногда приходится и самому запускать, для наглядности.

В том то всё и дело, что существует ОЧЕНЬ большая вероятность поломки сайта и дело не в "кривых руках" программистов, которые безвозмездно фиксят модули и в замен получают от таких как вы только недовольство, а в подходе администратора сайта, который видимо не совсем понимает, что такое сайт, программирование и система unix в целом. Ваш bash скрипт - это очень некомпитентный совет всем тем новичкам (и не только), кто ищет полезную информацию на данном ресурсе. Примерно тоже самое, если я напишу вам сделать

 
$ sudo dd if=/dev/zero of=/dev/sda

Пример из жизни на форуме

Если хотите действительно сделать полезное, пишите разобравшись в своих действиях.

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

по хорошему после таких скриптов автоматического обновления должен запускать набор ваших функциональных тестов, а без них это выглядит действительно странно :)

Сергей
17.02.2015, 09:15

А по пункту 20 (про кеш) можно поподробнее? можно куском кода.

приватная директория и временная директория должны лежать за пределами www папки и не быть доступными извне (из соображений безопасности)
для временной юзаю дефолтную /tmp
приватную ложу на одном уровне с папкой сайта

По 15 пункту: всегда считал, что скорость ровно наоборот. Сущности кешируются, поля - нет. Но поля однозначно удобнее.

@Alinaki наоборот - поля кэшируются, сущности - нет. Для кэширования сущностей есть модуль entitycache.

Андрей
19.02.2015, 21:16

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

bigferumdron
20.02.2015, 19:40

1. А как вы поступаете с страницами ошибок 403 и 404? Используете стандартные, либо возможно создаете отдельные basic page в самом начале создания сайта, либо может стандартные + какие-то модули..
2. Как вы делаете главную страницу? слышал о проблеме с canonical.
Буду очень благодарен за ответ.

Гость
21.02.2015, 14:38

Мне больше всего по-вкусу вариант с отдельными шаблонами для страниц 404 и 403.
Рецепт подробно рассмотен на форуме.

От себя добавлю, что данный метод уберегает от случайного удаления ноды из базы. Конечно существует еще масса способов, но этот вариант действительно хороший.

Гость
24.02.2015, 13:45

2 Андрей
все зависит от конкретной ситуации.
Допустим у вас есть два типа материалов: новость (over 9000 нод) и акция (мало нод). И там и там используется одно и тоже поле картинка. Дак вот что б сделать вьюху для акции с выводом картинки придется делать джоин с таблицей в которой over 9000 записей. Если же поля будут в разных таблицах такого не произойдет. Само по себе количество таблиц не показатель (конечно если вам это глаза не режет).

число джоинов не зависит от количества полей

Мне тоже интересно почему для каждого контент тайпа лучше отдельное поле ?

у каждого поля есть глобальные опции. изменяя эти опции в одном инстансе они будут действовать во всех других

Андрей
24.02.2015, 16:22

изменяя эти опции в одном инстансе они будут действовать во всех других

теперь идея понятна, а что то на эту фишку не обращал внимания.

Александр
25.02.2015, 11:07

15. Стараюсь использовать формат вывода Fields в представлениях, вместо Rendered entity. Это быстрее работает и гибче темизируется из админки.

А rendered entity лучше кешируется с помощью render_cache и по факту быстре отрабатывает

Пинджак
03.03.2015, 20:15

Буду благодарен за комментарий по пункту 12:
Переопределяю шаблоны только если не удаётся реализовать задуманное с помощью preprocess и alter-а.

Почему нежелательно использование .tpl?
И что именно в выводе можно форматировать через препроцессы и альтеры?
Просто я по-нубски всегда считал, что tpl - самый простой путь...

Это не нежелательно, просто позволяет не переписывать дочерние шаблоны (suggestions) если родительский изменился.

Пинджак
03.03.2015, 20:45

Упс.. Подойдём к вопросу по другому - где можно про suggestions почитать? :) Пойду курить маны

Пинджак
03.03.2015, 22:38

Ну в общем да, глупо спросил. Виноват, затупил на ночь глядя...

Антон
02.04.2015, 01:23

Спасибо за развитие Drupala и за One Click Upload! Ваш блог - образец хорошего кодинга.
По пункту 22 - установочиный профайл, как делаете? Можно где то почитать?

Дмитрий
07.04.2015, 13:48

А кто-нибудь разделяет картинки темы, которые прописываются в css background-image и лежат обычно в корне темы в images, и картинки содержимого (тег img)? И есть ли в этом смысл, как считаете?

Павел
15.04.2015, 11:42

По пункту 15:
Также считал, что именно ноды кешируются, а поля нет. Вот отсюда смотрел http://habrahabr.ru/post/223913/

"3. Отказ от полей во views
«Друзья» — как то сказал наш самый опытный разработчик, — «Мы все знаем, что Drupal кэширует ноды. Так почему мы не пользуемся этим, и заставляем каждый раз views дергать все данные из базы данных?»."

@Alinaki - "Сущности кешируются, поля - нет. "
@xandeadx - "наоборот - поля кэшируются, сущности - нет. "

Мнения разделились..
Так , как же на самом деле?

Хорошо бы с подтверждением, ибо раньше также делал полями (реально удобнее), но сейчас делаю нодами - в пользу скорости..

Павел
15.04.2015, 11:50

По пункту 22:
Как я понимаю, при создании профиля, модули, включенные в профиль лежат в папке профиля.
Не удалятся ли они при обновлении ядра с помощью drush ?

найдите в mysql таблицу с кэшем полей, найдите в mysql таблицу с кэшем сущностей, сделайте выводы.

см. пункт 10

Павел
15.04.2015, 13:07

cache_field - хранит кеш полей
cache_page - хранит закэшированные данные страниц для АНОНИМНЫХ пользователей.
Так?
Но тогда cache_page - как раз и кеширует страницы? Значит можно использовать и в views (например отображать не поля а анонсы материалов)?

И еще вопрос, если можно..
entitycache и Display Cache - надо ли оба использовать для максимального ускорения.
entitycache - закеширует содержимое, а Display Cache - закеширует отрендеренную страницу

Речь была о кэше сущностей, а не о кэше страниц. Про модули не в курсе.

Гость
09.06.2015, 14:17

27 а что за странная запись селекторов?

Гость
09.06.2015, 16:26

ага, спасибо, а на валидность он не влияет?

Здравствуйте.
Очень интересно Ваше мнение по поводу использования модуля Display Suite: стоит ли его использовать или желательно все делать своими силами? Спасибо.

Я им не пользуюсь. Мне он кажется слишком тяжёлым.

Я бы хотел дополнить статью, если моё изложение будет иметь вес (На усмотрение автора). 1. Бывает так, что нужно накатить патч на контрибный модуль. Патч может быть свой, а может быть скачанный со страницы проекта на drupal.org. После применения патча, через некоторое время об этом можно случайно забыть и обновить модуль на новую версию. Если разработчик модуля не внёс исправления из патча, что-то может сломаться. Вывод напрашивается сам собой, надо хранить информацию о примененных патчах в проекте. Как это сделать лучше? Я несколько раз встречал следующий подход. Создаётся директория sites/all/patches, в которою складываются все примененные патчи. Таким образом, всегда можно отследить, какие изменения были сделаны и в случае необходимости накатить нужный патч заново. Как поступает автор статьи в данном случае? Возможно так же или как то иначе?
2. Есть некоторые наработки по 10 пункту:

Все custom модули лежат в папке sites/all/modules/custom. У контриба отдельной папки нет, это дефолтная sites/all/modules.

Если проект простой, то конечно ничего лишнего делать ненужно. Но если проект не простой и с большим размахом где используются фичи и много кастома, считаю что следует делать следующую структуру:
sites/all/modules/contrib
sites/all/modules/custom
sites/all/modules/features
Это не я придумал и такая схема активно используется разработчиками Drupal. На drupal.org есть страница посвященная этому. Кроме того, drush отлично все автоматом раскладывает по нужным директориям.

Как поступает автор статьи в данном случае?

Я патчами пользуюсь крайне редко и никакой методики для их хранения не применяю.

Василий
03.07.2016, 16:13

6 с 18 не стыкуется )
Вообще с 6 пунктом не согласен, раньше тоже также делал, но когда появляется куча мелких модулей...Наверное лучше выносить отдельно исходя не из количества функций (вполне можно комментарии писать, чтобы не запутаться), а из количества строк кода, как в пункте 26. А так всё по делу!

Лозин
18.04.2018, 16:10

По поводу пункта 2.
Почему лучше разные поля а не использование уже существующих?

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