На самом деле, жизнь проста, но мы настойчиво её усложняем.

Drupal и WordPress — сравнение, аналогии, сходства, различия из песочницы


Целью данной публикации является сравнение возможностей двух популярных CMSDrupal 7 и WordPress (последней на данный момент версии 4.6). Ставилась цель рассмотреть CMS с точки зрения программиста и сравнить основные API обеих систем, провести аналогии, сделать выводы о том, какая система лучше подходит для каких задач. Публикация не претендует на полноту изложения всех возможностей CMS, а автор будет благодарен за коррективы и дополнения.

Архитектура

Оба фреймворка построены по сходной архитектуре: ядро + тема + дополнения. Ядро (движок) обеспечивает базовую функциональность. Дополнения в Drupal называются модулями, в WP — плагинами. И модули и плагины для своего создания требуют минимальных усилий (пары файлов с определённой структурой) и по своей сути не отличаются, это некоторый именованный кусок php кода с возможными сопутствующими стилями и JS скриптами, который можно независимо распространять и устанавливать в систему. Темы призваны обеспечить Look & Feel сайта, состоят из шаблонов страниц и вспомогательного кода и так же распространяются и устанавливаются отдельно. Подробности рассмотрим позже.

Настройка и переопределение базовой функциональности ядра и стандартных компонентов происходит с помощью системы хуков, которая также имеет аналогичное предназначение в этих системах. Таким образом общая архитектура представляется весьма сходной.
 

Особенности эксплуатации

WordPress давно вырос из своего первоначального назначения быть движком блогов. На данный момент декларируется, что его применение практически ничем не ограничено. Drupal, определяемый иногда, как CMF (content management framework), изначально задумывался универсальным и подходящим для всех типов сайтов. Установка обеих систем занимает небольшое время (5-10 мин), не требует каких-либо специальных компьютерных мощностей и бесплатна. После установки в обоих случаях получается готовый к настройке и использованию сайт с темой по умолчанию.

В качестве БД WP использует только MySQL, Drupal предоставляет набор вариантов популярных баз данных (MS-SQL, Oracle, SQLite, PostgreSQL). После базовой установки WP создаёт 11 таблиц БД, Drupal — более сотни (на первый взгляд это пугает, на второй тоже).

В обеих системах есть административное меню. В Drupal для него явно определяется своя тема, в WP для админки формально тема всегда одна и та же, но настраивается с помощью плагинов. В целом админка WP кажется более готовой для использования конечным пользователем и простой в восприятии, чем админка в Drupal, которая, кажется, рассчитана на профессионального администратора или на программиста (но это лишь вопрос темы для админки).

Плагины WP удобно ищутся и устанавливаются прямо в админке, обычно имеют понятное описание и всякие хинты для пользователя (типа “привет, я установился, нажми сюда”). В Drupal встроенной системы поиска модулей нет, модуль ищется руками на drupal.org и устанавливается по его URL, либо прямым копированием в директорию модулей (что для WP тоже возможно), либо с помощью консольного приложения drush (в WP тоже есть консольное приложение WP-CLI, но, думаю, гораздо менее популярное).

Обновления обеих систем вполне аналогичны, проверка на обновления автоматизирована, сами обновления скачиваются и устанавливаются нажатием одной кнопки. Принципиальную разницу представляет система мажорных версий, где WP придерживается политики единой линейки при полной обратной совместимости (и ваш сайт апдейтится на самую последнюю версию), в то время как, например, Drupal 7 и Drupal 8 — совсем разные и несовместимые друг с другом линейки продуктов. Для переноса сайта с Drupal 7 на Drupal 8 могут потребоваться значительные усилия программиста. 

Ввиду того, что апдейты для обеих систем приходят систематически, ни там ни там крайне не рекомендуется “взламывать ядро”, т.е. модифицировать ядерные файлы. Делать это скорее всего и не придётся, а если кажется, что это единственный путь, то скорее всего либо CMS была выбрана неадекватно задаче (что реже), либо (и скорее всего) не все возможности настройки системы еще изучены.
 

Подробнее о модулях и плагинах

Модуль Drupal создаётся определением файлов module_name.module и module_name.info, где первый может быть совсем пустым, а последний должен содержать лишь минимальную информацию определённой структуры. После появления этих файлов в папке с модулями (обычно в отдельной папке, но не обязательно), Drupal распознаёт модуль и отображает его в панели административного меню. Для начала работы модуль необходимо активировать. Кастомные (т.е. созданные программистом для данного проекта) модули ничем не отличаются от контрибьюторских (стандартных, находящихся в базе Drupal), последние на практике порой подвергаются доработке для нужд конкретного проекта.

Считается, что модуль должен содержать некий логически изолированный кусок функциональности, т.е. приветствуется разбивка более сложных частей функциональности на отдельные модули («видишь что-то отдельное/отделимое — напиши модуль»). Профессиональный сайт на Drupal, особенно использующий большие подсистемы типа Drupal Commerce (состоящие из многих взаимосвязанных модулей), может содержать несколько сотен контрибьюторских и кастомных модулей.

Для определения плагина WP также требуются минимальные усилия, а именно всего один PHP файл с комментарием в шапке (обязательна лишь одна строчка с именем плагина). Как и модуль, плагин требуется активировать в админке для начала работы. Поскольку по сути дела писать код больше некуда (файл темы functions.php явно не предназначен вместить всю функциональность, а шаблоны не принято набивать кодом бизнес-логики), то организация приложения также осуществляется с помощью разбивки на плагины.

WordPress довольно часто критикуют за то, что плагинов очень много, но никто не гарантирует, что с подключением конкретного плагина в вашем сайте не образуется секьюрная дыра. В Drupal наблюдение общественности за состоянием модулей кажется более внимательным, хотя не очень понятно, способно ли это реально предупредить проблемы с секьюрити или лишь оперативно отреагировать на уже случившуюся беду. В целом рынок плагинов WP производит впечатление более “свободного” и разностороннего (и небезопасного), а набор модулей Drupal — впечатление более профессионально проверенного. Хотя может быть это только впечатление.
 

Хуки

Краеугольной фичей работы тем, модулей и плагинов является возможность (и необходимость) использовать хуки. Хук (зацепка) — это место в ядре или другом модуле/плагине, когда предоставляется возможность изменить дефолтовую работу кода. Хуков много в обеих системах (базовых в Drupal — около 350, в WP — около 250). 

В Drupal для подключения хуков используется интересная и самобытная система именования, не требующая отдельного явного подключения. Например, находящаяся в модуле my_module функция my_module_menu будет автоматически служить хуком для определения роутов (шаблон имени “hook_menu”). В WP для определения хука (точнее экшен хука/экшена или фильтра, что по сути то же самое) требуется явно вызвать функцию add_action или add_filter. Соображения по этому поводу могут быть разные. С одной стороны определение функции и последующий вызов add_action() может показаться немного избыточной синтаксической конструкцией. С другой стороны имеют место следующие нюансы:
 

  • add_action() несколько уменьшает количество “магии” в коде, которая не способствует читаемости кода;
  • add_action() позволяет одному плагину добавить сколько угодно обработчиков, в то время как функция my_module_menu() может быть в данном модуле только одна;
  • есть функция remove_action(), с помощью которой можно отменить хук другого модуля, а в Drupal такого механизма нет.

 

Создание темы

Тема Drupal появляется после создания файла themename.info в папке sites/all/themes. Info файл — это простой текстовый файл, определяющий общую информацию о теме: название, автор, регионы на странице, подключаемые файлы JS и CSS и т.д. После создания или установки (установка темы аналогична установке модуля), тема должна быть активирована в админке и выбрана основной.

Тема WP определяется двумя файлами: основным является style.css, который задаёт название темы (и конечно обычно стили) и дополнительным — базовым шаблоном index.php. Структура определения темы WP восходит к временам, когда WP был простым движком для блогов, единственным шаблоном был index.php, а style.css собственно содержал стили. С тех пор шаблонов стало больше, а определение темы осталось тем же. Назначение style.css обязательным и главным файлом темы может показаться не изящным, но зато есть обратная совместимость.

Обе системы поддерживают создание дочерних тем, что упрощает жизнь, когда работаешь с очень сложными готовыми темами, настраивая их под себя. В случае дочерней темы обязательными остаются только файлы *.info и style.css.

