xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Мои Best Practices

Опубликовано в

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

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

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

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

  4. Машинные имена словарей в множественном числе — categories, colors.

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

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

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

  8. Custom модули создаются одной командой drush. Можете самостоятельно написать её или воспользоваться уже готовой.

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

  10. Модули рассортированы по подпапкам contrib, custom и sandbox.

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

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

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

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

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

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

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

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

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

  20. В dev окружении отключён кэш страниц и блоков, а так же агрегация css и js. Отключается с помощью хардкода в settings.php.

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

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

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

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

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

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

  27. При написании селекторов начинаю с id блока. Если это контент, то с соответствующего класса вьюхи/формы/ноды. Стараюсь не использовать больше двух элементов в селекторе. Пример:

    #block-last-news {
      .news { ... }
      .news-title { ... }
      .news-body { ... }
    }

Bad Practices.

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

Комментарии RSS

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-х сайтов на сервере. И честно говоря я уже забыл когда последний раз после обновления любого модуля, что-нибудь ломалось.

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

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

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

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

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

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

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

1. нода типа page
2. нода или вьюха

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

см. пункт 10

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

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

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

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

less/scss

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

валидность чего?

нет

Здравствуйте.
Очень интересно Ваше мнение по поводу использования модуля 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 отлично все автоматом раскладывает по нужным директориям.

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

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

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

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании