The purpose of this publication is to compare the capabilities of two popular CMS - Drupal 7 and WordPress (the latest at the moment version 4.6). The goal was to consider CMS from the programmer's point of view and compare the main APIs of both systems, draw analogies, and draw conclusions about which system is better suited for which tasks. The publication does not pretend to the full presentation of all the possibilities of CMS, and the author will be grateful for corrections and additions.
Architecture
Both frameworks are built on a similar architecture: core + theme + add-ons. The kernel (engine) provides basic functionality. Add-ons in Drupal are called modules, in WP they are plug-ins. Both modules and plugins for their creation require minimal effort (pairs of files with a certain structure) and do not differ in essence, this is some named piece of php code with possible accompanying styles and JS scripts that can be independently distributed and installed into the system. Themes are designed to provide the site's Look & Feel, consist of page templates and auxiliary code, and are also distributed and installed separately. Details will be discussed later.
The basic functionality of the kernel and standard components are set and redefined using the hooks system, which also has a similar purpose in these systems. Thus, the overall architecture seems very similar.
Features of operation
WordPress has long grown from its original purpose of being a blogging engine. At the moment, it is declared that its use is practically unlimited. Drupal, sometimes defined as the CMF (content management framework), was originally conceived as universal and suitable for all types of sites. Installation of both systems takes a little time (5-10 min), does not require any special computer power and is free. After installation in both cases, you get a site that is ready for configuration and use with a default theme.
')
As a database, WP uses only MySQL, Drupal provides a set of variants of popular databases (MS-SQL, Oracle, SQLite, PostgreSQL). After the basic installation, WP creates 11 database tables, Drupal - more than a hundred (at first glance it frightens, at the second too).
In both systems there is an administrative menu. In Drupal, his theme is clearly defined for him, in WP for the admin, formally, the theme is always the same, but configured using plugins. In general, the WP admin panel seems more ready for use by the end user and easier to understand than the admin panel in Drupal, which seems to be designed for a professional administrator or programmer (but this is only a matter of admin theme).
WP plugins are conveniently searched for and installed directly in the admin panel, usually have a clear description and all the hints for the user (like “hello, I am installed, click here”). In Drupal, there is no built-in search engine for modules, the module is searched by hands on drupal.org and installed via its URL, either by direct copying to the modules directory (which is also possible for WP), or using the
drush console application (WP also has a
WP- CLI , but, I think, much less popular).
Updates of both systems are quite similar, the check for updates is automated, the updates themselves are downloaded and installed by pressing one button. The major difference is the major version system, where WP adheres to the policy of a single line with full backward compatibility (and your website is updated to the latest version), while, for example, Drupal 7 and Drupal 8 are completely different and incompatible product lines . Moving a site from Drupal 7 to Drupal 8 may require considerable programmer effort.
Due to the fact that updates for both systems come systematically, neither there nor there it is not recommended to “crack the core”, i.e. modify nuclear files. Most likely, this will not have to be done, and if it seems that this is the only way, then most likely either the CMS was chosen inadequately to the task (which is less common), or (and most likely) not all the possibilities of setting up the system have been studied.
More about modules and plugins
A Drupal module is created by defining the module_name.module and module_name.info files, where the first can be completely empty, and the last should contain only minimal information of a certain structure. After the appearance of these files in the module folder (usually in a separate folder, but not necessarily), Drupal recognizes the module and displays it in the administrative menu panel. To get started, the module must be activated. Custom modules (ie, those created by the programmer for this project) do not differ in any way from the contributors (standard ones that are in the Drupal database), the latter in practice are sometimes modified to meet the needs of a specific project.
It is considered that a module should contain some logically isolated piece of functionality, i.e. The breakdown of more complex parts of the functionality into separate modules is welcomed (“you see something separate / separable - write a module”). A professional site on Drupal, especially using large subsystems such as
Drupal Commerce (consisting of many interconnected modules), may contain several hundred contributor and custom modules.
The definition of the WP plugin also requires minimal effort, namely just one PHP file with a comment in the header (only one line with the name of the plugin is required). Like the module, the plugin needs to be activated in the admin area to get started. Since, in essence, there is no other place to write code (the functions.php theme file is clearly not designed to accommodate all the functionality, and templates are not made to be crammed with business logic code), the organization of the application is also done using the breakdown into plug-ins.
WordPress is often criticized for the fact that there are a lot of plug-ins, but no one guarantees that with the connection of a specific plug-in, there is no security hole in your website. In Drupal, public monitoring of the state of the modules seems to be more attentive, although it is not very clear whether this can really prevent problems with security or only respond promptly to a disaster that has already happened. In general, the WP plug-in market seems to be more “free” and versatile (and insecure), and the Drupal suite of modules gives the impression of a more professionally proven one. Although it may be just an impression.
Hooks
The cornerstone of how themes, modules, and plugins work is the ability (and necessity) to use hooks. A hook (hook) is a place in the kernel or another module / plugin, when it is possible to change the default code operation. There are a lot of hooks in both systems (there are about 350 basic ones in Drupal, about 250 in WP).
Drupal uses an interesting and original naming system for connecting hooks, which does not require a separate explicit connection. For example, the my_module_menu function in the my_module module will automatically serve as a hook for defining routes (the “hook_menu” name pattern). In WP, to define a hook (more precisely, a hook / action or a filter, which is essentially the same), you must explicitly call the add_action or add_filter function. Considerations on this subject may be different. On the one hand, the definition of a function and the subsequent call to add_action () may seem a bit redundant syntax. On the other hand, the following nuances take place:
- add_action () slightly reduces the amount of “magic” in the code, which does not contribute to the readability of the code;
- add_action () allows one plug-in to add as many handlers as you need, while the function my_module_menu () can only have one in this module;
- There is a function remove_action (), with which you can cancel the hook of another module, but there is no such mechanism in Drupal.
Topic creation
The Drupal theme appears after creating the themename.info file in the sites / all / themes folder. An Info file is a simple text file that defines general information about a topic: title, author, regions on the page, JS and CSS included files, etc. After creating or installing (installing the theme is similar to installing the module), the theme must be activated in the admin area and the main one is selected.
The WP theme is defined by two files: the main one is style.css, which sets the name of the theme (and of course, usually styles) and the additional one is the basic index.php template. The structure of the definition of the WP theme dates back to the times when WP was a simple blogging engine, the only template was index.php, and the style.css actually contained styles. Since then, the templates have become more, and the definition of the theme remains the same. The designation of style.css as mandatory and the main theme file may not seem elegant, but there is backward compatibility.
Both systems support the creation of subsidiaries by simplifying life when working with very complex ready-made themes, customizing them for yourself. In the case of a child theme, only * .info and style.css files remain mandatory.
A theme in Drupal accompanies the file template.php, where theme settings are made, and the functionality specific to the entire theme is determined. WP has a similar functions.php file. When you create your own WP theme in functions.php usually put the code to connect and disable typical features of the theme (functions add_theme_support and remove_theme_support), JS scripts, styles and sidebars are registered. In Drupal, such things are usually done with a mouse in the admin panel, and in template.php are placed functions like template_process / template_preprocess, which override the behavior of templates.
Ready themes and their settings
In terms of ready-made themes and their settings, WP was significantly ahead of Drupal. In the free (and in the non-free) access there is a very wide range of topics for every taste with both classic and modern design, ordinary, responsive and whatever you like. In addition, WP provides a separate API (customizer) for defining theme settings, and theme creators try to make them as customizable as possible. The WP theme is sometimes a separate product with regular updates and premium functionality. A separate chip when setting up a WP theme is the preview function.
Drupal doesn’t accentuate the theme settings. For an ordinary theme in the admin panel, you can only change the color scheme and the main parameters of the site - the name, icon, etc. In a typical way, a programmer creating a website will take a standard minimalist theme (for example,
Stark ), and build its layout on its basis. Another approach would be to use more advanced products, such as the
Zen theme, using responsive design, Sass, and Gulp.
HTTP Request Processing
In web applications, everything starts with the query string. Using the query string, both systems determine how to proceed. Drupal creates a router of paths, including both standard paths (such as node / 1234, user / 123, or taxonomy / term / 123) and custom paths (defined using hook_menu). After analyzing the query string, the desired path is found in the router and from the additional information attached to the path, delivery_callback, the page rendering function, is obtained. There are two standard delivery callbacks - the default drupal_deliver_html_page and ajax ajax_deliver, plus you can set your own when defining the path.
In WP, on the basis of the query string, the query parameters are parsed, and a global $ wp_query object of the WP_Query class is created. Next, conditional tags are set (
conditional tags - is_page, is_single, is_category, is_archive, etc), which describe what the request is and what is actually requested (specific type of posts, posts from the archive or from a category, etc.). The global object $ wp_query and conditional tags are further used in templates and custom code. Based on the conditional tags, the further selection of the template file for drawing also occurs.
In general, the approach in Drupal is more systemic and solid (the router is a single repository of paths and handlers), the approach in WP is simpler, and apparently evolved evolutionarily (for example, by adding new conditional tags), but nonetheless is quite flexible and customizable. The
WP_Query class
seems to be a very convenient mechanism for simple work with additional queries, and the pre_get_posts hook allows you to modify the main query.
Templates
The hierarchy of Drupal templates has the following structure. The template of the lowest level is html.tpl.php, which contains the main markup of the page with the doctype tag. Setting it up is done in relatively rare cases, because there are higher-level mechanisms for adding CSS / JS (even Google Analytics code is implemented by a
separate module ). Next comes page.tpl.php, which is inserted into html.tpl.php as a variable of $ page and defines the general structure of the page. The page.tpl.php defines the regions specified in the theme info file. There are no explicit concepts for header and footer in Drupal, logically they are “spread out” between html and page templates.
The system of regions in the theme is very convenient and flexible, you can define your own templates for the regions (the region.tpl.php template), there can be as many regions as you like, and a good basic set is provided by default. The page template contains the $ content variable, through which the actual content flows into the template. To display content that is represented in Drupal by entities of the type node (node), there is a node.tpl.php template.
For all the above basic patterns, there are default versions, i.e. The theme is able to live completely without templates in its folder, in this case, similar templates from the kernel and nuclear modules (for example, from the system module) will be picked up. To redefine it is enough to find and copy the template in the folder of your theme. In addition to standard templates, modules can define their own, as, for example, done in the Views module. Each template is supplied with a number of predefined variables (described in detail in the comments in the template), which can be changed and supplemented in functions of the process_page / preprocess_page type.
In general, the hierarchy of the theme templates Drupal has the character of "nesting", the field is embedded in the node, the node is embedded in the page, page - in html. Also, the substitution of one template by another occurs during specialization (for example, when node-15.tpl.php is used instead of node.tpl.php).
The WP hierarchy has a different character. All the basic patterns here are “full-sized”, i.e. contain doctype. Which template is applied depends on the current request and conditional tags. By tag it is determined which template to use. If, for example, a page is requested (is_page () == true), the system uses page.php, if the category is in the request (is_category), then category.php, if a separate blog entry, single.php is used, etc. . The central place is occupied by the index.php template, which is used to process requests for which no more specific template was found. Once upon a time this template was the only one in WP, and this central place remained so.
There are no default templates in WP, but index.php (as an “omnivorous” template) most often has a typical view with a WP loop (
loop ). In WordPress, header.php and footer.php templates are usually explicitly defined. These are the “raw” parts of html (opening header, in header.php, and closing tags in footer.php). To insert them, the get_header () and get_footer () functions are provided (therefore, the files should be called this way). It seems like a primitive, but simple and understandable. Drupal regions in WP correspond to Sidebars, they have their own sidebar-name.php templates and functions for their use dynamic_sidebar () (about sidebars and widgets a bit later).
In addition to standard templates in WP, you can create named custom templates that can then be applied to individual pages (when creating pages, the option to use templates appears if at least one exists).
To display the main page there is not quite (as it seemed to me) obvious logic based on several display options: a static page, a standard blog view or a custom template. Details can be found in
the WP code in the development section.
As you can see, Drupal templates are more systemic and easy to learn, and WP is probably more flexible and practical. Both here and there the hierarchy of patterns has to be studied in order to apply effectively. And there and there is a choice and the necessary flexibility to achieve the desired result.
Regions and sidebars
So, in the Drupal info file, the regions define regions, in the page.tpl.php file the placement of the regions on the page is determined, in the region - name.tpl.php templates the mark of specific regions is defined. This gives a clear structure and greater flexibility in the construction of the topic. After determining the regions, they are available in the admin panel for block placement. Blocks are visually isolated pieces of output to pages that can easily move between regions (for example, with a mouse in the admin panel). In essence, regions are created to house blocks and main content. A block can be typical (for example, “made on Drupal”), can be defined in any module using hooks (hook_block_info), or it can be created directly in the admin as an arbitrary html-code. For blocks, there is a template block - name.tpl.php.
Widgets in WP are exactly the same as blocks in Drupal. WordPress widgets are also typical (for example, “the site works on WP”), they can be created by plugins and themes (using the WP_Widget class inheritance and the register_widget function), and can be defined directly in the admin using html-code (more precisely, there is a standard widget, allowing to place arbitrary HTML code). The role of regions in WP is played by sidebars. Sidebars need to be registered in the theme in the functions.php file using the register_sidebar function. After registration, sidebars become available in the admin panel in the Widgets section and allow you to place widgets of various kinds. For sidebars, there is a default sidebar.php template, for additional “named” sidebars you can define sidebar-name.php templates.
In general, the regions and blocks in Drupal are somewhat simpler to use, but slightly, the functionality of the sidebars and widgets is completely similar.
CSS / JS connection
To connect JS in WP, the wp_enqueue_script function is used, and the wp_enqueue_scripts hook. The path itself is unique. If you want to control the connection, then logic is used, since hooks in WP require an explicit call to add_action (). There are several ways to connect JS in Drupal:
- connection in the theme info file
- connection by the drupal_add_js function (similar to wp_enqueue_script)
- connection via libraries API
- connection via attach in forms
- connection directly to the html.tpl.php template (not recommended);
The first way is the most convenient and logical, the second allows you to add logic when connecting.
Libraries API is a pretty handy thing that allows you to connect entire libraries (JS / CSS / PHP), with several versions and tracking which version is when to download. Libraries can be used with several themes.
For connecting CSS, the connection mechanisms are similar (replacing the script with style and js with css).
Content
For historical reasons, content in WP is called posts (post), content in Drupal is called nodes (node). In general, they have no particular differences, with the exception of nuances. For example, the two standard types of content in WP are the posts and pages themselves. Pages are not a subtype of posts, but are a separate type of content with their own properties. For example, taxonomy cannot be defined for pages. Pages are often used for static content, but can be defined according to a custom template, i.e. essentially contain anything.
Nodes in Drupal are all kinds of content, including pages. All content is initially available via links like “node / node_id”, for example “/ node / 12345”, thus all content is unified.
Content Types and Fields
Content types are subtypes of nodes and posts, respectively. For WP, the type of posts is simply determined by a certain marker-name and does not determine anything else. You can create posts with this “type”, you can pull them out of the database by type. For Drupal, the node type (bundle) is not only the name, but also, for example, custom fields that are attached by default to this bundle. In WP, instead of the fields in the basic functionality, there is meta-information - any key-value pair can be attached to a post (a specific post, and not the entire type).
A popular solution is to use the
Advanced Custom Fields (ACF) module, with which you can define field sets and attach them to content types, similar to the Drupal approach. In Drupal, this is done more flexibly, because the concepts of field and field instance are separated - an abstractly defined field and a field attached to a bandla. But in general, the practical possibilities are similar in the end.
Meta-information in WP can be attached not only to posts, but also to users, taxonomy terms and comments (functions add_post_meta, add_user_meta, add_term_meta, add_comment_meta). In Drupal, there is a generalized concept of an entity (Entity and Entity API), and fields are attached to entities that have a fieldable property.
Taxonomy
Taxonomy is the categorization of content using a hierarchy of terms. Both systems have full-featured capabilities for defining an arbitrarily complex taxonomy, since the idea itself is not too complicated. Both systems provide an advanced API for operations with dictionaries and taxonomy terms. The appearance of custom post types in the WP and hierarchical taxonomy is declared a fundamental change, due to which WP ceased to be just a blog engine and turned into a full-featured CMS. Perhaps you can agree with this, although there are quite a few WPs of the former “blog-oriented” WP (for example, the bloginfo function, WP_Post, sidebars, Loop itself, etc.).
Configuring content output
One of the most significant contrib-modules of Drupal -
Views - allows you to create pages to display the available types of content in almost any form. All this is convenient to configure from the admin panel, but if you wish, you can also from the code. In essence, when creating specific pages of a site on Drupal, the task of displaying content in the form of static pages, the entire node (through the node.tpl.php template) or view (that is, a block or page formed by the Views module) is solved. The view itself determines how the displayed content is generated, and the corresponding templates of the Views module determine the specific output markup. To redefine such templates, you should also copy them from the module to your theme.
An analogue of Views in WP can probably be considered the main mechanism for outputting content - a loop (loop). The loop uses the global variable $ wp_query to get the results of the query. Most of the standard templates use a loop and template tags (
Template Tags ), to display specific parts of the content (title, date, the actual content of the post, links to the post, etc.). In essence, the Drupal view object is a wrapper for this kind of loop, tuned using a structured array (which are so loved in Drupal).
It is difficult to say which mechanism is more convenient and flexible. Views can be created completely without programming, immediately getting a preview of how everything will be displayed on real content. On the other hand, more fine-tuning of views (from code through a view object and functions like views_embed_view) is clearly more complicated than setting the output of a WP loop. But then the already configured view object can be reused anywhere in the code, no need to repeat the loop code.
Speaking about the output of content using a set of templates, it is important to note one significant difference - until the very last moment (call the render () or drupal_render () functions) the format of the output of content in Drupal remains in the form of so-called
renderable arrays - structured arrays, which are easier to change, than the finished HTML string. Structured arrays are an interesting and convenient mechanism, although arrays grow with incredible dimensions over time (sometimes hundreds of thousands of elements), become recursive, include and re-include the same content, and sometimes even terrify.
APIs
Both Drupal and WP are constantly evolving and adding new features for programmers. In both systems, these capabilities are structured as separate APIs. Consider some of them.
AJAX API
Drupal provides a very interesting interface for working with
Ajax . The basic idea is to organize Ajax functionality as much as possible without writing any JavaScript code. This is achieved by introducing CSS classes like “use-ajax” (just assigning such a class to a button or link), as well as the standard ajax request handling mechanism (for all ajax requests, one typical system / ajax path). On the server side, using the functions of the ajax_command_ * series (for example, ajax_command_invoke), you can completely determine what will happen in the browser, right up to calling specific jQuery functions. The mechanism requires some time to master, but later allows you to effectively redraw the necessary pieces of DOM directly from PHP.
Separate consideration is deserved by the mechanism of
Drupal behaviors . According to the plan, this mechanism is intended to treat the JS code as some behavior that is turned on at the right time, not only when the page loads for the first time, but, for example, after redrawing a part of the DOM during an ajax request. Behavior gets the context (essentially the root element of the DOM where the changes took place) and can respond accordingly. The behaviors mechanism is useful and interesting if mastered and correctly applied.
The Ajax mechanism in WP is much simpler and only slightly different from basic ajax in principle in PHP. In fact, WP defines a standard path where requests are sent from JS (global variable ajaxurl to JS) and the mechanism for determining handlers via hooks. Ajax response is formed using the WP_Ajax_Response class, which simply creates the necessary XML code. You can also simply use the wp_send_json function.
Forms API
Drupal provides a fairly
powerful API for working with forms using structured arrays. In fact, any form in Drupal should be defined by the description of all its components, as elements in a structured array, and be displayed in a template using drupal_render. When defining array elements, you can specify many interesting things, for example, using the Ajax API mentioned above, including those required specifically for the JS / CSS form, you can create multi-page forms. Forms API (FAPI) supports input validation, several handlers for submit, the ability to redefine forms using hooks.
In WP, there is no such mechanism for working with forms; there are many plug-ins that help the admin panel draw feedback forms for sites and embed them into pages. There are
attempts to create something similar to Drupal FAPI. In general, it is somewhat disappointing that for such a basic functionality there are not even simple form helpers like Form :: open ().
More about the way
As already noted, Drupal routes (routes) are defined using hook_menu. Thus, you can set any possible paths (usual, in admin panel, Ajax, API, etc.) - the way is convenient and uniform. There is no such uniform method in WP, but there are two interesting APIs:
Rewrite , with which you can independently determine the rules for converting a path to a beautiful link, and the
WP REST API . The latter provides a real ready-made REST interface that allows you to receive data from the database, and also allows you to define any custom paths. In Drupal, there are no analogues to this API.
Entity API
Not so long ago, the
Entity API appeared in Drupal - a new level of abstraction over nodes that allows you to define entities that are not directly related to the content. Nodes, users, comments, and taxonomy terms have become special cases of entities. By connecting the
Entity API contrib-module (which for some reason is not included in the default set), entities can be effectively handled.
The main question is when and why to do it. They recommend everything that looks like content and has the look and feel as node types, and something more abstract and “invisible” on the screen - as entities. We can say that this is a tool for organizing a more complex Drupal application. For example, entities are actively used in Drupal Commerce for processing individual characteristics of an order.
There is no such abstraction in WP, so if you need to write something more intricate, you will have to either use custom post types or just have fun and write in PHP.
Data and Database Models
The data model in the CMS is built around content types. If the business logic of the application can be conveniently described using content types, then CMS is a good tool to use. Content type is an independent entity with a fixed set of attributes (among which there is something like title and description). It is desirable that different types of content are not related to each other.
It is most convenient to work with WP post types through the WP_Query object, as well as the get_posts () and query_posts () functions. If WP_Query's capabilities are not enough, then there is the dbDelta () function, which is designed to run any SQL queries, as well as the wpdb class, the capabilities of which are used through the global $ wpdb object. The wpdb class somewhat simplifies working with the database, but still you often have to write “raw” SQL, it does not provide any query builder features.
Drupal has several APIs for working with the database:
1. To work with the database structure (schema), there is a hook_schema and functions of the db_create_table / db_add_field type.
2. The drupal_write_record function as a simple way to write to the database.
3. The main API is a set of db_select / db_insert / db_update / db_delete / db_query functions, with dynamic query construction (
examples ).
4. For more convenient work with entities and fields, there is a class
EntityFieldQuery , which also allows you to make dynamic queries.
There are also attempts to adapt more serious Doctrine tools to CMS. Both for
WordPress and for
Drupal there are corresponding modules / plugins, but, apparently, not in active development. Apparently there is no urgent need for such tools, in view, again, several other data models.
Conclusion and conclusions
Consideration of specific opportunities for the programmer leads us to the conclusion that Drupal is a much more complex and equipped development system, at the same time requiring a lot of time to learn (which is not always the case and not everyone has). , Drupal- . Drupal, « », .
WordPress — , . WordPress , , . CMS, , .