Теме в Drupal сопутствует файл template.php, где производятся настройки темы, и определяется функционал, специфичный для всей темы целиком. В WP есть аналогичный файл functions.php. При создании собственной темы WP в functions.php обычно помещается код для подключения и отключения типовых возможностей темы (функции add_theme_support и remove_theme_support), регистрируются JS скрипты, стили и сайдбары. В Drupal такие вещи обычно делаются мышкой в админке, а в template.php помещаются функции типа template_process/template_preprocess, переопределяющие поведение шаблонов.
 

Готовые темы и их настройка

В аспекте готовых тем и их настройки WP значительно опередил Drupal. В свободном (и в несвободном) доступе имеется очень широкий круг тем на любой вкус и с классическим и с современным дизайном, обычных, responsive и вообще каких угодно. Кроме того, WP предоставляет отдельный API (customizer) для определения настроек темы, и создатели тем стараются сделать их максимально настраиваемыми. Тема WP — это порой отдельный продукт с регулярными обновлениями и премиум-функционалом. Отдельной фишкой при настройке темы WP является функция предпросмотра.

Drupal на настройке тем так не акцентируется. Для обычной темы в админке можно лишь поменять цветовую гамму и основные параметры сайта — название, иконку и т.д. Типовым путём создающего свой сайт программиста будет взять какую-то стандартную минималистическую тему (например, Stark), и на её базе построить свою вёрстку. Другим подходом будет использование более продвинутых продуктов, например темы Zen, использующей responsive design, Sass и Gulp.
 

Процессинг HTTP Запроса

В веб-приложениях всё начинается со строки запроса. Используя строку запроса, обе системы определяют, как дальше действовать. В Drupal создается роутер путей, включающий как стандартные пути (типа “node/1234”, “user/123” или “taxonomy/term/123”), так и кастомные (определённые с помощью hook_menu). После анализа строки запроса находится нужный путь в роутере и из прикреплённой к пути дополнительной информации достаётся delivery_callback — функция отрисовки страницы. Есть два стандартных delivery callback — дефолтовый drupal_deliver_html_page и аяксовый ajax_deliver, плюс при определении пути можно задать свой собственный.

В WP на основе строки запроса производится парсинг параметров запроса, и создаётся глобальный объект $wp_query класса WP_Query. Далее устанавливаются условные таги (conditional tags — is_page, is_single, is_category, is_archive, etc), которые описывают, что из себя представляет запрос, и что собственно запрашивается (конкретный тип постов, посты из архива или из категории и т.д.). Глобальный объект $wp_query и условные таги далее используются в шаблонах и пользовательском коде. На основе условных тагов происходит также дальнейший выбор файла-шаблона для отрисовки.

В целом подход в Drupal более системный и солидный (роутер — единое хранилище путей и обработчиков), подход в WP проще, и, видимо, развивался эволюционно (например, добавлением новых условных тагов), но тем не менее достаточно гибок и кастомизируем. Класс WP_Query представляется очень удобным механизмом простой работы с дополнительными запросами, а хук pre_get_posts позволяет модифицировать основной запрос.
 

Шаблоны

Иерархия шаблонов Drupal имеет следующую структуру. Шаблоном самого нижнего уровня является html.tpl.php, содержащий основной маркап страницы с тегом doctype. Настройка его производится в относительно редких случаях, потому что для добавления CSS/JS есть более высокоуровневые механизмы (даже код Google Analytics внедряется отдельным модулем). Далее идёт page.tpl.php, вставляющийся в html.tpl.php в виде переменной $page и определяющий общую структуру страницы. В page.tpl.php определяются регионы, указанные в info-файле темы. Явных понятий header и footer в Drupal нет, логически они “размазаны” между html и page шаблонами. 

Система регионов в теме очень удобно и гибка, для регионов можно определить свои шаблоны (шаблон region.tpl.php), регионов может быть сколь угодно много, а по умолчанию предоставляется хороший базовый набор. В шаблоне page есть переменная $content, через которую в шаблон попадает собственно контент. Для вывода контента, который в Drupal представлен сущностями типа node (нода), имеется шаблон node.tpl.php. 

