Drupal vs. WordPress: A Developer Weighs In

By: Philip Jonas

As a developer, you know that the software development landscape has grown to astronomical proportions with no signs of slowing down. At times, it feels like remaining current is an impossible task. In this chaotic landscape, you need something that is simple to learn, easy to maintain, and robust enough to allow absolute control and customization, all the while offering the security you need. Faced with these stipulations, two main platforms come to mind: WordPress and Drupal.

WordPress and Drupal were released as open source frameworks in 2003 and 2001, respectively. Drupal was founded and is backed by Dries Buytaert. At the time of writing this article, 1.2 percent of the top 10 million sites use Drupal. WordPress, meanwhile, has seen incredible growth in usage, and as of January 2022, WordPress was being used by over 42 percent of all websites currently on the internet. It’s seen massive investments and growth with the help of the holding company Automattic.

One of the main differences between these frameworks is their core. Drupal uses the Symfony framework, and WordPress uses a custom framework incorporating its own WordPress Coding Standards.

In this article, you’ll see a comparison between Drupal and WordPress based on their plugins and themes, developer experience, ability to customize, community support, and hosting options.

Plugin and Theme Availability

With both WordPress and Drupal, the core features available are quite extensive. These features include core content management systems as well as media management tools for images. However, there is always the need for customization. These customization requirements are normally handled in isolation, away from the core code of the framework, which is why you need to create plugins or themes.

When looking at the stats, Drupal has a total of 18 premium plugins available for download on CodeCanyon, and 43,600 free plugins on the Drupal platform. However, if you narrow the search to only include modules that are actively developed, this number is reduced to about 15,000.

On CodeCanyon, WordPress has over 5,100 premium plugins available. There are also various mainstream plugins and themes that sell their plugins independently, including ElementorWordFence, and Yoast.

Moreover, WordPress.org includes nearly 60,000 free plugins on its repository, with thousands of premium versions available. Something interesting to note is that most premium WordPress plugins have supported versions of WordPress as old as v4.5.x dating back to April 2016. Premium plugins must always be maintained to support the latest version of WordPress.

Creating a WordPress Plugin

To create a WordPress plugin, make sure you have WordPress downloaded. Once you extract your WordPress site, you will be presented with the following folder structure:

Folder Subfolder Description
wp-admin Core of WordPress: DO NOT EDIT THIS FOLDER
wp-content Plugins, themes, and media uploads
└── languages Language-specific plugins and features
└── plugins Location of WordPress plugins
└── themes Location of themes
wp-includes Core of WordPress: DO NOT EDIT THIS FOLDER

In this example, the plugin will be called Hello World. To create it, follow these steps:

  1. Create your plugin folder: ./MyTestSite/wp-content/plugins/hello-world
  2. Create your plugin root file: ./MyTestSite/wp-content/plugins/hello-world/hello-world.php
  3. Open hello-world.php using your editor of choice (Visual Studio Code was used here)
  4. Update hello-world.php with the following code:<?php /** * Hello World * * @package HelloWorld * @author Philip Jonas * @copyright 2022 Philip Jonas * @license GPL-2.0-or-later * * @wordpress-plugin * Plugin Name: Hello World * Description: Allow for activating and deactivating * Version: 0.0.1 * Author: Philip Jonas * Author URI: https:// * Text Domain: hello-world * License: GPL v2 or later * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ /** * As good practice, if this file is called directly, the defined global * constant won't exist so that code will terminate. */ if ( ! defined( 'ABSPATH' ) ) { exit; } function helloworld_activate_plugin() { /** * Called once when activated. Pre configuration starting point */ } register_activation_hook( __FILE__, 'helloworld_activate_plugin' ); function helloworld_deactivate_plugin() { /** * Called once when deactivated. Process teardown here */ } register_deactivation_hook( __FILE__, 'helloworld_deactivate_plugin' );

Using this plugin code, you can see that there are two WordPress hooks called register_activation_hook and register_deactivation_hook. These hooks are called once per action for activating and deactivating a plugin.

In addition, the prefix helloworld_ was used on all the global functions. Prefixing global classes and functions (ie anything not wrapped in a class) has a global state. To avoid conflicts between themes and plugins, it’s good practice to add a prefix to all your methods and classes using your plugin name. When prefixing classes, remember to use title case (**HelloWorld**MyClassName) and sentence case for methods (**helloworld_**function_name()).

As a standard, all root functions and classes need to be unique, so using a prefix is the safest way to prevent duplication.

At this point, you can start adding custom features, including adding menu items using the admin_menu action hook with add_action("admin_menu", "helloworld_admin_menu"), or you can register new API endpoints that can be used in either the backend or the frontend of your site by using register_rest_route( $namespace, $route, $args = array(), $override = false ).

Creating a Drupal Module

To create a Drupal module, you need to have Drupal downloaded. Once you’ve downloaded and extracted it, you’ll be presented with the following root folder structure:

Folder Description
core Drupal core
modules Custom and contributed module installations
profiles Custom and contributed profile installations
sites ./[domain name OR default]/files: site-specific modules and themes
themes Custom and contributed module installations
vendor Third-party composer modules

In this example, the Drupal module will also be called Hello World. Follow these steps to set up a Drupal module:

  1. Create a folder called custom under ./MyDrupalSite/modules/ folder.
  2. Create a custom module folder called ./MyDrupalSite/modules/custom/hello_world/.

Note: As a standard for Drupal, use underscores and not hyphens.

  1. Create the module info YAML file in your hello_world folder using this standard: {YOUR MODULE SHORTNAME}.info.yml. Your info file will be called ./MyDrupalSite/modules/custom/hello_world/**hello_world.info.yml**.
  2. Open your info file located at ./MyDrupalSite/modules/custom/hello_world.info.yml and add the following code snippet:
name: Hello World Module
description: Simple drupal module
package: Custom

type: module
core_version_requirement: ^9.4 || ^10

dependencies:
    - drupal:link
    - drupal:views
    - paragraphs:paragraphs
    - webform:webform (>=6.1.0)

test_dependencies:
    - drupal:image

configure: hello_world.settings

php: 8.0

hidden: true
required: true

Following is a breakdown of the previous YAML settings file. You can find more info on their module development page:

YAML properties Description
name Is the name displayed in the admin console
description Provides the info on what the module does
package Allows the grouping of similar module types
type Identifies extensions moduletheme, or profile
dependencies List the modules that your custom module will depend on
test_dependencies Is required for specific automated tests
configure Sets a configuration form
php Gives the version of PHP required
hidden Hides your module on the extend page
required Identifies extensions moduletheme, or profile

For an in-depth guide on creating Drupal modules, check out their official documentation on creating modules.

Both these examples are scaffolds for creating a WordPress plugin and Drupal module. When working with Drupal, some knowledge of Symfony and its design patterns will make it easier for you to understand the code structure.

In contrast, with WordPress, the process is far simpler as its design patterns are easy to follow, even if you have little experience with PHP or programming in general. This is mostly thanks to the communities as well as the WordPress documentation.

Developer Experience

When deciding on a framework that will be used to develop your application, it’s important to understand the pros and cons of using a specific framework. This is where developer experience comes into play.

In regard to developer experience, you need to think about the general feelings and perceptions your team has about a platform and how they will interact with it. In addition, your developers need to understand the underlying codebase. Whether you choose to work with Drupal or WordPress, knowledge of PHP is required for both.

Usage of PHP

Both WordPress and Drupal use PHP. WordPress currently runs on PHP 7.4 or higher, whereas Drupal v9 requires PHP v8.0, and the upcoming v10 recommends the use of PHP v8.1.

Because of Drupal’s Symfony core, the barrier to entry requires some knowledge of how to work with Symfony as well as strict object-oriented programming (OOP) standards. It is a framework that is mainly used for large government agencies and large corporations. It is capable of handling large amounts of traffic mainly due to its hosting platform as well as complex systems and architecture with very large media and content libraries.

WordPress also has these capabilities but relies heavily on the optimization of content and hosting, but it also caters to a very wide array of implementations. These range from small blogger sites to media outlets and e-commerce systems. The underlying code and how PHP has been utilized allow PHP beginners to jump in easily and start developing, as well as allow advanced senior developers to use their own coding patterns and standards.

With both frameworks, the extensibility with the use of custom modules, plugins, and themes allows developers to build integrations into an application as well as distribution of content to other services and web applications. This can be accomplished by using the API capabilities of both frameworks.

APIs

WordPress and Drupal both offer robust Rest API interfaces. One of the main features of these APIs is that it allows you as a developer to interact with the CMS content outside of the Drupal and WordPress framework.

One of the key differences with regard to the APIs of WordPress and Drupal is that WordPress has it built into the core of the system. Drupal, however, requires an external module to be installed and configured for the different types of requests.

The implementation of the WordPress API has two separate areas: the backend and the frontend. The backend API calls are secured behind WordPress authentication tokens. There’s also a global configuration that allows you to enable and disable the visibility of these routes, but by default, they’re enabled.

Drupal, in contrast, uses a separate module to enable restful web services. These restful web services enable you to access all the content within your Drupal platform as well as an admin-based route for managing, creating, deleting, and editing existing content.

Both platforms offer similar benefits with regard to their APIs. This includes admin APIs for managing content and requesting content for display on the frontend. The latter allows you to build your own frontend using a framework of your choice, like React or Vue.js.

Customization

Both Drupal and WordPress allow for extensive customization. Drupal, by default, makes use of the Twig template engine.

A template engine or parser uses a data model from the server to generate content. It also allows for rapid development, especially where pages have multiple content blocks. This allows developers to separate each block of content to be reused elsewhere on the application. However, Twig is not the only templating engine that Drupal can use. Other popular engines include JadeEjsJinja2, and Mustache. WordPress, meanwhile, does not make use of a templating engine; however, any of the aforementioned engines can be used to build frontend templates for WordPress. The main problem with Drupal and template engines is that frontend development will need to start from scratch.

When developing WordPress themes, blocks can be declared in the theme, which allows for modifying each block’s styles using the styles editor in the admin console. This can be anything from headers, navigations, content layouts, footers, or UI elements, like text, buttons, and images. These themes are called block or site editor themes.

The benefits of using block themes include the following:

  • add_theme_support is replaced with the use of the Theme.json file
  • Enhanced loading performance because only the CSS for the relevant blocks is loaded
  • Style interfaces can customize typography and colors for blocks and websites
  • Accessibility features (ie keyboard navigation, content skipping) are generated automatically
  • No need to enqueue style sheets for frontend and the editor

WordPress, however, allows developers to build themes in any way they want. There is a file structure for themes that makes this process very simple, but there is also an extensive library of over 10,000 WordPress themes and page builder plugins.

Page builder plugins, like Elementor and Divi, with the use of specialized themes, like the Elementor Hello theme for the Elementor plugin, allow for full customization with complete device support from desktop to mobile without writing a single line of code.

With these two approaches of building your theme from the ground up or using page builders for the codeless approach, WordPress offers complexity as well as simplicity but complete freedom to how your site looks and functions.

Content Types

WordPress and Drupal come with a set of default content / post types. In both instances, these content types are a collection of settings relative to their use case. In WordPress, these content types are generally referred to as post types. Following is a list of default content types:

WordPress post types Drupal content types
Posts Article
Pages Basic page
Attachments Blog entry
Revisions Book page
Navigation menus Forum topic
Custom CSS Poll
Changesets

Creating a Custom Content Type for Drupal

Creating content types with Drupal is primarily done via the admin console. To create a custom content type, you first need to sign into your Drupal site admin console:

Select Structure in the navigation bar at the top and then Content Types:

Click the Add content type button and fill in the new content details page:

Set the configuration for Submission form settings:

Then set the Publishing optionsDisplay settings, and Menu settings, and click Save and manage fields:

Next, you’ll be directed to the Manage fields screen:

Creating a Custom Post Type for WordPress

When creating custom post types in WordPress, there are two ways to do it. The first is with a plugin called Custom Post Type UI. The second way is programmatically within a custom plugin or in your theme.

For example, here, you’re going to look at adding a custom post type from within your theme’s functions.php file. The functions file is a required theme file used by WordPress to execute functionality or register event hooks as soon as the theme loads.

Open your functions file located in your theme folder: **example**~/MyWordPressSite/wp-content/my-theme/functions.php`.

Add the following code to your functions.php file. It’s best to add it at the end of the file so that it doesn’t affect any of the core theme logic:


/**
 * Custom post type initialization hook
 */