Для всех указанных базовых шаблонов существуют дефолтовые версии, т.е. тема в состоянии жить совсем без шаблонов у себя в папке, в этом случае будут подхватываться одноимённые шаблоны из ядра и ядерных модулей (например, из модуля system). Для переопределения достаточно найти и скопировать шаблон в папку своей темы. Помимо типовых шаблонов модули могут определять собственные, как, например, сделано в модуле Views. Каждый шаблон снабжается рядом предустановленных переменных (подробно расписанных в комментариях в шаблоне), которые можно менять и дополнять в функциях типа process_page/preprocess_page.

В целом иерархичность шаблонов темы Drupal имеет характер “вложенности”, field вкладывается в node, node вкладывается в page, page — в html. Также подмена одного шаблона другим происходит при специализации (когда, например, node-15.tpl.php используется вместо node.tpl.php).

Иерархия шаблонов WP имеет другой характер. Все базовые шаблоны тут являются “полноразмерными”, т.е. содержат doctype. Какой шаблон применяется, зависит от текущего запроса и условных тагов. По тагам определяется, какой шаблон использовать. Если, например, запрашивается страница (is_page() == true), то система использует page.php, если в запросе категория (is_category), то category.php, если отдельная запись в блоге, то используется single.php и т.д. Центральное место занимает шаблон index.php, который используется для обработки запросов, для которых не нашлось более специфичного шаблона. Когда-то этот шаблон был в WP единственным, и это центральное место так за ним и осталось.

Дефолтовых шаблонов в WP нет, но index.php (как “всеядный” шаблон) чаще всего имеет типовой вид с WP циклом (loop). В WordPress обычно явно определяются шаблоны header.php и footer.php. Это “сырые” части html (в header.php открывающие теги , , в footer.php — закрывающие). Для их вставки предусмотрены функции get_header() и get_footer() (поэтому файлы должны называться именно так). Вроде как примитивно, но зато просто и понятно. Drupal регионам в WP соответствуют Sidebars, для них есть свои шаблоны sidebar-name.php и функции их использования dynamic_sidebar() (про сайдбары и виджеты чуть позже).

Кроме типовых шаблонов в WP можно создавать именованные кастомные шаблоны, которые потом можно применять к отдельным страницам (при создании страниц появляется опция использовать шаблоны, если хоть один существует).

Для отображения главной страницы есть не совсем (как мне показалось) очевидная логика, основанная на нескольких вариантах отображения: статической страницей, стандартным блоговым видом или кастомным шаблоном. С деталями можно ознакомиться в кодексе WP в разделе разработки тем.

Как видно, шаблоны в Drupal более системны и просты в изучении, а в WP вероятно более гибки и практичны. И там и там иерархию шаблонов приходится поизучать, чтобы применять эффективно. И там и там есть выбор и необходимая гибкость для достижения необходимого результата.
 

Регионы и сайдбары

Итак, в info-файле Drupal темы определяются регионы, в файле page.tpl.php определяется размещение регионов на странице, в шаблонах region--name.tpl.php определяется маркап конкретных регионов. Это даёт ясную структуру и большую гибкость в построении темы. После определения регионов они доступны в админке для размещения блоков (block). Блоки — это визуально-изолированные кусочки вывода на страницы, которые могут легко перемещаться между регионами (например, мышкой в админке). По сути регионы создаются для размещения блоков и главного контента. Блок может быть типовой (например, “сделано на Drupal”), может быть определён в любом модуле с помощью хуков (hook_block_info), а может быть создан прямо в админке как произвольный html-код. Для блоков существует свой шаблон block--name.tpl.php.

Виджеты в WP — это ровно то же самое, что блоки в Drupal. WordPress виджеты также бывают типовые (например, “сайт работает на WP”), могут создаваться плагинами и темами (с помощью наследования класса WP_Widget и функции register_widget), а могут быть определены прямо в админке с помощью html-кода (точнее есть стандартный виджет, позволяющий разместить произвольный HTML код). Роль регионов в WP играют сайдбары (sidebars). Сайдбары нужно регистрировать в теме в файле functions.php с помощью функции register_sidebar. После регистрации сайдбары становятся доступны в админке в разделе Виджеты и позволяют размещать виджеты разных видов. Для сайдбара по умолчанию есть шаблон sidebar.php, для дополнительных “именованных” сайдбаров можно определять шаблоны sidebar-name.php. 