function news_article_post_type_init() {
    /**
     * Labels for your custom post type.
     */
    $labels = array(
  'name'                  => _x( 'Articles', 'Post type general name', 'news-articles' ),
  'singular_name'         => _x( 'Article', 'Post type singular name', 'news-articles' ),
  'menu_name'             => _x( 'Articles', 'Admin Menu text', 'news-articles' ),
  'name_admin_bar'        => _x( 'Article', 'Add New on Toolbar', 'news-articles' ),
  'add_new'               => __( 'Add New', 'news-articles' ),
  'add_new_item'          => __( 'Add New Article', 'news-articles' ),
  'new_item'              => __( 'New Article', 'news-articles' ),
  'edit_item'             => __( 'Edit Article', 'news-articles' ),
  'view_item'             => __( 'View Article', 'news-articles' ),
  'all_items'             => __( 'All Articles', 'news-articles' ),
  'search_items'          => __( 'Search Articles', 'news-articles' ),
  'parent_item_colon'     => __( 'Parent Articles:', 'news-articles' ),
  'not_found'             => __( 'No articles found.', 'news-articles' ),
  'not_found_in_trash'    => __( 'No articles found in Trash.', 'news-articles' )
        // See https://developer.wordpress.org/reference/functions/get_post_type_labels/#description for a full list of labels 
 );

    /**
     * Custom post type arguments and settings
     */
    $args = array(
  'labels'             => $labels,
  'public'             => true,
  'publicly_queryable' => true,
  'show_ui'            => true,
  'show_in_menu'       => true,
  'query_var'          => true,
  'rewrite'            => array( 'slug' => 'news-articles' ),
  'capability_type'    => 'post',
  'has_archive'        => true,
  'hierarchical'       => false,
  'menu_position'      => null,
  'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
 );

    /**
     * Register the post type with the declared arguments.
     */
    register_post_type( 'news-articles', $args );
}

/**
 * WordPress action that triggers as soon as the WP core is loaded and initialized
 * and then registers the post type using the callback
 */
add_action( 'init', 'news_article_post_type_init' );

In this code, you create an action that fires the callback as soon as the WordPress core is initialized. Once it’s been initialized, you declare the labels that will appear when managing your news-article post types. Then you set up the post type settings and parameters before you register the post type in WordPress using the register_post_type method.

As you can see, Drupal provides a simpler and faster way to create custom content nodes, which can also be extended to using Drupal modules. From there, you can then easily create custom fields using the admin console.

With WordPress, the same simplicity to create custom post types can be achieved by using a plugin, but in general, it’s accepted to create these post types programmatically. Doing it this way achieves the greatest freedom to customize, enhance, and extend new custom post types, as well as existing ones, at the cost of extra development.

In summary, Drupal offers simplicity at the expense of flexibility, whereas WordPress offers some simplicity and incredible flexibility to customize all aspects of an admin console custom and existing post type.

Can Drupal and WordPress Run as a Headless CMS?

A headless CMS is a decoupled content management system that has no frontend. Basically, you can use any third-party framework on any device to request your content via your headless CMS API.

Both Drupal and WordPress can run a headless CMS implementation. For example, you can have a WordPress or Drupal CMS with no themes for the frontend and build a separate Next.js application. The difference is, WordPress has a built-in API as part of its core, whereas Drupal needs its API module installed and configured.

As widely recognized platforms across the world, finding solutions to technical problems online is easy, especially with platforms like StackOverflow. Searching for Drupal or WordPress yields similar results, between 100 million and 113 million code samples, 2 million and 27 million commits, and 200,000 and 700,000 submitted issues and features.

With live community groups on social media, such as Facebook, Slack, and Discord, communities for both groups consist of thousands of members willing to give answers and respond to feedback.

The WordPress forum and Drupal forum have an extensive amount of discussions; however, the WordPress forum is more active. In fact, some discussions are only minutes apart.

Hosting Options

When you compare the two platforms, WordPress is the more flexible CMS. You can make use of any form of hosting, including cloud hosting. Drupal, however, requires dedicated hosting and, by default, requires Apache or IIS web services. The reason for this is that some of the security features are relevant to these two web servers. But if you only have access to an Nginx web server, you’ll need to configure those security parameters yourself.

A few hosting companies listed on the WordPress.org website include WordPress.com, DreamHost, and SiteGround.

Drupal hosting options include PantheonAcquia, and A2 Hosting.

When you review the offerings, it’s clear that both tools are catered to the platform they will host. However, they all include performance-based hardware, security, and regular updates, as well as easy deployment for both CMS platforms. Some of the Drupal hosting platforms also include specialized WordPress hosting.

Conclusion

WordPress and Drupal both offer very powerful features. Drupal offers a model-view-controller (MVC) framework using Symfony, and WordPress uses a custom-built and powerful PHP core system that is extremely easy to customize using themes and plugins.

WordPress is used by over 42 percent of all websites on the internet, whereas Drupal only covers 1.2 percent of the top 10 million. While some consider WordPress’ large footprint a security risk, it’s also one of its greatest strengths. There is an entire community and team of engineers who place security at the forefront of their updates and releases. Moreover, these security features don’t just affect the WordPress core, but also extend to the premium and free plugins (60,000 free and over 5,000 premium) and themes (10,000 premium and countless free).

In contrast, Drupal makes use of Twig templates (a PHP templating engine) and is largely used to create themes from the ground up, with its preference to be deployed on dedicated hosting platforms, such as AWS or Google Cloud. Its security is largely left to the developers and DevOps engineers.

WordPress and Drupal both have a Rest API that can be used to build external applications without the need to use themes. This is where the headless CMS capabilities for both platforms allow teams to focus on client features without having to worry about the CMS side. In cases like this, developers can utilize frameworks like React, Vue.js, and even Blazor to create any application for any platform.

In the end, it’s all about ease of use, deployment time, security, as well as the creative freedom designers and developers have. And in all these cases, WordPress has more to offer than Drupal.