В целом регионы и блоки в Drupal несколько более просты в использовании, но незначительно, функциональность сайдбаров и виджетов полностью аналогична.
 

Подключение CSS/JS

Для подключения JS в WP используется функция wp_enqueue_script, и хук wp_enqueue_scripts. Путь собственно единственный. Если хочется контролировать подключение, то используется логика, благо хуки в WP требуют явного вызова add_action(). В Drupal для подключения JS существует несколько путей:
 

  • подключение в файле info темы
  • подключение функцией drupal_add_js (аналогична wp_enqueue_script)
  • подключение через libraries API
  • подключение через параметр attach в формах
  • подключение прямо в шаблон html.tpl.php (не рекомендуется);

Первый путь наиболее удобен и логичен, второй позволяет добавить логику при подключении. Libraries API — довольно удобная штука, позволяющая подключать целые библиотеки (JS/CSS/PHP), с несколькими версиями и отслеживанием, какую версию когда загружать. Библиотеки при этом могут использоваться несколькими темами.

Для подключения CSS механизмы подключения аналогичны (с заменой script на style и js на css).
 

Контент

По историческим причинам контент в WP называется постами (post), контент в Drupal называется нодами (node). В целом они особых отличий не имеют, за исключением нюансов. Например, двумя стандартными типами контента в WP являются собственно посты и страницы. Страницы не являются подтипом постов, а представляют собой некий обособленный тип контента со своими свойствами. Например, для страниц нельзя определить таксономию. Страницы часто используются для статического контента, но могут быть определены согласно пользовательскому шаблону, т.е. по сути содержать что угодно.

Ноды в Drupal представляют собой все виды контента, включая страницы (pages). Весь контент изначально доступен по ссылкам типа “node/node_id”, например “/node/12345”, таким образом весь контент унифицирован.
 

Типы контента и поля

Типы контента — это подтипы нод и постов соответственно. Для WP тип постов определяет просто некий маркер-название и ничего больше не определяет. Можно создавать посты с таким “типом”, можно их по типу вытаскивать из базы. Для Drupal тип нод (бандл) — это не только название, но и, например, кастомные поля, которые по умолчанию прикрепляются к данному бандлу. В WP вместо полей в базовом функционале есть мета-информация — любого сорта key-value пара, которая может прикрепляться к посту (конкретному посту, а не всему типу). 

Популярным решением является использование модуля Advanced Custom Fields (ACF), с помощью которого можно определять наборы полей и прикреплять их к типам контента, аналогично Drupal подходу. В Drupal это сделано более гибко, потому что разделяются понятия field и field instance — абстрактно определённое поле и поле, прикреплённое к какому-то бандлу. Но в целом практические возможности в итоге аналогичны.

Мета-информация в WP может прикрепляться не только к постам, но и к пользователям, терминам таксономии и комментариям (функции add_post_meta, add_user_meta, add_term_meta, add_comment_meta). В Drupal есть обобщающее понятие сущности (Entity и Entity API), и поля прикрепляются к сущностям, имеющим свойство fieldable. 
 

Таксономия

Таксономия — это категоризация контента с помощью иерархии терминов. Обе системы имеют полнофункциональные возможности для определения сколь угодно сложной таксономии, благо сама идея не слишком сложна. Обе системы предоставляют развитый API для операций со словарями и терминами таксономии. Появление в WP кастомных типов постов и иерархической таксономии объявляется коренным изменением, благодаря которому WP перестал быть просто движком для блогов и превратился в полноценную CMS. Наверно можно с этим согласиться, хотя рудиментов былой “блого-ориентированности” WP довольно много (например, функция bloginfo, WP_Post, sidebars, сам по себе Loop и т.д).
 

Настройка вывода контента

Один из самых значимых контриб-модулей Drupal — Views — позволяет формировать страницы для отображения имеющихся видов контента почти в любом виде. Настраивать это всё удобно из админки, но при желании можно и из кода. По сути при создании конкретных страниц сайта на Drupal решается задача вывода контента в форме статических страниц, ноды целиком (через шаблон node.tpl.php) или вьюшки (т.е. блока или страницы, сформированной модулем Views). Сама вьюшка определяет как выводимый контент формируется, а соответствующие шаблоны модуля Views определяют конкретный маркап вывода. Для переопределения таких шаблонов их также следует скопировать из модуля себе в тему.

Аналогом Views в WP вероятно можно считать главный механизм вывода контента — цикл (loop). Цикл использует глобальную переменную $wp_query для получения результатов запроса. Большинство стандартных шаблонов использует цикл и таги шаблонов (Template Tags), для вывода конкретных частей содержимого (заголовка, даты, собственно содержимого поста, ссылки на пост и т.д.). По сути Drupal объект view является обёрткой такого рода цикла, настраивающейся с помощью структурированного массива (которые столь в Drupal любимы).

Трудно сказать, какой механизм удобнее и гибче. Вьюшки можно создавать совсем без программирования, сразу же получая предпросмотр того, как всё будет выводиться на реальном контенте. С другой стороны более тонкая настройка вьюшек (из кода через объект view и функции типа views_embed_view) явно сложнее настройки вывода цикла WP. Но зато уже настроенный объект вьюшки можно переиспользовать в любом месте кода, не надо повторять код цикла.

Говоря про вывод контента с помощью набора шаблонов, важно отметить одно значительное отличие — до самого последнего момента (вызов функций render() или drupal_render()) формат вывода контента в Drupal остаётся в виде так называемых renderable arrays — структурированных массивов, менять которые проще, чем готовую HTML строку. Структурированные массивы — механизм интересный и удобный, правда массивы эти со временем разрастаются до неимоверных размеров (иногда сотни тысяч элементов), становятся рекурсивными, включают и пере-включают в себя одно и то же содержание и вообще порой наводят ужас.
 

APIs

И Drupal и WP постоянно развиваются и добавляют новые возможности для программистов. В обеих системах эти возможности структурированы, как отдельные API. Рассмотрим некоторые из них.
 

AJAX API

Drupal предоставляет весьма интересный интерфейс для работы с Ajax. Основная идея — организовать Ajax функциональность по возможности вообще без написания какого-либо JavaScript кода. Это достигается введением CSS классов типа “use-ajax” (достаточно приписать такой класс к кнопке или ссылке), а также механизма стандартной обработки ajax запросов (для всех ajax-запросов один типовой путь system/ajax). На серверной стороне с помощью функций ряда ajax_command_* (например, ajax_command_invoke) можно полностью определить, что будет происходить в браузере, вплоть до вызова конкретных функций jQuery. Механизм требует некоторого времени на освоение, но позже позволяет эффективно перерисовывать нужные куски DOM прямо из PHP.

Отдельного рассмотрения заслуживает механизм Drupal behaviors. По замыслу этот механизм призван трактовать JS код, как некоторое поведение, которое включается в нужный момент времени, не только при первичной загрузке страницы, а, например, после перерисовки части DOM при ajax запросе. Behavior получает контекст (по сути корневой элемент DOM, в котором произошли изменения) и может отреагировать соответственно. Механизм behaviors — полезный и интересный, если освоен и правильно применяется.

Механизм Ajax в WP значительно проще и слабо отличается от базового ajax в принципе в PHP. По сути WP определяет стандартный путь, куда посылаются запросы из JS (глобальная переменная ajaxurl в JS) и механизм определения обработчиков через хуки. Ajax response при этом формируется с помощью класса WP_Ajax_Response, который просто создаёт нужный XML код. Можно также просто использовать функцию wp_send_json. 
 

Forms API

Drupal предоставляет довольно мощный API для работы с формами, используя структурированные массивы. Фактически любая форма в Drupal должна определяться описанием всех своих компонентов, как элементов в структурированном массиве и выводиться уже в шаблоне с помощью drupal_render. При определении элементов массива, можно указывать многие интересные вещи, например использовать Ajax API, упомянутый выше, включать требуемые специально для формы JS/CSS, можно создавать многостраничные формы. Forms API (FAPI) поддерживает валидацию ввода, несколько обработчиков при submit, возможности переопределения форм с помощью хуков.

В WP подобного механизма работы с формами нет, есть много плагинов, которые помогают в админке рисовать формы обратной связи для сайтов и вставлять их на странички. Известны попытки создать что-то похожее на Drupal FAPI. В целом несколько обидно, что для настолько базового функционала нет даже простых хелперов типа Form::open().
 

Еще про пути

Как уже отмечалось, пути (routes) в Drupal определяются с помощью хука hook_menu. Таким образом можно задать любые возможные пути (обычные, в админке, Ajax, API и т.д.) — способ удобный и единообразный. В WP такого единообразного способа нет, зато есть два интересных API: Rewrite, с помощью которого можно самостоятельно определять правила преобразования пути в красивую ссылку, и WP REST API. Последний предоставляет реальный готовый REST интерфейс, позволяющий получать данные из БД, а также позволяет определять любые свои кастомные пути. В Drupal аналогов этим API нет.
 

Entity API

Не так давно в Drupal появился Entity API — новый уровень абстракции над нодами, позволяющий определять сущности, не относящиеся непосредственно к контенту. Ноды, пользователи, комментарии и термины таксономии стали частными случаями сущностей (entity). При подключении контриб-модуля Entity API (который почему-то не входит в набор по умолчанию) с сущностями можно эффективно работать. 

Основным вопросом является — когда и зачем это делать. Рекомендуют всё, что похоже на контент и имеет внешний вид оформлять как типы нод, а что-то более абстрактное и “невидимое” на экране — как сущности. Можно сказать, что это инструмент для организации более сложного приложения на Drupal. Например, сущности активно используются в Drupal Commerce для оформления отдельных характеристик заказа.

В WP такой абстракции нет, поэтому если нужно будет писать что-то более замысловатое, то придётся либо использовать custom post types либо просто получать удовольствие и писать на PHP. 
 

Модели данных и БД

Модель данных в CMS построена вокруг типов контента. Если бизнес-логика приложения может быть удобно описана с помощью типов контента, то CMS — удачный инструмент для использования. Тип контента — это независимая сущность с фиксированным набором атрибутов (среди которых есть что-то типа title и description). Желательно, чтобы разные типы контента были между собой не связаны.
С типами постов WP удобнее всего работать через объект WP_Query, а также функции get_posts() и query_posts(). Если возможностей WP_Query недостаточно, то есть функция dbDelta(), которая призвана запускать любые SQL запросы, а также класс wpdb, возможности которого используют через глобальный объект $wpdb. Класс wpdb несколько упрощает работу с БД, но всё равно часто приходится писать “сырой” SQL, никаких возможностей query builder он не предоставляет.

В Drupal для работы с БД есть несколько API:

1. Для работы со структурой (схемой) БД есть hook_schema и функции типа db_create_table/db_add_field.
2. Функция drupal_write_record, как простой способ записи в БД.
3. Основной API — набор функций db_select/db_insert/db_update/db_delete/db_query, с динамическим построением запросов (примеры).
4. Для более удобной работы с сущностями и полями существует класс EntityFieldQuery, который также позволяет делать динамические запросы.

Существуют также попытки приладить к CMS более серьёзные инструменты типа Doctrine. И для WordPress и для Drupal есть соответствующие модули/плагины, но, судя по всему, не в активной разработке. Видимо острой надобности в таких инструментах нет, ввиду опять же несколько другой модели данных.
 

Заключение и выводы

Рассмотрение конкретных возможностей для программиста приводит нас к выводу, что Drupal представляет из себя значительно более сложную и оснащённую систему разработки, вместе с тем требующую большого времени для изучения (которое не всегда и не у всех есть). Опыт показывает, что Drupal-мощь на практике компенсируется его сложностью. Сайт на Drupal, попавший «не в те руки», быстро становится огромной кучей несопровождаемого кода.

С другой стороны WordPress — это значительно более лёгкая платформа, позволяющая очень быстро получить заметный результат. Инструментов для длительной командной разработки у WordPress конечно маловато, но система активно развивается, прирастает интересными возможностями. Обе CMS, таким образом, заслуживают серьёзного рассмотрения для своего круга задач.

Источник