Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Jul 22 2021
Jul 22

A security audit is the process of identifying security threats that can lead to unauthorised access to content, data leaks, bypassing the security, and other dangers. In the first part of the series on conducting a security audit, we'll focus on the overview of the Drupal module versions that we use at Droptica for this purpose, as well as on PHP and JavaScript libraries.

Drupal security audit

At Droptica, we make every effort to ensure that the solutions we provide are as safe as possible. We use the tools provided by the Drupal community, such as the Security Review module, to optimize the process of detecting the most popular security errors. We also use the Security Kit to make the project we're working on more resistant to attacks. You can learn more about the functionality of these modules in the linked posts, and the information on their operation will be useful in the following parts, in which we'll talk about the Drupal configuration review and code analysis.

Checking the versions of the installed Drupal modules

Updating modules and libraries is the simplest activity that we can perform to improve the security of our application. Drupal provides a view listing all the modules, which additionally indicates whether a given module is up-to-date, and if it isn’t – whether the update contains security fixes.

To check if the modules are up-to-date, go to /admin/modules/update

Checking the versions of Drupal modules as part of security audit

In the screenshot above, you can see that some of the modules need updating. Of course, in such cases we always recommend that you update all possible modules. If any of the modules contain a security fix, the update is required to ensure a high level of security for the application.

In the case of Drupal, the information about whether a given module has a security flaw is made available to the public when the author of the module releases its patched version. Module authors usually try to hide which code has been changed to patch a security flaw, but this always means that the attacker just needs more time to find a way to cause the bug and exploit it. Time is important, so you should keep track of security updates regularly, not only during a Drupal security audit. As we mentioned earlier, this is one of the simplest steps we can take to ensure a higher level of security for our application.

Patches review

When updating the Drupal modules, you should also check if a patch has been applied to a given module. If so, we proceed as follows:

  1. We check whether the patch was created by the community and if it concerns a specific issue on drupal.org. If so, we look for the issue that the patch is from. It's possible that the patch has been applied to one of the newer versions of the module. In such a case, we recommend updating the module and removing the patch with the information that the code that fixes the bug or adds a given functionality has been applied to the official, newer version of the module. If the patch hasn’t yet been applied to the newer version of the module, we still recommend updating and testing if the latest version of the patch serves its purpose.
  2. If the patch wasn’t created by the Drupal community, but is the result of working on the project, we still recommend updating the module. In this case, however, ensuring the correct operation of the patch lies with the people responsible for the custom code of the project. After updating, you should check whether the patch works as intended. If not, we recommend introducing appropriate fixes to the patch which will ensure its correct operation on the latest version of the module.

PHP libraries review

The next step will be reviewing the used PHP libraries. To list them, we can use the composer show command or the local-php-security-checker package. We recommend the latter solution because it significantly speeds up the process.

Result of the composer show command during the review of the used PHP libraries

Result of the composer show command.

If you choose to install the local-php-security-checker package, follow the guidelines in the README.md file.

Result of the scan using local-php-security-checker during a Drupal security audit

Result of the scan using local-php-security-checker.

There's also the little-known Drupal Composer Security Checker module that uses the security-checker package. Currently, this module doesn't fulfill its task and the security-checker package itself isn't actively developed (since January 2021), therefore we'll focus on the local-php-security-checker package itself. If you find a security risk, our recommendation will be to update the library, of course – as in any case. An audit of the PHP libraries should be carried out regularly, the same as in the case of the Drupal modules.

JavaScript libraries review

The next step will be to check if the used JavaScript libraries are up-to-date and if they contain security fixes. To do this, you should review the library directory and the used package.json files.

In the case of the library directory, you need to check the version manually. In the case of package.json, we use the npm-audit command.

Result of the npm-audit command checking the package.json during the JavaScript libraries review

Result of the npm-audit command

The npm-audit command will list all known vulnerabilities, determine the threat level, package, dependencies, package path, and show a link with information about the vulnerability.

The npm-audit command shows all vulnerabilities in the JavaScript libraries

If you find a vulnerability, as always we recommend the update. JS library scans should be performed routinely, more often than a comprehensive security audit.

Improving the Drupal security - further steps

In this part of the Drupal security audit cycle, we've learned how to check whether the used versions of the modules and libraries are up-to-date and don't contain known security bugs. We also understand how to proceed if there is a patch available for a module – both when the patch comes from the Drupal community and when it was prepared by the developer working on the application.

Acquiring the knowledge provided in this post is the easiest way to improve the security of your application. Checking the versions of the used solutions is the first step that we perform during a security audit - our Drupal support team recommends periodic checking for updates. In the event that an update containing security fixes is released, we recommend that you perform an update as soon as possible.

In the next part of this series of articles, we'll get to learn more about the Drupal configuration aimed at increasing the security of our application. We'll also learn how to reduce the number of attack vectors and we'll find out more about the modules that'll help us with this.

Jul 16 2021
Jul 16

Many people probably wonder why system creators recommend regular updating to the latest version and why we are informed at every step by pop-ups that the latest patch or other fix has been released, sometimes changing only a few lines of code in the software. Using Drupal as an example, I'll try to explain why it's so crucial. Although the system works properly, it can contain many errors and surprise you with unstable work.

Why should you update your systems?

The first and most important reason why you should carry out regular updates (including the ones related to Drupal) is the security of the system itself. If the authors or the community discover a software flaw, with an update they can immediately fix it and protect users from threats (such as hacker attacks) that lurk at every step.

In the case of Drupal, new versions of the software not only protect you against dangerous attacks, but may also provide new functionalities. Usually options of this type appear in the "major" versions, such as 8.2, 8.3. You can check the update plan at any time on the roadmap on the Drupal website.

System personalization is important for every user and thanks to an update you can gain new modules or additional options that'll make your work easier. It's also worth keeping in mind that regular updates protect you from unnecessary programming work in the future, because the older your Drupal version is, the more difficult it is to install the latest update. Another advantage is the continuity of the webpage's operation, because you avoid time-consuming failures and minimise the risk of unstable system operation.

When is it worth performing an update?

As we've already mentioned, it's best to perform updates on a regular basis. As soon as you receive a notification about a new version or find out about it from another source, you should plan that update in the near future.

In the case of Drupal, updates are released approximately twice a month. You should also remember that monitoring the date until which support for a given version of Drupal is provided is sometimes a matter of several years. Therefore, you should bear in mind that every version has its "end of life" planned, and usually a migration to the newer version should be performed when updating. If you want to protect your system from hacker attacks and downtime, as well as keep the website running smoothly, you should remember to always use the latest version (or the one that is supported).

In addition, there are also updates of the modules themselves (depending on which ones are currently installed) and the PHP itself. In the case of modules, you don't always have to act so quickly, because when they are released, the information about what exactly has been fixed and who is at risk is provided. If the given problem doesn't concern you, you can do it at a time that's more convenient for you. You should pay attention in the case of PHP - it's worth acting quickly in this case, especially if the new release fixes security holes from the previous version.

To sum up, when you don't have time to install the latest update (such situations, unfortunately, sometimes happen), try to use a version that's currently supported. In the case of modules, you can take care of the ones you use most often first. This will ensure stress-free work and the certainty that you'll always be able to count on quick help in the event of unexpected errors.

Drupal update - upgrading to a higher version

A Drupal update within the same major version usually runs smoothly and doesn't cause many bugs. However, if you change major versions of Drupal, updating may be much more difficult.

Upgrading from Drupal 7 to 8

The update from version 7 to 8 can't be performed automatically, unfortunately. In most cases, you need to write the page from scratch. Drupal 8 has significantly changed the way content and configuration are stored in the database. Therefore, the database and other files must be transferred to the new page based on version 8. The configuration data include content types, user roles, and field definitions. You must also remember that not all modules have automatic update paths. Manual code tampering or custom migration will sometimes be required.

The structure of the themes has changed compared to version 7. This is another thing that needs to be rebuilt for the content to display properly in version 8. To facilitate this task, it's best to obtain the appropriate tools from the official Drupal website:

Another thing that'll help you migrate is an analysis of the Drupal modules. You need to determine which modules are most important to you (preferably in the form of a list), and whether their installation on Drupal 8 is really necessary. Also, remember to update Drupal 7 to the latest version. This'll make it easier to transfer the configuration and content data. The last step before the migration is to back up your current page, based on version 7. If anything goes in the wrong direction, you'll have a guarantee that you won’t lose the page and data.

Upgrading Drupal 7 to 8 is a complicated operation, but it brings many benefits.

  1. Lots of new features and modules have been added to the Drupal 8 core, e.g. Media and Layout Builder.
  2. Drupal 8 has access to more modern technologies - it uses more modern tools that facilitate an editor's work. Thanks to this, the configuration is easier and better adapted to people who are just starting their adventure with this CMS.
  3. In Drupal 8, part of the core is the Views module, which easily presents the added content to you in many different ways. In addition, the main page itself is a separate view, therefore you can easily manage individual elements.
  4. The core also includes the modules that provide new field types (such as phone, e-mail, link, meta tags, entity reference and contact forms).

In addition, Drupal 8 is much better suited for larger pages than Drupal 7, because it can be optimized (it has a much more advanced cache system, controlled by tags and contexts), which makes it smooth and fast to work with. It's based on the components of the Symfony framework, which is considered in the world of PHP development to be the best solution for creating complex applications.

Upgrading from Drupal 8 to 9

Drupal 9 doesn't differ significantly from version 8. One important piece of information is the upgrade to Symfony 4, which ensures compliance with the latest standards - thanks to this you can program in accordance with the latest specifications. Besides, Drupal 9 is an improved variant of the previous version. Some of the old code has been removed, Symfony and Twig have been updated, so you can be sure that the system will always work effectively and without any problems. The quick and easy update between releases (i.e. switching from 8 to 9) has also been kept. Also, the modules' updates will not require many additional changes. You should also keep in mind that Drupal 9 uses PHP 7.3 or higher versions.

The migration to the latest version will certainly require you to verify the application's code. You should remove the items marked as "deprecated" from it. You can use the drupal-check tool for this, which will automatically track down the obsolete code fragments. Then you can proceed with an automated process, the execution time of which depends on the page, and which will provide you with the latest version of the software.

How to test the system after the update?

One of the most important steps you should take after any software update is to test the introduced changes or the entire application or system. There are situations when an update is associated with data loss, system crash or unexpected errors. In the case of Drupal, you can, for example, use smoke tests. They allow you to check whether all subpages are displayed without critical errors. Another option is any visual tests that compare the previous look of the page to the new one. It would also be necessary to verify the operation of individual forms and modules and check whether the data entered on the pages is assigned to the correct fields.

To sum up, you should check the website both visually and functionally. Technically the page should work fine. You can correct minor changes to its appearance later.


Software, whether it is for a web page (as in the case of Drupal) or an operating system or other application, should be updated regularly. This ensures the support of the producer or creators and may protect you from any external attacks. In addition, you often have at your disposal new functions, modules or improvements that can significantly change your comfort of working with a particular system.

If you aren't sure how to update your CMS's version, find out how we can help you with Drupal support.

Jul 08 2021
Jul 08

Together with the contact page, the services page is one of the key parts of a website. It's also one of the basic elements of an effective business website. Presenting the scope of services is usually the main purpose of its existence. We'll show you step by step how to create a services page in Droopler - a Drupal distribution.

Pages created using ready-made components

Droopler is a website builder based on predefined components. Thanks to a set of ready-made parts, it's good for building company websites for organisations of all sizes. We can easily create with it a home page and each subpage. Depending on the needs and preferences, we can use photo and text components, a gallery, a contact form, emphasise some significant numbers or direct the users to other subpages with more detailed information, such as the offered services.

Building a services page from scratch

We'll start building a services page by creating a new subpage. To do this, after logging in, select Add content from the Content menu and then Content page.

Creating a services page from scratch in Droopler, a Drupal distribution

In the displayed view, we enter the title of the page. It'll be Services in our case. We also add "Teaser Image" and "Teaser text". In the options on the right, we select Provide a menu link, which will make the link to the new subpage appear in the top menu. We also enter the text that should appear as a link in the menu. It'll also be Services in our case. After filling in these fields, we deselect the Published checkbox so that our subpage isn't visible to visitors for this moment. We'll only publish it when it's finished.

Adding a title, teaser image, and teaser text for a new website in Droopler

Finally, we click Save and see this:

A view after creating a new services page in Droopler


Sidebar Image

Now we can start adding components. To access the library of available items, we click the "+" in a circle button. We'll see a menu with the available options. The first item we choose will be Sidebar Image.

The library of components available in Droopler


We select this paragraph and start filling in the fields. First, we enter the header (this will be the title of our subpage) and choose its type - H1.

Filling in the fields of the new paragraph Sidebar Image in Droopler


We add a photo and enter the text describing the subpage.

Adding a photo to a new services pageAdding a text describing a new services page


In the options found in the right tab, we choose which side the picture will be on. We select Right and click Save. The first component (section) of our services page is ready!

In the paragraph settings, we select where our image should be displayed on our services pageThe look of the ready Sidebar Image component


The next section will consist of links to individual services. To add this section, we'll start by selecting the Group of text blocks component.

Selecting the Group of text blocks component in Droopler


As in the case of the previous component, we enter the title and select the header type (this time it'll be H2).

Filing in the title and selecting the header type for the Group of text blocks


Below, we also enter the text that describes the given section:

The text describing a particular section of the Group of text blocks component in Droopler


The next step is adding the 4 tiles which are the links to individual subcategories of the subpage. In order to create them, we select the second Items tab and click Add single block text.

Adding the tiles which will serve as the links to the specific subcategories of the page


We enter the title of the tile and select the photo which will be its background.

Filing in the title of a tile which will be in the Group of text blocks paragraphChoosing a background for the tile from the Group of text blocks paragraph in Droopler


In the Call To Action subsection we enter the subpage which the tile should link to (in the format "/" plus "subpage name", e.g. /boats), as well as the link's text.

Filing in the URL address of a subpage to which a new tile has to link to, and a text which will be displayed on a link


We prepare the other 3 tiles in a similar way. When it's ready, we click Save and we see this:

The ready tiles in the Group of text blocks component in Droopler


Now it's time to embellish this section. Therefore we go to the paragraph's settings by clicking on the pencil button:

After clicking on the pencil button, we'll go to the Edit paragraph page


In the settings, we change a few fields:

Embellishing the Group of text blocks component


In the options for each of the tiles, we select:

Selecting the options for each of the tiles


We click Save and we have a ready section with subcategories for the services we offer.

The ready section with subcategories of an offer on a website built in Droopler


Group of counters

We move on to the next section of the page, that is a counter with interesting figures regarding the company. We'll use the Group of counters component.

Adding the Group of counters paragraph to the services page


Similarly to the previous sections, we choose the title, header type and background photo.

Setting the title, header type and the background photo for the Group of counters paragraph


In the Items tab, we add individual values by clicking Add single counter and entering a digit and a text. We create 4 such elements and click Save.

Adding individual values to the Group of counters component in Droopler


The finished section should look like this:

The ready section Group of counters on the services page


Text page

The last element that we'll add to the services page will be a call to action. We add this simple section using the Text page component.

Adding the Text page component to the website in Droopler


As in the case of the previous steps, we select the header, "long text" and define the button.

Defining the details of the button that will be in the Text page paragraph


A ready services page in Droopler

The services page is finished. We only have to select Published in the selection field in the main options of the subpage. Now everything is ready and available online for the visitors of our website.

Publishing of a new services page

The whole Services subpage should look like this:

The ready services page in Droopler


You can see the created subpage in the Droopler demo. We build other subpages in a similar way. We encourage you to experiment with the options and different components. The multitude of available possibilities allows for personalising the page in a simple and quick way, without the need for coding.

Jun 24 2021
Jun 24

Droopler offers the ability of building a professional webpage using ready-made visual components. This website builder can also be customized to your individual needs. In the text below, we’ll present some examples of pages created with Droopler.

Meet Droopler - a Drupal distribution

Droopler is a Drupal distribution – the version of this content management system extended with add-ons that are configured in such a way as to meet the business objectives of the web page right after installation. Thanks to utilising modules such as Paragraphs and Geysir, it can be used as a page factory, e.g. for landing pages promoting products or for various language versions of a company website. Other advantages are the built-in SEO support and the appearance of the pages adapted to mobile phones and tablets.

What are the benefits of choosing the right distribution? There are many of them, but the most important ones are the following:

  • you don’t have to browse, select and install every module separately, which shortens the time needed to build a page, and it also starts to earn money faster;
  • its further development or modifications are possible to perform; you can do some changes by yourself, whereas Drupal developers can help you implement individual solutions.

In the case of Droopler, another advantage is the ability to use a wide range of paragraphs (because that is another name for components). You can learn more about them in the documentation of this tool. Below, we present the use of these elements on examples of specific pages.

Portamet - photos catch the eye

The website of Portamet, a company operating in the carbon steel and glass products industry, uses many of Droopler's visual components. When browsing this site, it's impossible to ignore the paragraphs devoted to individual projects, business solutions and realizations. The page’s author used the Tiles Paragraph component, thanks to which you can put text on one side of the screen and photos on the other. Such a solution catches the eye. Moreover, when you hover the mouse cursor over a graphic element, its title is highlighted, and when you press it, a larger view opens. Then if you want to present your portfolio in an attractive way, it’s worth taking a look at the Portamet website and see the solutions used there.

On the Portamet website, we can see the Tiles Paragraph component from Droopler

Source: Portamet

EKO-HOME - products’ showcasing

Still on the subject of presenting one's own offer, the author of the page of EKO-HOME - a manufacturer of external roller shutters and gates - in addition to the already mentioned Tiles Paragraph, used several other components. The Sidebar Image Paragraph deserves particular attention. It highlights a single photo, next to which there's a space for a description.

The element Sidebar Image Paragraph visible on the EKO-HOME website built with Droopler

Source: EKO-HOME

At the bottom of the page, you can see logos of the company's partners, presented in an interesting way. Instead of a static list, there's a dynamic presentation within which the graphic elements move automatically. You can also scroll through them by pressing the arrows. Such an effect can be achieved using the Carousel Paragraph.

An interesting usage of the Carousel Paragraph in the section with partners' logos on the EKO-HOME website

Niewczas Strawberry Plant Nursery - customized use of Droopler

We’ve already mentioned photos, now let's start with a movie. The strawberryplant.eu website, belonging to a company dealing with professional strawberry cultivation, uses the Sidebar Embed Paragraph with a video in the About us section. To upload a video from YouTube or Dailymotion, you just need to copy the iframe code to Droopler.

The website of Niewczas Strawberry Plant Nursery uses the  Sidebar Embed Paragraph with a video

Source: Niewczas Szkółka Sadzonek Truskawek

Another ready-made Droopler solution used on this page is the Counters Paragraph. It's an attractive form of presenting numbers that are meaningful for the company. The most important thing is that they appear dynamically.

The Counters Paragraph component from Droopler used on the strawberryplant.eu website

The Side By Side Paragraph also looks very nice. This component allows you to achieve the effect of several alternating blocks of text and graphic elements.

The Side By Side Paragraph component from Droopler is perfect for the alternating blocks of graphic elements and text


This highly attractive website is also an example of extending Droopler's capabilities with the help of a developer. The next paragraphs appear as you scroll down the site while browsing the home page. On the other hand, the subpage with the offer, besides of the blocks with graphic elements, attracts attention with the filtering option. The result is a narrower display of these blocks. There's also the Blog section with a very clear content layout and visible extracts of articles.

We encourage you to spend some time on this page, because it can be a unique inspiration for creating your own site.

Be Happy Music Club - video as the most important part of the page

In the previous example, we started with a movie, now we'll do that again, but a bit differently. That's because a video fills the entire Banner Paragraph on the home page of Be Happy Music Club - an organisation whose mission is to improve the well-being of disabled children and to promote social integration through music programmes. Probably due to the noble objectives of the site, the video was put at the beginning, and the slow-motion playback successfully strengthens the effect and attracts attention.

The video in the Banner Paragraph plays a main role on the Be Happy Music Club website, built with Droopler, a Drupal distribution

Source: Be Happy Music Club

We haven't yet covered the Gallery Paragraph, which appears below. Of course, the number of photos in this component is unrestricted, and in the case of this page the authors also added a button. We mention it because, depending on individual needs, it's sometimes worth including such a call to action under the presentation of graphic elements.

The Gallery Paragraph component with three photos, texts and a call to action button

At the bottom of the page, we can see the Counter Paragraph we already know, although in a narrowed version (yes, you can define the number of individual counters).

The Counter Paragraph on the Be Happy Music Club website created in Droopler, a Drupal distribution

We'd also like to highlight the Our People section and go back to the subject of photos. Not only the Gallery Paragraph, but also, for example, Text Blocks can be used as a component for team presentation (and not only). The upside is the ability to put text under the selected photo.

The Our people section on the Be Happy Music Club website, based on the Text Blocks component from Droopler

A similar procedure has been applied on the Be Happy Music Club website in the Supporters tab.

The usage of the Text Blocks paragraph on the Be Happy Music Club website


9/11 DAY - emphasised movie about good deeds

Finally, we'll look at the 911day.org website, run by a foundation that encourages doing good deeds as a tribute to those killed and injured on 11 September 2001. On the home page, the video is even bigger than in the previous example. It even overlaps the menu, which is separated by a thin line, which delimits two zones, gives the impression of order, and the whole thing is visually attractive. Thanks to the two visible buttons, the user can go from this place to the subpages they are interested in.

A big section with a video on the 911day.org website, built in Droopler

Source: 911day.org

Also worth noting is the custom search engine for volunteer work options, which can be searched by keywords and location.

The search engine for discovering volunteer work options on the 911day.org website. You can search using keywords or location.


Of course, it's also integrated with a payment gateway.

Integration with a payment gateway on the website created in Droopler


911day.org is an interesting example of a website built on Droopler that only gets traffic during certain periods of time. If you are interested in how to set up a website so that it works properly in such conditions, we encourage you to read the article on how to prepare your site for the occasional spikes in traffic.


Droopler is a Drupal distribution that - as you can see in the examples above - is flexible and non-limited. With its help, you can create your site based on the existing paragraphs, and additionally use Drupal modules that meet specific needs. Did you like the examples of pages in this article? If so… #MeetDroopler.

Jun 04 2021
Jun 04

Creating a dynamic PDF file is one of the most important points of a project. The crucial thing is to find the right solution that meets your expectations and requirements. In this article, we’ll show you one of the most popular PDF generation modules for Drupal that will be helpful for you to generate, view or download reports, articles, and invoices in PDF.


The first version of the module was released on 22 January 2015, the latest update - 18 June 2020.

The module can be installed on:

  • Drupal 7 (7.x-1.5 stable release version),
  • Drupal 8 and 9 (8.x-2.2 stable release version).

All stable releases for this project are covered by the security advisory policy.

Module’s popularity

According to the usage statistics from the module's page, it’s currently used by around 12 thousand websites.

Module’s creators

The module is created and maintained by benjy.

What is the module used for?

Entity Print allows you to print (save) any Drupal entity (Drupal 7 and 8) or View (Drupal 8+ only) to a PDF file. It uses the PDF engines based on popular PHP libraries like Dompdf, Phpwkhtmltopdf and TCPDF.


  1. To install Entity Print, go to its webpage or do it via composer: 
    composer require "drupal/entity_print 2.x"
  2. Install Dompdf by running composer require
    composer require "dompdf/dompdf:0.8.0" 
  3. Additionally you can install Wkhtmltopdf and TCPDF engines.
    composer require "mikehaertl/phpwkhtmltopdf ~2.1" 
    composer require "tecnickcom/tcpdf ~6" 
  4. Enable the Entity Print module.
  5. Grant permissions for non-admin users to download the PDFs.
  6. Optionally, enable the Entity Print Views module.
The installation settings of the Entity Print Drupal module


Configure Entity Print

Let’s check what this module allows us to configure.

  • Enable Default CSS - provide some very basic styles.
  • Force Download - force the browser to download the PDF file.
  • PDF - select the default PDF engine for printing.
  • Paper Size - change page size to print the PDF to.
  • Paper Orientation - change orientation to Landscape or Portrait.
  • Enable HTML5 Parser - Dompdf doesn't work without this option enabled.
  • Disable Log - disable Dompdf logging to log.html in Drupal's temporary directory.
  • Enable Remote URLs - must be enabled for CSS and Images to work unless you manipulate the source manually.
  • SSL CONFIGURATION - may be needed for development only, in production you shouldn’t change it.
  • HTTP AUTHENTICATION - if your website is behind HTTP Authentication, you can set the username/password.
  • EPub - select the default EPub engine for printing (currently not supported, you can follow the opened issue).
  • Word Document - select the default Word Document engine for printing (currently not supported, follow the opened issue).
The Entity Print module's configuration


The preferable PDF engine is Dompdf, which is (mostly) a CSS 2.1 compliant HTML layout and rendering engine written in PHP. It’s a style-driven renderer so it’ll download and read external stylesheets, inline style tags, and the style attributes of individual HTML elements. It also supports most presentational HTML attributes.

Module’s use

After the module is configured properly and all permissions are set, we can start exporting entities and views to a PDF file.

Exporting entities

Entity Print adds a disabled field to the view modes of each content type. The field has a default label value of "View PDF". To make this field visible on any content type, enable it on the Manage Display page


Enabling the View PDF field on the Manage Display page of the Entity Print module

From now, we’ll have a view PDF button added to our content type. The URL button is:


(i.e. https://example.com/print/pdf/node/1)

View PDF option visible in a PDF file


Here is the PDF we want to save or print:

An example of a PDF file to save or print in the Entity Print Drupal module


Exporting Views

With the Entity Print Views module enabled, a "Print" Global option can be added to the View's header or footer.

The URL button looks like:


Adding a Print Global option to the View's header in the Entity Print module



For easy and quick debugging, Entity Print provides us a HTML version of the entities sent to the PDF engine. The URL looks pretty much the same as above only with /debug appended.

E.g. https://example.com/print/pdf/[entity_type]/[entity_id]/debug.

How to hide the View PDF link in the exported file

By default, the "View PDF" link is also added to the PDF. To remove it, go to the Manage Display page for the specific content type. On the Custom Display Settings section you need to enable the PDF view mode.

Custom display settings in the Entity Print module


Now you can disable the Entity Print field on that view mode. Next time you export the PDF, you won’t have the "View PDF" link included.

By default, the PDF view mode is installed for Nodes only. In case you have any custom entities, you must first create a PDF view mode for the specific entity type via "admin/structure/display-modes/view". You can name it whatever you like but remember that a machine name should be "pdf", as it will be automatically prefixed with the entity name.

Styling the PDF from your theme

The following examples show how to register entity_print CSS files from your_theme_name.info.yml file. You can do it for any entity type or even view.

#Add css library to all nodes:

    all: 'YOUR_THEME_NAME/print-styling' 

#Add css library to the Node entities but only article bundles:

    article: 'YOUR_THEME_NAME/print-styling' 

#Add css library to all views:

    all: 'YOUR_THEME_NAME/print-styling' 

Don’t forget to define a CSS library in your YOUR_THEME_NAME.libraries.yml:

print-styling: version: VERSION css: theme: css/print-style.css: { } 


Modifying templates

All the normal ways to override templates are available. Using theme hook suggestions, you can create a Twig template and modify the content of any specific entity (e.g. node--blog-post--pdf.html.twig). In this template, you can modify the markup as you normally do by using {{ content.field_example }} or {{ node.field_example }}.

You can modify the HTML output of the entire Entity Print template. Just copy the entity-print.html.twig file from its base location into your theme folder. Using theme hook suggestions, you can also create entity-print--node--[content-type].html.twig file.

   {{ title }}
   {{ entity_print_css }}

{{ content }}

Make sure the {{ entity_print_css }} is always included inside the tag tag head in your custom Twig template file. Otherwise your custom CSS libraries won’t work.

Custom PDF Engines

It’s worth mentioning that the Entity Print PDF engines are pluggable. It means you can easily implement your own engines. To do so, you need to create a class in your_module_name/src/Plugin/EntityPrint/NewPdfEngine.php that implements Drupal\entity_print\Plugin\PrintEngineInterface with its all required methods. After that, your plugin will be available in the engines select list on the configuration page.

Alternative solutions

There are a few other options for making a PDF of an entity in Drupal that you might want to investigate.

PrintFriendly & PDF is a plugin for Drupal 7, 8 and 9. Below you can see its features list:

  • It’s fully customizable.
  • With the On-Page-Lightbox option, the PDF file opens in a Lightbox.
  • It lets you print or get a PDF.
  • You can edit the page before printing or getting a PDF, for example by removing the images and paragraphs you don't need.

Printer and PDF versions for Drupal 8+ is a module that also works for Drupal 9. It allows you to generate the following printer-friendly versions of any node:

  • webpage printer-friendly version (at /node/[node_id]/printable/print),
  • PDF version (at /node/[node_id]/printable/pdf).

Supported libraries:

  • mPDF,
  • TCPDF,
  • wkhtmltopdf,
  • dompdf.


The Entity Print module provides multiple methods of exporting entities to PDFs via different PDF engines. It is a very flexible and customizable module which will help you in dynamic generation of your articles, invoices or other content related to your Drupal website. The module has full test coverage and is ready to be used in production for Drupal 7, 8 and 9.

Jun 03 2021
Jun 03

Modern websites have become more and more extensive. At some point, a user may feel confused due to a large amount of content. At the same time, the website itself starts to be hard to use. Then the need to create a convenient, easy to develop, and maintain navigation appears. The solution which will work great in this case is a mega menu.

What is a mega menu?

A mega menu is a type of navigation consisting of several levels, used on websites. The first level looks like a standard list of links, but after hovering over one of its elements, additional options are shown. These options consist not only of a list of links in the second level of navigation but often have a third or even fourth level. Sometimes there are also visible photos or even videos. A menu built in this way is visually appealing to the user and allows them to easily find their way around large websites.

Below you can see the example of how the mega menu works on the webpage built in Droopler.

Mega menu in Drupal on the example of a website created in Droopler, a website builder


Mega menu in Drupal

In the Drupal CMS, creating a mega menu is quite a difficult task. That’s why the modules that simplify building advanced navigation were made. One of them is Mega Menu. Not only will it save you countless time creating and customizing complex navigation, but at the same time make your website amazingly impress your users.

Here’s how the Mega Menu module works: based on the default Drupal menus, the configurable mega menus are created. We can add to them submenu or even the whole blocks, using a friendly configuration interface. The additional option is the possibility to add a few columns in the submenu, setting styles, and animations.

Creating an extensive menu in Drupal, using a Mega Menu module

Source: Drupal.org

However, it’s important to mention the downsides of Mega Menu. One of them is that the module uses a separate Bootstrap library. This not only increases the size of the CSS and JS files, but also conflicts with the Bootstrap library used on the websites. The second disadvantage is that the navigation built with the Mega Menu module is poorly optimized for mobile devices.

In Droopler, a Drupal distribution, we rewrote the frontend part of the module from scratch. This way, we eliminated the most significant downsides of the default Mega Menu module. On the example of Droopler, we’ll show you how you can create with this module an extensive menu for your website.

Creating an extensive menu in Droopler

Droopler is a Drupal-based distribution dedicated to building corporate websites. It contains ready-to-use elements and tools enabling quick creation of the websites.

Main menu configuration

We can find the main menu settings in the Drupal administration menu in Structure. Next, in Drupal 8 Mega Menu, we look for the Main navigation element and from this element's menu, we go to Edit links.

Configuration of main menu in the Drupal administration menu

After going to the edit page, the working structure of the main menu appears, which we can freely edit using the "drag and drop" method. To add more levels to the menu, we need to move the secondary element to the right to create an "indentation".

Adding new blocks

To add a block to the menu, we must first add a new content block. We go to Structure -> Block Layout -> Add custom block and select the content block.

Adding a new content block to the menu

The system takes us to a form, where we add a new block. We fill out the title and the content of interest. In this case, it’ll be the title and a few links. Next, we add another block with the content and photo.

Editing a custom block in Droopler


After adding two blocks, we need to add them to the region on the page and - at the same time – disable the display of these blocks in the region. In the Block Layout of the header section, we click Place Block, and then select from the popup window the block we want to add and click Place block. In the next step, we uncheck the show title option and save.

Adding new blocks to the region on the page


When the blocks are added to the region, we should disable them. To do this, we click Disable in the block's action menu.

Disabling display of new blocks in the region


After completing this step, we can start adding blocks to the menu. To do this, we go to Structure, Drupal 8 Mega Menu, and then click config next to the main navigation.

We are taken to the menu edit. In our case, we’ll add blocks to the "products" element. After clicking "products", a configuration panel appears on the right. We check the Submenu in it as active.

Activating the Submenu in the configuration panel of the mega menu in Drupal


Now a workspace appears under "products", where we’ll add our blocks in a moment. After clicking on this element under "products", another configuration panel appears, but this time it concerns our workspace.

The configuration panel of the workspace


In this panel, we use the plus and minus buttons to set the number of columns in our mega menu. In the Grid field, we set the column’s width, while the Blocks field is used to select the previously added blocks.

After setting the appropriate options, we click Save and our menu should look similar to the one below.

The ready mega menu built with Droopler, a Drupal distribution, and the Mega Menu module



A mega menu is a good option for presenting to the user an advanced website’s structure or a web application. With the Droopler distribution and the Mega Menu module, we can easily build the advanced pages with a user-friendly navigation which allows us to clearly show the structure of a large website.

May 27 2021
May 27

Virtual business card, flyer, minisite – all these terms perfectly reflect the nature and essence of landing pages. They consist of several horizontal segments in which advertising content is presented, encouraging you to continue exploring a given topic on other dedicated and full-sized webpages. Let's check the possibilities Drupal gives us when creating these specific websites.

A page made of blocks

To create a one-page website composed of horizontal segments – clearly separated from each other, yet forming a consistent whole – we can use several tools or modules available in Drupal's core. The first option that comes to mind is using blocks. In Drupal, blocks work just like Lego bricks, elements containing any content. They can be displayed in different regions of the page, one above the other. Sounds like something we need!

While the idea of using simple blocks, mainly containing text, will work great in this case, achieving visual requirements or the desire to include slightly more complicated content (e.g. counters, multimedia, combination of text and multimedia, carousel, etc.) seems to be time- and labour-consuming. A high level of block personalization will require us to create several block types and/or content types and additional fields from scratch, along with additional classes for a purpose of a correct display.

For the proponents of clean code - Twig

One of the available solutions is also the option to create a twig collection, where – using the HTML and PHP code – we are able to create a landing page with any level of complexity, using the available or new fields. This option, however, requires us to spend many hours in front of the screen, countless lines of code, not to mention the subsequent maintenance and content management. To implement this solution, one definitely needs a person with technical knowledge – also at the stage of introducing the content.

Creating a Drupal landing page - modules

As we mentioned earlier, a landing page in Drupal can also be built using modules. Let's check out which of them we can use and how.

Layout Builder module

A very useful tool that has been recently added to Drupal's core is the Layout Builder module, which allows you to create templates for the structure of displaying elements on a page. The user has the ability to define their own "regions" for different types of content, using a very helpful drag and drop interface. In simple terms, it replaces the default display management function, which defines how and which fields are to be displayed, and additionally gives the opportunity to put blocks in place. When creating a template, you can feel like a graphic designer juggling the elements, while all the tools they need (in our case – the options for editing blocks and sections) are at hand in the form of an edit bar. To use this module, you need to launch it manually, as it isn’t enabled by default when installing Drupal.

When creating a new content type or wanting to use Layout Builder for an existing one, go to the display management tab. An additional "Layout options" section will appear below the list of fields, where we select the "use Layout Builder" option. Instead of a list of fields, a "manage display" button will be added, which will redirect us to the Layout Builder interface. We can freely manage the order of elements, add blocks that may contain fields from any entity, forms, plain text, links, views, and even an entire menu. Blocks are added within sections. Each section can be arranged into any number of columns between 1 and 4. The order of sections can't be changed or "dragged", so be careful when adding them.

Creating a Drupal landing page with the Layout Builder module


Unfortunately, Layout Builder won’t do everything for us. We need to put more effort into styling all the elements. There is, however, an additional module – Layout Builder Styles – dedicated to creating new classes for Layout Builder blocks and sections, with the ability to define restrictions concerning which blocks a given class will be assignable to. A beta version is currently available, and our Drupal installation can’t be older than version 8.7.7. However, to take full advantage of the style management capabilities, without having to interfere with the code, we need to install one more module - Asset Injector, where we'll define all the parameters of the previously created classes. Then, when editing every block or section, we'll be able to assign one class available on the list.

Styling the elements of the landing page using the Layout Builder Styles and Asset Injector Drupal modules


Paragraphs module

The second most frequently chosen option when creating a Drupal landing page is the use of the Paragraphs module along with Entity Reference Revisions. Paragraphs allows you to create templates that will later be sections (aka paragraphs of a page). One paragraph may consist of many fields of any type. Such a collection will constitute the type of paragraph to be used by any selected content type. For example, let's create a new content type named "Landing page". At this stage, in addition to the default "body" field, we add a few other fields that are important to us. This time, we only need one field of the paragraph type.

Adding a paragraph field to a content type during creation of a landing page using the Paragraphs module

Now we'll create two new types of paragraphs: “banner” and “image + text”. Under Structure -> Paragraph types -> Add paragraphs type, we create new types of paragraphs and manage the fields to be included in them. For a banner, it'll mean an image field. For the “image + text” type, it'll also mean an image field and formatted text. As is the case when creating content types, with paragraph types we can manage the display of fields and their formatters. You'll surely notice in the list that you can add a field of the paragraph type, this way we can create nested paragraphs and use the already existing ones.

Creating new types of paragraphs with the Paragraphs and Entity Reference Revisions Drupal modules

Having the types of paragraphs, let's check out what the landing page creation will look like. It's worth mentioning that without defining in the content type settings what specific paragraph is to be its content, we are presented with a list of all available paragraph types, which we can add multiple times thanks to setting “unlimited” when creating a paragraph field.

Creating a Drupal landing page with the Paragraphs module


Paragraphs is a powerful tool that allows you to maintain a high degree of flexibility when creating landing pages. The pitfall when using this module is managing the content later, especially if we create a complex structure with multiple nested fields. The person editing the content on the page may then feel lost and overwhelmed by the enormity of tabs and settings.

Tuned-up paragraphs. Creating a landing page in Droopler

If you like the option of using paragraphs the most, you'll surely find what Droopler has to offer for creating one-page websites to be even better! Droopler is our free Drupal distribution for creating webpages. It contains many ready-made templates and components.

For this tool, we used the idea of creating paragraphs and nested paragraphs to "assemble" a webpage. In the default version, along with the Droopler installation we get a number of predefined types of paragraphs at our disposal. These are the most commonly used kinds of paragraphs when creating webpages.

Types of paragraphs in Droopler, a free Drupal distribution

Types of paragraphs in Droopler

Then why should we use Droopler and how does it really differ from the previously presented possibilities offered by the Paragraphs module, apart from saving time when creating the most popular types of paragraphs?


Already at first glance, we can see one fundamental difference – the added paragraphs look professional and, if we are satisfied with the used colour scheme, we don't have to do anything else with them! However, if we decide to change it, overwriting the default skin won't be a problem. You can find more information on this topic here.

Editing directly on the created page

I mentioned earlier that it can be confusing to navigate around editing a content type that consists of paragraphs. This problem has been solved in Droopler thanks to using the Geysir module and the possibility of editing paragraphs directly on the created page, in the form of modal windows. The interface also allows you to “cut” and “paste” paragraphs, that is, to reorder and remove them without having to go to a content type edit page. This way everything remains clear and we immediately see the effects of our changes.

Possibility of editing paragraphs directly on the created page in Droopler


Additional options

The Paragraphs module is field-based, allows you to choose the formatter and manage the display, but there is no room anywhere for additional options related to styling or quick reorganisation of the content within a single paragraph. If we want to have a paragraph with an image gallery, we need separate types for putting 4 or 8 thumbnails. The same happens when using different types of media – a separate type is needed for images and videos.

Droopler is highly flexible in this aspect. The banner paragraph type accepts both an image and a video file. What's more, for every type of paragraph in the "settings" tab in the adding paragraph window, it's possible to configure margins and padding, as well as to define additional classes that we determine in our skin, and there's even the option of choosing a predefined colour scheme.

While editing a paragraph in Droopler, you can configure margins and padding, as well as define additional classes


If we want to create a paragraph composed of tiles, we can choose which of them should be highlighted by increasing their size in relation to the rest, achieving the effect of a "masonry" gallery.

Do you have a prepared block that you'd like to use and place among the paragraphs? In Droopler, paragraphs can also consist of blocks, in the tab we can choose from among all those that currently exist on our page. The block with icons and links to social media - ready. A quick contact form? This has also already been done for us.


Landing pages or one-page websites are a very specific type of content that we can find around the web. It should be simple, transparent, look modern and encourage us to go to the further, target pages. It's a huge tool in the hands of marketing teams, so Drupal was also designed to give users, including non-programmers, the option to quickly create these kinds of pages. Some of the methods presented in the post show a low degree of difficulty and can be implemented by a layman (Layout Builder, Paragraphs). However, they have their limitations and at some point the "architecture" created with them becomes too complicated and difficult to maintain. Additionally, the intention to create something non-standard will require the help of a developer, especially for styling. By choosing Droopler, we can be sure that the landing page creation process will be simple and pleasant, as well as visually effective, without having to tamper with the code. Anyone, without exception, will be able to learn to manage paragraphs with ease, and in less time than expected.

May 21 2021
May 21

The homepage is the most important element of a website. The first impression of the user depends on it – whether they'll stay on the website, whether they'll be interested in the company's offer and the company itself. In just a few simple steps, we'll show you how to create a homepage that will help you keep your visitors' attention.


What elements should a homepage contain?

A prospect enters the homepage. You have a few seconds to interest them and make them continue to check out your offer. How can you do that? You need to correctly convey the most important information that will immediately answer the customer's questions.

Banner with a call to action

First of all, you need to briefly describe what your company does. This type of information is often displayed in a banner at the top of the page. In this section, you can add a CTA (Call to Action). It's a link which when clicked redirects the user the destination area, e.g. to the next section of a page or to a contact form.

Blocks with content

You should also put blocks that contain information about what your company can offer to a potential customer and why they should choose your offer. Various types of representing information are suitable for these purposes: from simple text blocks to advanced interactive carousels that allow you to put more content into a fairly tight framework of one block.

Once you know what elements to put on the home page, the matter of creating the page in a fairly quick and easy way arises. Website builders – one of which is Droopler – are suitable for solving such a problem.


Create a homepage in Droopler

Droopler is an open source website builder based on CMS/CMF Drupal. It contains ready-made components and tools that allow you to quickly create modern webpages. Droopler is simple to edit and easy to expand. Let's try to create the most important elements of a homepage with its help.

Banner paragraph

As we've already mentioned, one of the most important elements of a homepage is a banner with brief information about the company at the top of the page. In order to add a block of this type, press the “Paragraph overlay” button on the top right of the page.

The Paragraph overlay button is located on the top right of the page in Droopler


Next, you have the option to add a new block in the selected area. After pressing the "Add" button, select the "Banner" component in the pop-up window.

Adding a new block on the homepageIn the pop-up window, select the Banner component to add it to the homepage


In the next window, you need to add a banner background. Additionally, you can add a title, subtitle, icon that appears at the top of the block and some brief text. It’s also possible to add the already mentioned Call to Action button and configure its main attributes.

Configuring a new paragraph for a homepage in Droopler


In the "Settings" tab, you can choose the shape of the block: placing the text in the central part of the banner or on the left side with a translucent background. It’s also possible to set different colour versions of a paragraph and define your own colours to ensure good readability of the text. Additional options include configuring the margins and padding, as well as adding additional classes for the block.

In the Settings tab, we can configure more settings for a particular paragraph


After pressing the "Save" button, the first block of the main page will be put in the lower right corner of the window:

The block with a banner on a homepage in Droopler


Carousel paragraph

A carousel is a type of block that contains a looped slideshow that can be controlled by the user. In order to create such a block in Droopler, select "Carousel" in the component list window.

Selecting a Carousel component to add it to the homepage


As in the case of a banner, you can add a title, icon, description and CTA. In the "Settings" tab, it’s also possible to set the margins. In addition, you can define the number of columns - how many elements should be displayed in this block.

Configuring the settings for a Carousel paragraph


The carousel items are added in the "Items" tab. You can choose your own title, image, description and link for each of them. The same as for the entire paragraph, for every element, you can set separate graphic themes - change the colour of the background or text. The next picture shows a finished carousel.

A finished carousel with graphic and text elements in Droopler


About Us section

You can create a block with information about the company using the "Text page" paragraph type. It's a simple section where you can enter a title, subtitle, add an icon, text and link. The available settings are the same as for a banner and carousel. After all the fields are filled in, the section will look like this:

The About Us section on the homepage, created using Text page paragraph



In this article, we explained how to create the most important elements of a homepage in a fairly easy and quick way. We used Droopler – a modern website builder, which not only allows you to build websites without coding, but also facilitates Drupal development.

May 21 2021
May 21

The homepage is the most important element of a website. The first impression of the user depends on it – whether they'll stay on the website, whether they'll be interested in the company's offer and the company itself. In just a few simple steps, we'll show you how to create a homepage that will help you keep your visitors' attention.


What elements should a homepage contain?

A prospect enters the homepage. You have a few seconds to interest them and make them continue to check out your offer. How can you do that? You need to correctly convey the most important information that will immediately answer the customer's questions.

Banner with a call to action

First of all, you need to briefly describe what your company does. This type of information is often displayed in a banner at the top of the page. In this section, you can add a CTA (Call to Action). It's a link which when clicked redirects the user the destination area, e.g. to the next section of a page or to a contact form.

Blocks with content

You should also put blocks that contain information about what your company can offer to a potential customer and why they should choose your offer. Various types of representing information are suitable for these purposes: from simple text blocks to advanced interactive carousels that allow you to put more content into a fairly tight framework of one block.

Once you know what elements to put on the home page, the matter of creating the page in a fairly quick and easy way arises. Website builders – one of which is Droopler – are suitable for solving such a problem.


Create a homepage in Droopler

Droopler is an open source website builder based on CMS/CMF Drupal. It contains ready-made components and tools that allow you to quickly create modern webpages. Droopler is simple to edit and easy to expand. Let's try to create the most important elements of a homepage with its help.

Banner paragraph

As we've already mentioned, one of the most important elements of a homepage is a banner with brief information about the company at the top of the page. In order to add a block of this type, press the “Paragraph overlay” button on the top right of the page.

The Paragraph overlay button is located on the top right of the page in Droopler


Next, you have the option to add a new block in the selected area. After pressing the "Add" button, select the "Banner" component in the pop-up window.

Adding a new block on the homepageIn the pop-up window, select the Banner component to add it to the homepage


In the next window, you need to add a banner background. Additionally, you can add a title, subtitle, icon that appears at the top of the block and some brief text. It’s also possible to add the already mentioned Call to Action button and configure its main attributes.

Configuring a new paragraph for a homepage in Droopler


In the "Settings" tab, you can choose the shape of the block: placing the text in the central part of the banner or on the left side with a translucent background. It’s also possible to set different colour versions of a paragraph and define your own colours to ensure good readability of the text. Additional options include configuring the margins and padding, as well as adding additional classes for the block.

In the Settings tab, we can configure more settings for a particular paragraph


After pressing the "Save" button, the first block of the main page will be put in the lower right corner of the window:

The block with a banner on a homepage in Droopler


Carousel paragraph

A carousel is a type of block that contains a looped slideshow that can be controlled by the user. In order to create such a block in Droopler, select "Carousel" in the component list window.

Selecting a Carousel component to add it to the homepage


As in the case of a banner, you can add a title, icon, description and CTA. In the "Settings" tab, it’s also possible to set the margins. In addition, you can define the number of columns - how many elements should be displayed in this block.

Configuring the settings for a Carousel paragraph


The carousel items are added in the "Items" tab. You can choose your own title, image, description and link for each of them. The same as for the entire paragraph, for every element, you can set separate graphic themes - change the colour of the background or text. The next picture shows a finished carousel.

A finished carousel with graphic and text elements in Droopler


About Us section

You can create a block with information about the company using the "Text page" paragraph type. It's a simple section where you can enter a title, subtitle, add an icon, text and link. The available settings are the same as for a banner and carousel. After all the fields are filled in, the section will look like this:

The About Us section on the homepage, created using Text page paragraph



In this article, we explained how to create the most important elements of a homepage in a fairly easy and quick way. We used Droopler – a modern website builder, which not only allows you to build websites without coding, but also facilitates Drupal development.

May 05 2021
May 05

The N1ED module works as a bridge between Drupal 8 and 9 versions, and the N1ED library – which is a multi-plugin for CKEditor, the basic text editor in this system. The library itself is built based on Bootstrap and its classes. In this text, we'll take a look at it and at the module itself.

N1ED library

The N1ED library is available in free and paid versions. The former has limited functionalities, but you can use options such as:

  • full screen text input,
  • widgets which introduce new buttons to the editor, such as Font Awesome icons, easy table insertion and HTML code insertion,
  • easy addition of headings and paragraphs, which allows you to better control the entered text.
Full screen version of the free editor version

Full screen version of the free editor version

Apart from the free version of the library, there are three different paid plans that provide additional functionalities. The most interesting of them is Bootstrap Editor, thanks to which you can easily design what the website will look like in the desktop or mobile version.

N1ED module

Before the installation, you can see and feel for yourself how the N1ED module works and only then decide if it's worth starting to use it on your own website.


It's a relatively young module. It appeared on Drupal.org in early 2019, but it's already a stable version monitored by the Drupal Security Team. The first release of the N1ED library was earlier – on 18 December 2018.

Popularity of the module and the library

According to the official statistics, the module is being used by more than 150 websites. The library itself can be used in any system that uses CKEditor or TinyMCE, for example in Symfony, Laravel or Magento.

Configuration and use

Download the N1ED module from Drupal.org. The module is installed in the typical way:

composer: composer require drupal/n1ed

drush: drush dl n1ed

drupal console: drupal mod n1ed

After executing the command you need to enable N1ED on the page with modules using Drush or Drupal Console. Support for a new plugin in CKEditor is automatically enabled for the Full HTML filter.

Support for N1ED plugin in CKEditor

N1ED can be enabled for any text format. Just set the switch to the desired position in the text format edit options.

In the same place, you can set your own API key which is required for the plugin to work. After the installation, you use the default key provided with the module which gives basic free functionality.

Setting your own API key for the N1ED module



Although the free version of the library is very limited in terms of available functionalities, it provides a new look and feel for adding content in Drupal. In addition, it helps you to control the text and elements you enter. We use both the library and the N1ED module as part of our Drupal development services.

Apr 28 2021
Apr 28

Bluehost is among the 20 largest hosting companies in the world, handling over 2 million domains. The company's offer includes a wide range of services. We will show you how to install Droopler, the Drupal distribution, using the basic shared hosting offer (Basic Web Hosting).


Step 1. Server preparation

First, you need to configure the database and PHP. This stage is necessary because, without it, it won't be possible to install Droopler. But before you start, you need to get familiar with the requirements for the system on which you want to run Droopler.

To configure your hosting, after logging in to the account using the login form, go to the "Advanced" tab, where you'll find all the necessary functions:

The Advanced tab in Bluehost, where you'll find all the necessary functions for the hosting configuration



1. Database configuration

First, you need to create a new database. To do this, click on the "MySQL Database Wizard" in the "Databases" section.

The Databases section in Bluehost


You'll be redirected to the database wizard page. In the first step, you need to define the database name. It can be any name but in our example, we’ll use the most intuitive one - droopler. The full database name will consist of a prefix (usually associated with the account id) and a second part/name defined by you.

Defining the database name in MySQL Database Wizard


In the next step, you need to define the database users (at least one) and their passwords. You can generate the password using the Password Generator located in the form.

Defining the database users in MySQL Database Wizard


In the third step, you need to assign the user permissions to your database. For the Droopler installation to work correctly, it's safest to assign all permissions by selecting the "ALL PRIVILEGES'' option.

Assigning all database privileges to a user to make the Droopler installation work properly


2. PHP configuration

Setting the appropriate version of the PHP language and adjusting its configuration is crucial and can significantly affect the installation process. To make the necessary changes, go to the "Software" section in the "Advanced" tab.

The Software section in the Advanced tab in Bluehost


To set a specific PHP version, click on "MultiPHP Manager". In our installation, we'll use the proven PHP 7.3 version.

Selecting a specific PHP version in MultiPHP Manager


To change the environmental settings, click on "MultiPHP INI Editor".

With MultiPHP INI Editor, we can change the environmental settings


In the first step, you need to select the domain for which you want to make the necessary changes.

Selecting the domain for which you want to make the changes in MultiPHP INI Editor


Then you need to adjust the configuration for the needs of the Droopler installer and for the smooth operation of the website. We increase the maximum script execution time (max_execution_time) to 180 and the memory limit to 512 MB.

Adjusting PHP configuration for the needs of the Droopler installer and the smooth operation of the website


We leave the other values in accordance with the default settings.


Step 2. Downloading Droopler

The Droopler distribution can be downloaded from the official website of the project.

1. Download the latest version of Droopler as a zip archive.

A place on the Drupal distribution's page from where you can download the Droopler


2. Go to the File Manager located in the "Files" section in the "Advanced" tab.

The Files section in the Advanced tab in Bluehost


3. After opening the file manager, click on the "Settings" button in the upper right corner to unlock the option to display hidden files.

After coming to the Settings section, we can unlock the option to display hidden files


4. In the file explorer located in the left column, click on the public_html directory.

The public_html directory in File Manager in Bluehost


5. Click on the "Upload" button in the top menu in order to upload the file from the archive downloaded in the first step.

The Upload button in File Manager


6. Drag and drop or select the file using the system file explorer.

Adding the Droopler file to File Manager in Bluehost


7. After loading the file, right-click on it and select the "Extract" option.

Selecting the Extract option for the Droopler file


8. Set the target directory for the extraction to /public_html.

Setting the target director for the extraction of the Droopler file


9. After the extraction is complete, go to the newly created directory with Droopler (in our example, it'll be the directory named droopler-8.x-2.1) and select all files.

The newly created directory with Droopler in File Manager in Bluehost


10. Move the selected files and subdirectories directly to the /public_html directory using the move button available in the top menu or after right-clicking.

Moving the selected files to the public_html directory


11. Leave only /public_html in the name of the path to which you'll move all the contents of the directory.

Defining the path to which you'll move all the contents from the directory with Droopler


12. After moving the files, go back to the /public_html directory and remove the uploaded .zip archive (droopler-8.x-2.1-core.zip) and the directory created during the unpacking (droopler-8.x-2.1).

Removing .zip archive and the Droopler directory from the public_hml directory


Step 3. Droopler installation

Everything is ready now. To start the installation process, all you need to do is to go to the website by entering your domain address in the browser bar.

The Droopler installer


The Bluehost web hostings don't offer PHP OPcache, so you'll see a warning when verifying your requirements. You can ignore it and proceed with the installation by clicking on the "continue anyway" link at the bottom of the page.

The warnings during the requirements verification in the Droopler installer


The last important step is database configuration. Here we enter the data that we previously set in the Bluehost panel, i.e., the database name, the database user's name and their password. The host and port number remain as in the attached screenshot.

Database configuration in the Droopler installer


After clicking on "Save and continue", you have nothing else to do other than to take a short break for coffee or tea, during which the rest of the Droopler installation will be performed.

Apr 14 2021
Apr 14

Working with multimedia is one of the areas that large websites have to deal with. When multiple editors upload a large number of files, keeping your photos and videos in order can become difficult and time-consuming. Drupal has several proven recipes for managing the media library, which I'll present in this article.

Drupal modules for managing multimedia

Drupal offers great flexibility when working with files on a website. In the simplest terms, you can use fields like "File upload". A more complicated option is to use one of the modules to work with multimedia. Let's take a look at three interesting modules worth knowing about.

IMCE module

IMCE is a file viewer available to administrators and editors that also allows you to add, copy, and delete files and directories. It’s fast and convenient, it offers a preview of photos (including creating thumbnails), allows you to sort them and limit the disk space for individual users.

There was a time when the IMCE module was an absolute must-have for any Drupal website. To this day, over 340 thousand websites use it, but its popularity is steadily declining. The reason for this is that with more editors it's difficult to keep your file directories in order. Searching for a specific item is problematic, because the files have only a name and type. It's also impossible to filter them according to selected criteria. Despite the existence of the IMCE version for Drupal 8, new websites usually use other solutions.

IMCE module - Drupal file viewer


SCALD project

SCALD is a module designed for Drupal 7, with a very rich base of add-ons (over 50 additional modules). It allows you to add photos, videos, and other types of files as entities called atoms. Each atom can have any field list based on which the media list is filtered. There is no module version for Drupal 8, but there is a migration path for atoms to the Media module entity.

I mention the SCALD module due to its significant contribution to building the concept of media management. With the premières of Drupal 6 and 7, the era of entities and fields was slowly approaching. The first ideas began to emerge to present files as entities that could be described in any way. This is how the SCALD project was created – quite niche, although used over the years on large and popular sites with millions of multimedia, such as Radio France, ARTE TV and Le Figaro.

Media module

This is by far the most important of the modules presented here. It follows an idea similar to SCALD, because it turns files into entities. It’s currently used by over 180 thousand Drupal 7-based websites, as well as all the websites based on Drupal 8 and 9. That's because since version 8.4 it’s in the core.

Media is a mature module, prepared for years by a team of experienced programmers. I can confidently say that it's one of the best multimedia management solutions available on the Internet. What makes the Media module so special? I'd point out its four main advantages:

  1. Effective embedding of a file library in the Drupal's entity/field/view model. This solution gives virtually endless possibilities for web developers. The files can have different view modes and form view modes, they can be used in many independent contexts. A photo sent via the Media module can be used multiple times, both as a thumbnail in the content of the article and, for example, as a background of a large banner.
  2. Leaving the directory/file model. When uploading a photo or video, the editor no longer decides about the order in the directory structure. It’s done automatically. Ordering is done using the fields defined in the media. You can, for example, add a category to the files, and then use it to search through the list of multimedia.
  3. Independence from media sources. On a well-designed website, videos will work the same way whether they are uploaded directly or via YouTube or Vimeo. Photos can also be loaded from multiple sources (such as Pixabay or Google Drive). Such an approach makes the work of editors easier and allows quickly adding subsequent sources as needed.
  4. Media isn't only multimedia anymore. You can put documents, Facebook posts or excerpts from Google Maps in the media library. Your only limit is your imagination.

When it comes to migration, remember that the Media module comes in three forms:

In each of these cases, a migration path to the core version is available, so you can easily transfer the multimedia library to a newer Drupal.

Why isn't the Media module used on every website?

This begs the question – since the Media module is so great and also available in the core, why isn't it enabled by default and used in every Drupal development project? This is because many Media elements need to be set up by a programmer first. Therefore, this module is a tailor-made solution that is strongly adapted to the needs of a specific website.

It's particularly problematic to correctly display videos from external sources (due to the limited capabilities of external players) and to design appropriate display modes for the media. Getting through these issues can take a long time. Due to this fact, at Droptica we use a ready-made solution included in Droopler, the Drupal distribution.

Media module in Droopler

Since version 2.0, Droopler has built-in support for the Media module. All photos, graphics, icons and videos on the website are stored in the file library.

Usage of the Drupal Media module in the Droopler distribution


It's fine if you have a website based on Droopler 1.x. When upgrading to Droopler 2.x all "File upload" fields will be automatically converted to the new format.

The files put in the library can be used in many places on the website - as a paragraph background, an icon, a photo in a gallery or a cover for a blog post. In each of these contexts, the multimedia will be trimmed and adjusted accordingly. Here are examples of using the same photo in a completely different capacity:

As a tile

An example of using a photo as a tile on a website based on Droopler, thanks to the Drupal Media module


As a form background

An example of using a photo as a form background in Droopler


As a blog cover

An example of using a photo as a blog cover


Once you start using Droopler, you'll be amazed at the ease with which you can use YouTube and Vimeo videos. For example, try putting your video in a paragraph with a banner. In the paragraph edit options add the media in the "Background" field:

Adding a video in a paragraph with a banner in Droopler, the Drupal distribution


Then go to the "Video" tab, enter the video address, click ADD and choose a title for the newly added item. Finally, put the video in a paragraph.

Adding a video in a paragraph with a banner in Droopler


The effect of this action will be a moving background that stretches across the entire screen and is played in a loop. The YouTube controls will be hidden, and the video will have a transparent black overlay, improving the readability of the text.

Video as a moving background, played in a loop, on a website based on Droopler


You can add a video to a gallery in the same way, and e.g. next to the text, in the "Sidebar Image" paragraph. There are practically no restrictions here, all the elements fit together well.


The multimedia library included in the latest Drupal works great with even with a large number of subpages and blog posts. You will quickly notice that reusing the existing photos and videos saves time and effort. Even though the Media module requires a lot of coding for every new project, you can use "prepackages" such as Droopler to start working on the content right away.

Apr 01 2021
Apr 01

One of the most annoying errors on websites are broken links, going nowhere or showing completely different content than expected. Neither Internet users nor Googlebot like them. The way to avoid incorrect links in Drupal is to use the Redirect module.

The redirects created by this module are extremely useful when there are changes being introduced to the URL structure of the website - both global ones and those caused by simple editing of individual content. Redirects ensure that the user will always find what they are looking for, even if the URL is no longer valid.


The module was first made available in 2006 by Moshe Weitzman in a very simplified form. The first alpha version was released in 2010, and a stable version was released for Drupal 8 in 2017. For several years Redirect has been developing much more dynamically, with the support of the Drupal.org community.


Even the lack of a stable release for Drupal 7 didn’t discourage web developers from using the Redirect module. According to the official statistics, it’s currently used on over 260 thousand websites, 45% of which use Drupal 8.

The official usage statics for Drupal Redirect module

Module's creators

The module is being looked after by three programmers:

The last few releases had a lot of support from other Drupal.org users. So far, over 110 people have contributed to the creation of the module.

Purpose of the module

The Redirect module is used to create URL redirects within Drupal. Thanks to it, you can redirect the user from one address within the website to another. Note that there is a big difference between a redirect and an alias.

  • An alias is the "user-friendly" URL of the content that you see in the address bar of a web browser. If you won't define an alias for a given subpage, it will have a default address like “/node/123” or “/ taxonomy/term/456”.
  • A redirect is a rule that's triggered when you reach a given URL address. The rule specifies the target address the user will be redirected to, the language for the redirect, and the type of HTTP code returned. The target webpage will only appear in the browser's address bar when there are no more redirects to be carried out.

The URL redirects are primarily used to improve the linking structure within a webpage. Redirect, however, has a few more interesting applications resulting from the fact that in the version for Drupal 8 it received some of the functionalities of the Global Redirect module. I’ll mention them later in this article.


You can download the Redirect module from the Drupal.org website. The recommended installation method is to use the Composer command:

composer require drupal/redirect

You can find the module settings panel by going to Configuration → Search and Metadata → URL Redirects.

Module's use

The main element of the module's configuration is the list of redirects:

The list of URL redirects in Drupal Redirect module

To add a new redirect, select "+ Add redirect" and then fill in the necessary information, i.e. source address, target address, HTTP code and language.

Adding a new URL redirect in the Redirect module

It's good to explore the seven available HTTP codes. This is because they greatly affect the SEO. You will definitely need:

  • 301 Moved Permanently - the requested page has permanently changed its address. This is an important signal for search engines, which remove the previous page address from their resources and replace it with the new one.
  • 302 Found - the requested page is temporarily available under a different address. This code is useful in a situation where you test changing the linking structure on a webpage, but you want the change to be noted by search engine robots.

Other available codes are:

  • 300 Multiple Choices - there is more than one way to process the given query (rarely used, e.g. for processing different video formats).
  • 303 See Other - the response to the request is under a different address (used e.g. for POST requests).
  • 304 Not Modified - information for the browser that the webpage hasn’t changed since the last visit and it can be loaded from the cache.
  • 305 Use Proxy - the requested webpage is only accessible via proxy.
  • 307 Temporary Redirect - same as 302, but with the assumption that the HTTP method can't be changed.

Additional options

When you've mastered creating URL redirects, check the "Settings" tab. You'll find there two important options that will help you achieve better results with Google.

  • Automatically create redirects when URL aliases are changed - be sure to select this setting. It'll help you keep the webpage clean in the case of changes to internal linking. When you modify any alias on a webpage, a redirect from the old address to the new one will be automatically created.
  • Enforce clean and canonical URLs - this is the option that convinces many developers to choose the Redirect module. It redirects the user to the canonical address of the given webpage, so that they won't stay under a working address like "/node/123". This setting was available in Drupal 7 through the Global Redirect module.

Hooks and integrations

The module provides the following hooks:

  • hook_redirect_load() - launched when loading an array with redirects, allows you to add new items to it,
  • hook_redirect_load_by_source_alter() - used to modify redirections for a given source address,
  • hook_redirect_prepare() - changes the form of a given redirection in the module's administration panel,
  • hook_redirect_alter() - allows you to change the settings of a redirect just before it is triggered.

In addition, the Redirect works with the Pathauto module. It's a very harmonious tandem for managing creating redirects when changing page aliases.


The ease of creating and handling redirects is an important feature of a professional CMS. The Redirect module does this very well. It’s a stable solution that has been developed over the years. I recommend using it in any Drupal development project.

Mar 25 2021
Mar 25

A good CMS can be recognised by how it deals with the URL addresses of individual subpages. Convenient linking attracts users from search engines and has a significant impact on SEO. In this article, I'll introduce you to the Pathauto Drupal module, which is used to automate the creation of page aliases.

With this module, you can easily configure efficient, maintenance-free aliases for your content, including taxonomy terms and user pages.


The first version of Pathauto was released in February 2006 as an add-on to Drupal 4. Stable 1.0 version was released for Drupal 5 in 2007. The current code of this module from the 8.x-1.x branch is the result of a long evolution involving many members of the Drupal.org community.


The figures from the official statistics speak for themselves – the Pathauto module is used by over 640 thousand pages. And 32% of these are built on Drupal 8 and 9. We’re dealing here with one of the "essentials", installed immediately at the stage of creating new projects.

Official usage statistics for Pathauto Drupal module

Module's creators

The module is currently being maintained by four developers:

Since the beginnings of the Pathauto module, over 100 people have been involved in its development, creating a total of almost 1,600 commits. The tremendous contribution of the community is further evidenced by over 3,000 reported tasks and bugs on Drupal.org. Unfortunately, many of these remain unresolved.

Purpose of the module

With bare Drupal, you can create URL aliases for individual subpages, but you have to do it manually. If you don't fill in the field with the alias, the new content will have standard, inconvenient addresses like /node/123 or /taxonomy/term/456.

The Pathauto module automates the addition of aliases by generating them according to the template with tokens specified by you. For example, static pages may have a title derivative address (/foo-bar), and taxonomy terms may contain a vocabulary name (/vocabulary-name/foo-bar).


You can download the module from Drupal.org or join the project by running the following command:

composer require drupal/pathauto

After launching Pathauto, go to its settings by selecting Configuration → Search and Metadata → URL Aliases → Patterns.

Module's use

Pathauto offers a broad range of settings for the methods of generating aliases. It also allows you to carry out mass operations on already existing content. I'll briefly describe below the most important options available.

URL address templates

The basic functionality of the Pathauto module is creating URL address templates, i.e. strings of characters containing tokens. Individual aliases are generated based on them when content is being saved.

I'll explain it using the example of a blog. If you want your posts to be available under the address http://example.com/2021/foo-bar.html%20 containing the year of publication and the title, go to the panel Configuration → Search and Metadata → URL Aliases → Patterns and add a new template for the appropriate content type:

Adding a new URL address template in the configuration panel of Pathauto Drupal module

Try to create a new blog post now. It should get the address /2021/foo-bar.html. Note that you can still overwrite its URL alias, however by default it is generated automatically:

Generating URL alias in the Pathauto module


Page titles usually contain spaces and special characters. Pathauto module automatically converts them to the ASCII format separated by dashes. Then, a title like "How to Make Crème Brûlée?" will be replaced with a simpler version – "how-to-make-creme-brulee". The settings for this conversion can be found in the "Settings" tab.

I suggest that you leave most of these options at the default position, but pay special attention to the "Strings to Remove" field. It contains strings of characters that will be removed from the address, including numerous English prepositions and articles. If you create a blog post titled "A Guide To Drupal", you'll end up with an address like /2021/guide-drupal.html, which is not always the desired result.

The other settings allow for very detailed customisation of transliteration in aliases, which is useful for multi-language support. Here you can, for example, decide on how to handle punctuation.

Mass generation of URL addresses

By default, Pathauto only generates aliases when the content is being saved. This means that if you change the URL template, the modification will not be reflected immediately in the aliases on the entire page. Also, after adding a new template, all its content will not get a new URL address immediately.

When creating large websites, it is often necessary to quickly regenerate aliases for the existing content. This is done with the "Bulk Generate" function, which enables mass operations on URL addresses.

Regenerating URL aliases with Bulk generate function in Pathauto module

Be very careful not to accidentally overwrite the existing aliases with newer versions. Here I would recommend installing the Redirect module, which saves the redirects between the old and new subpage addresses.

Removing aliases

The Pathauto module also has an advanced panel for removing aliases. Be very careful when using it. Any changes introduced here are irreversible. You'll probably need the "Only delete automatically generated aliases" option to prevent deleting manually overwritten aliases.

Deleting URL aliases in Pathauto Drupal module

Hooks and integrations

Pathauto from the 8.x-1.x branch allows you to handle any kind of entities with plugins like @AliasType, and also provides some simple hooks:

  • hook_pathauto_is_alias_reserved() - blocks the creation of an alias if it is reserved by another module. In such a case, a number will be added to the alias (e.g. /foo-bar1).
  • hook_pathauto_punctuation_chars_alter() – it is used to add new punctuation settings.
  • hook_pathauto_pattern_alter() - allows you to modify the URL address template.
  • hook_pathauto_alias_alter() - allows you to change the alias after generating it.

When creating your own Drupal modules, you should think about adding an optional configuration for Pathauto to them. This is quite a common practice, for example in the Group module. As a result, the user receives default, ready-made alias templates.

Dealing with URL addresses in Drupal

Pathauto is an extremely powerful module that is used in most of our Drupal development projects. It keeps URL addresses consistent and frees editors from having to manually form aliases. Its usefulness is confirmed by hundreds of thousands of installations reported in the official statistics. I definitely recommend getting better acquainted with its abilities.

Mar 09 2021
Mar 09

A to-do list is the primary tool of a productive person. It helps in everyday work and allows you to carry out your duties better. As it turns out, some of its elements can also be entered into the administration panel of a Drupal website.

In this article I'll take a closer look at the Checklist API module, which provides Drupal users with an interesting implementation of a TODO list.


The first alpha release of the module was introduced in 2012 for Drupal 7. The stable version 1.0 was released several months later. To date, 12 stable versions have been created – including the newest, marked as 2.0, for Drupal 8 and 9.


Even though the Checklist API module isn't very popular, it has become quite recognisable over the years. Currently, according to the official statistics, it's used by over 30 thousand Drupal-based websites, 63% of which are the 7.x-1.x branch.

Official usage statistics for Checklist API Drupal module

Module's creators

The module is maintained by Travis Carden from Acquia, a very active member of the Drupal community. Besides him, 11 other people have also participated in the project so far. About 170 commits were created in total.

Purpose of the module

The Checklist API module is used to create lists with checkboxes. The status of the task execution is saved to the configuration or to the State API, and it can be modified using the code. Checklist API can be employed to build a to-do list, but that is only one way to use it.

In the case of the Droopler distribution, the Checklist API module was used as a mechanism supporting the update process. When automatic processes fail, we advise the user to perform the operations that aren’t checked on the list manually. There are detailed instructions and links available for them:

Usage of checklist API module in Droopler - Drupal distribution

Checklist API is used by many tools for checking websites in terms of SEO and quality, including SEO Checklist and QA Checklist.


The module is available on the Drupal.org website. You can install it both via Composer (using the composer require drupal/linkit command) and from the .zip file available on Drupal.org.

Module's use

After running the Checklist API module, you'll probably be surprised by the fact that it doesn't have any administration panel. New lists can only be created via the API. This is done using a hook – hook_checklistapi_checklist_info().

Here is an example of a hook that adds a simple to-do checklist when publishing a new website:

* Implements hook_checklistapi_checklist_info().
* Defines an example deploy checklist.
* .
function mylist_checklistapi_checklist_info() {
 $definitions = [];
 $definitions['mylist'] = [
   '#title' => t('Website deploy checklist'),
   '#path' => '/admin/config/development/website-checklist',
   '#callback' => 'mylist_checklistapi_checklist_items',
   '#description' => t('An example deploy checklist for the website.'),
   '#help' => t('

This is an example deploy checklist for your website, provided by the hook_checklistapi_checklist_items().

'), '#storage' => 'state', ]; return $definitions; }

This hook references the mylist_checklistapi_checklist_items function, which returns a multidimensional array. You divide the checklist into tabs with tasks. Each defined task can have a description and a list of links to help the user perform it:

* Implements callback_checklistapi_checklist_items() for mylist.
function mylist_checklistapi_checklist_items() {
 return [
   'tab1' => [
     '#title' => t('Drupal admin panel'),
     '#description' => t('

Set up the Drupal installation for PROD environment.

'), 'aggregate_css_js' => [ '#title' => t('Enable JS/CSS aggregation'), '#description' => t('Enable optimization of the site assets, it is crucial for page speed.'), 'handbook_page' => [ '#text' => t('Performance options'), '#url' => Url::fromUri('base://admin/config/development/performance'), ], ], 'disable_devel' => [ '#title' => t('Disable "devel" module'), 'handbook_page' => [ '#text' => t('Module list'), '#url' => Url::fromUri('base://admin/modules'), ], ], ], 'tab2' => [ // ... ], ]; }

After calling the above code, every authorised user of the website will get access to the new checklist. When they uncheck subsequent items, they'll obtain clear information about the level of completion of tasks:

Example of a checklist in Droopler, Drupal distribution

Defining the content via code has one major advantage – the ability to manipulate tasks, including automatically marking them as completed. Looking at the example above, you could write a module that will check by itself whether the CSS/JS aggregation is enabled and if the "devel" module has been uninstalled. This way, the potential user will save a lot of time.

Here's an example of a piece of code that loads the checklist and enforces its initial state. If the "devel" module is active, the relevant checkbox will be checked automatically.

$handler = \Drupal::service('module_handler');
$checklist = checklistapi_checklist_load('mylist');
$progress = [
 'tab1' => [
   'disable_devel' => $handler->moduleExists('devel'),


Checklist API is very useful for carrying out repetitive tasks, such as those you perform when publishing a new website. The module can also be used as a tool supporting security monitoring and website optimisation, performed as part of Drupal support.

With little effort, Checklist API provides plenty of possibilities and a convenient interface for non-technical users. I definitely recommend getting better acquainted with its functionalities.

Feb 25 2021
Feb 25

The work of a content manager requires intensive linking of various content together. Proper linking of subpages is one of the foundations of SEO. It also makes it easier to navigate your website, which may have a great impact on marketing effectiveness.

Drupal by default allows you to create links in text. You just select the appropriate button in the editor and enter the URL of the new link. However, when you need a more convenient autocomplete solution, I recommend trying the Linkit module. In this article, I’ll show you its abilities.


The module debuted at the beginning of 2010. The first stable version 1.0 for Drupal 6 was released back then. Since that time LinkIt has been updated regularly. The latest beta release, 6.0.0, saw the light of day in December 2020.


The LinkIt module is extremely popular in the Drupal world. Official statistics show over 110 thousand installations. This number also includes the websites based on our Drupal distribution – Droopler. 41% of the above websites are based on Drupal 7.


Module's creators

The module has been maintained by Emil Stjerneman for ten years, and he’s created over 900 commits in the project so far. In total, almost 80 users made contributions to it.

Purpose of the module

The LinkIt module adds to WYSIWYG editors the ability to conveniently link internal and external content. It offers built-in support for content types, taxonomies, users, files, and comments. Thanks to this, you don’t have to remember or copy the URLs you link to when you’re editing a webpage. All you have to do is enter a title fragment and the target page will be suggested by autocomplete. This is a very useful functionality, especially since errors in URLs are one of the most frequently detected problems in Drupal SEO audits.


The module is available on the Drupal.org website. Like other Drupal add-ons, you can install it from a .zip file or via Composer (using composer require drupal/linkit command).

The administration panel can be found in the menu by selecting Configuration → Config Authoring → Linkit.

Module's use

When you start editing any text format, pay attention to the "Drupal link" section.


After clicking the "Linkit enabled" checkbox, the standard link widget in CKEditor will be replaced with a new one, with built-in autocomplete.


At this stage, you can finish the module configuration.

Linkit profiles

If you want to customise autocomplete, create your own Linkit profile in the Configuration → Config Authoring → Linkit panel. Each profile has its name, description and a list of matchers.


You have the following types of matchers to choose from:

  • Content – basic matcher, searches for content by title among all or selected types of content,
  • Contact form – searches for contact forms,
  • Email – detects e-mail addresses and creates a mailto: link automatically,
  • File – searches for files from the sites/*/files directory managed by Drupal,
  • Front page – suggests a home page when you start typing "Front page",
  • Media – searches for media of selected types,
  • Taxonomy term – searches for taxonomy terms,
  • User – searches for website users.

Example of use

The easiest way to explain the operation of matchers is by using an example. I’m adding a new "Example profile" containing the following elements:


Notice that the “Metadata” fields are filled in, showing additional information about the link match found. Now, let’s set the “Example profile” as active in the text format configuration.

When you go to webpage editing, the effect of the above actions will be as follows:


You can see three matchers here, one below the other. The first one shows the article, the second one shows the Media object with a thumbnail, and the third one - the taxonomy term.

URL format

When you save the content with a link inserted via Linkit, you will notice that instead of a URL alias (of the /example-article type), the link contains its abbreviated form (e.g. /link/20). You can change this behaviour by activating the following filter in the text format settings:


Hooks and integrations

The Linkit module is object-oriented and highly flexible. You can extend it with:

  • "matcher"-type plugins, allowing you to easily add your own sources of link hints,
  • "substitution"-type plugins that return links to content.

There are currently no additional Linkit modules on Drupal.org. This is probably due to the fact that the basic version covers most cases of use.


Linkit is a simple and reliable solution that will improve the UX of your website at a low cost. It’ll also allow you to better control the structure of links and help you avoid linking errors. We’ve been using this module for many years – also as part of our own Drupal distribution – Droopler.

Feb 19 2021
Feb 19

When creating websites, you often need to quickly backup the data that isn’t in your code repository. In the case of Drupal, it’s possible to generate copies via the "Backup and Migrate" module.

This module offers options for both beginners and advanced users. In this article, I’ll present its functionalities in detail.


The module was released at the end of 2007 for Drupal 5. It’s been extensively updated since then. The 8.x-3.x branch appeared in 2015, along with Drupal 8, however it didn’t have a stable release. It took another three years for the stable 8.x-4.0 version to see the light of day.

Module's popularity

The popularity of the module is confirmed by the number of installations - according to the official statistics, it’s used by over 220 thousand pages, including approx. 40 thousand based on Drupal 8.


Module's creators

Four developers are responsible for maintaining the module:

There are 822 commits in the code repository, created by over 70 people.

What is the module used for?

Backup and Migrate is an advanced tool for creating backup copies. It operates on the database, as well as public and private files. It integrates with Drupal CRON, thus ensuring the possibility of making regular backups to various destinations.


The module is available at https://www.drupal.org/project/backup_migrate. You can install it from a .zip file or run the command composer require drupal/backup_migrate in the console.

You can find the settings administration panel in the Configuration → Development → Backup and Migrate menu.

Module's use

The module was designed with both beginners and advanced users in mind. The former don’t have to delve into the configuration of data export, they just need to use the quick backup option:


Clicking "Backup now" will download the database (or public/private files as selected in the "Backup Source" field). What’s more, the database backup will be devoid of cache and log entries, so it’ll take up much less space.

Some more settings are available in the "Advanced" tab. I’ll describe these later in the article.

Backup sources

By clicking Settings → Sources you’ll access the list of available backup sources.


By default, the sources can be:

  • databases,
  • public files,
  • private files,
  • whole page code along with a database.

This set can be extended slightly with external MySQL databases and any directories on the server. It can be done using the "Add Backup Source" option.

It’s possible to define own sources via the "Backup and Migrate" module's API.

Backup destinations

A backup destination is the place where it is to be put. This can be, for example, a server directory or a web browser. The available destinations are listed in Settings → Destinations.


As with sources, you can define your own destinations via the "Add Backup Destination" button and a corresponding hook. At the end of the article, I present some destination-adding modules like SFTP Server and S3 Cloud.


Remember that backups contain sensitive data and access to them should be strictly limited. Drupal is one of the most secure CMSs available, so it’s worth using its private file system. In addition, the possibility of encrypting files with backups comes in handy. To use it, add the Defuse library to the project using the command:

composer require defuse/php-encryption

After clearing the cache, the "Encrypt File" option will appear in the module configuration panel with the field for entering a password. It’ll be used to encrypt the generated archives.

Advanced backup

I’ve already covered how to create a quick backup. It’s time for its slightly more advanced version, which you can find in the "Backup" → "Advanced Backup" tab.

Here’s a quick overview of the options available:

  • Source - used to select a predefined source.
  • Backup file - allows you to configure the name and format of the backup file.
  • Backup encryption - enables archive encryption.
  • Take site offline - turns off the website while creating its backup.
  • Exclude database tables - allows you to exclude selected tables in the database (or only their contents) from the backup.
  • Exclude files - used to exclude selected files when creating a directory copy.
  • Destination - allows you to select the backup destination.

If you want to save such a set of advanced options for the future, take a look at the profiles in the "Settings" → "Settings profiles" tab.

Backup list

All backups on the server are listed in the "Saved Backups" list.


Interestingly, this list also works when saving backups to SFTP and S3 servers.

Backup restoration

Less often needed, but still an extremely interesting option, is to restore the website from a backup. For this purpose, you can use either one of the copies from the list presented above or upload any file via the form.


The last important functionality of the Backup and Migrate module is the ability to create backup schedules.


Here you have everything you need to build an efficient backup mechanism. These actions are performed using Drupal CRON functionalities. Therefore, no additional server configuration is needed.

Hooks and integrations

Backup and Migrate provides one basic hook hook_backup_migrate_service_object_alter(), allowing you to change practically the entire engine of the module. This is where additional plugins and filters are defined. You can define the following elements:

  • Backup sources - by default it is the database, public/private files and the entire website along with the source code.
  • Backup destinations - such as cloud storage or local directory storage.
  • Filters modifying the archives being generated - e.g. encryption.

On the basis of the above mechanism, many auxiliary modules that offer integration with external providers of disk space were created. Unfortunately, most of them run only under Drupal 7 control. These include:


In the face of new technologies, the Backup and Migrate module is sometimes considered redundant. However, we use it in our Drupal agency as it offers the easiest way to download a database and files from a Drupal-based website. It’s easy to set up and works almost immediately.

In the case of smaller websites, the module can be useful as a supplement to a standard backup. Especially when the code is on a shared server where you don't have full control of the system.

Feb 12 2021
Feb 12

When publishing a form on your website, you must be aware that sooner or later spambots will find it. It is one of the biggest scourges of the modern Internet. The Captcha module will protect you against such situations.

Further down the article, I will present the instructions for using the module and its potential possibilities. This is essential knowledge that we use in practice as part of the Drupal development services provided by Droptica.


The first version of the module was released in May 2005 for Drupal 4. Developing the version for Drupal 8 took many years. The first try-outs took place in 2013, but the première of a stable version took place only at the beginning of 2020.

Module’s popularity

Captcha is a popular and appreciated module. According to official statistics, it is used by almost 300,000 Drupal-based websites. The latest version from the 8.x-1.x branch is installed on 80,000 websites. The module’s popularity is gradually decreasing – probably due to the transition to other, more modern solutions.


Module’s creators

The Captcha module has five maintainers; they are Jakob Perry (Acquia and Lanfest), Fabiano Sant’Ana (Chuva Inc.), Lachlan Ennis (Expert1 Pty Ltd), Naveen Valecha (Acquia) and Andrii Podanenko (Open Y and ITCare). They are all very active and valuable members of the Drupal community. The official sponsor of the module is the Chuva Inc. company. The code repository consists of 606 commits by almost 120 users.

What is the module used for?

The Captcha module is used to protect forms against spam; it helps you ensure that the website’s visitor is not an Internet robot. There are many ways to check the user’s authenticity (such as reCaptcha) – they are delivered as dependent modules. By default, you can use a simple math challenge that will lock the form if the person completing it fails to add two numbers.


You can download the Captcha module at https://www.drupal.org/project/captcha.

After enabling the Drupal module, the only necessary step is to select the forms you want to cover by protection. Go to the module settings by selecting “Configuration → People → CAPTCHA module settings“ and select the “Form settings” tab. Find your form there and enable it by clicking on the “Enable” button.

CAPTCHA - list

If the form is not on the list, add it by clicking the “Add captcha point” button and enter form_id. The effect of the module for the user login form looks like this:

CAPTCHA - form

Module’s use

The Captcha module has several advanced settings that allow you to customise the protection of your websites better. The most important ones are:

  • Default challenge type - the ability to choose the type of a “trap”, by default it is a mathematical operation. External modules provide other types.
  • Default challenge on non-listed forms - a radical solution that enables protection for all forms that are not listed in the “Form settings” list.
  • Add CAPTCHA administration links to forms - a very useful option that allows you to manage the type of security directly from the given form. It saves a lot of time on complicated websites.
  • CAPTCHA placement caching - cache clearing, useful in the case of problems with forms.
  • Add a description to the CAPTCHA - adding a description explaining why the user needs to prove that they are not a bot.
  • Case sensitive/insensitive validation - determining whether there will be a distinction between uppercase and lowercase letters in solving the “puzzle” presented to the user.
  • Persistence - the ability to disable protection in certain special cases, e.g., when the user has previously confirmed their authenticity.

Hooks and integrations

Captcha provides two hooks to integrate Drupal modules that verify users. These are:

  • hook_captcha() - the main hook used to define your own submodules; it has a structure known from Drupal 7 (it transmits the $op variable containing the type of the currently performed operation).
  • hook_captcha_placement_map() - optional hook specifying the place in the form that should be modified.

This is where the real power of the module lies. At drupal.org, you can find a number of projects that implement various verification methods:

  • reCAPTCHA - to support the most popular verification services available, provided by Google.
  • Image CAPTCHA refresh - this module is an integral part of Captcha for Drupal 8; for Drupal 7 it functions as a separate project. It introduces a widget with an image from which one has to rewrite a text.
  • CAPTCHA Pack (alpha version only) - a collection of very interesting “traps” for bots, including completing a missing letter or word in a sentence.
  • Text CAPTCHA (Drupal 7 only) - integration with the textcaptcha.com website.
  • Captcha Riddler - allows you to define your own set of puzzles for the user.
  • Hidden CAPTCHA (Drupal 7 only) - cheats bots by inserting an invisible field that blocks the form from being sent.
  • CAPTCHA after (Drupal 7 only) - only runs Captcha after the user has submitted the form multiple times.
  • KeyCAPTCHA (Drupal 7 only) - integration with the keycaptcha.com website.
  • Draggable CAPTCHA (Drupal 7 only) - a drag & drop puzzle, no dependence on external websites.


The main arguments behind the module are the effectiveness and simplicity of implementation. It is perfect for fighting against Internet spammers.

We also use it in our Drupal agency as a tool that fits every form and does not require additional coding.

Feb 12 2021
Feb 12

When publishing a form on your website, you must be aware that sooner or later spambots will find it. It is one of the biggest scourges of the modern Internet. The Captcha module will protect you against such situations.

Further down the article, I will present the instructions for using the module and its potential possibilities. This is essential knowledge that we use in practice as part of the Drupal development services provided by Droptica.


The first version of the module was released in May 2005 for Drupal 4. Developing the version for Drupal 8 took many years. The first try-outs took place in 2013, but the première of a stable version took place only at the beginning of 2020.

Module’s popularity

Captcha is a popular and appreciated module. According to official statistics, it is used by almost 300,000 Drupal-based websites. The latest version from the 8.x-1.x branch is installed on 80,000 websites. The module’s popularity is gradually decreasing – probably due to the transition to other, more modern solutions.


Module’s creators

The Captcha module has five maintainers; they are Jakob Perry (Acquia and Lanfest), Fabiano Sant’Ana (Chuva Inc.), Lachlan Ennis (Expert1 Pty Ltd), Naveen Valecha (Acquia) and Andrii Podanenko (Open Y and ITCare). They are all very active and valuable members of the Drupal community. The official sponsor of the module is the Chuva Inc. company. The code repository consists of 606 commits by almost 120 users.

What is the module used for?

The Captcha module is used to protect forms against spam; it helps you ensure that the website’s visitor is not an Internet robot. There are many ways to check the user’s authenticity (such as reCaptcha) – they are delivered as dependent modules. By default, you can use a simple math challenge that will lock the form if the person completing it fails to add two numbers.


You can download the Captcha module at https://www.drupal.org/project/captcha.

After enabling the Drupal module, the only necessary step is to select the forms you want to cover by protection. Go to the module settings by selecting “Configuration → People → CAPTCHA module settings“ and select the “Form settings” tab. Find your form there and enable it by clicking on the “Enable” button.

CAPTCHA - list

If the form is not on the list, add it by clicking the “Add captcha point” button and enter form_id. The effect of the module for the user login form looks like this:

CAPTCHA - form

Module’s use

The Captcha module has several advanced settings that allow you to customise the protection of your websites better. The most important ones are:

  • Default challenge type - the ability to choose the type of a “trap”, by default it is a mathematical operation. External modules provide other types.
  • Default challenge on non-listed forms - a radical solution that enables protection for all forms that are not listed in the “Form settings” list.
  • Add CAPTCHA administration links to forms - a very useful option that allows you to manage the type of security directly from the given form. It saves a lot of time on complicated websites.
  • CAPTCHA placement caching - cache clearing, useful in the case of problems with forms.
  • Add a description to the CAPTCHA - adding a description explaining why the user needs to prove that they are not a bot.
  • Case sensitive/insensitive validation - determining whether there will be a distinction between uppercase and lowercase letters in solving the “puzzle” presented to the user.
  • Persistence - the ability to disable protection in certain special cases, e.g., when the user has previously confirmed their authenticity.

Hooks and integrations

Captcha provides two hooks to integrate Drupal modules that verify users. These are:

  • hook_captcha() - the main hook used to define your own submodules; it has a structure known from Drupal 7 (it transmits the $op variable containing the type of the currently performed operation).
  • hook_captcha_placement_map() - optional hook specifying the place in the form that should be modified.

This is where the real power of the module lies. At drupal.org, you can find a number of projects that implement various verification methods:

  • reCAPTCHA - to support the most popular verification services available, provided by Google.
  • Image CAPTCHA refresh - this module is an integral part of Captcha for Drupal 8; for Drupal 7 it functions as a separate project. It introduces a widget with an image from which one has to rewrite a text.
  • CAPTCHA Pack (alpha version only) - a collection of very interesting “traps” for bots, including completing a missing letter or word in a sentence.
  • Text CAPTCHA (Drupal 7 only) - integration with the textcaptcha.com website.
  • Captcha Riddler - allows you to define your own set of puzzles for the user.
  • Hidden CAPTCHA (Drupal 7 only) - cheats bots by inserting an invisible field that blocks the form from being sent.
  • CAPTCHA after (Drupal 7 only) - only runs Captcha after the user has submitted the form multiple times.
  • KeyCAPTCHA (Drupal 7 only) - integration with the keycaptcha.com website.
  • Draggable CAPTCHA (Drupal 7 only) - a drag & drop puzzle, no dependence on external websites.


The main arguments behind the module are the effectiveness and simplicity of implementation. It is perfect for fighting against Internet spammers.

We also use it in our Drupal agency as a tool that fits every form and does not require additional coding.

Jan 28 2021
Jan 28

Drupal's editing interface can be unclear to novice editors, and the number of options may seem overwhelming to many. The Simplify module comes in handy here, as it allows you to limit the available functionalities to the necessary minimum, thus making website editing easier.

Further down the article I will present the module's capabilities and the effects of its operation.


The first version of the module was released in December 2010. Since then, it has been slowly but steadily developed. At the end of 2015, a stable 1.0 version for Drupal 8 was released.

Module's popularity

According to official statistics, Simplify is used by over 15 thousand websites, however only 20% of this number are Drupal 8-based projects. The 7.x-3.x branch is currently by far the most popular.


Module's creators

The module has four maintainers, they are:

So far 72 commits have been created in the code repository. In addition to the developers mentioned above, several people have been involved in the project.

What is the module used for?

The module is used to simplify administration forms by hiding selected functionalities from the user. This makes it easier for those less proficient in the use of CMSs to edit pages and blocks.


You can download the module at Drupal.org / Simplify.

After launching Simplify, select the elements that should be hidden from the user. Go to Configuration -> User interface -> Simplify in the administration menu and check out the list of options there.

Module's use

The functionalities that can be disabled are divided into several categories according to the module that supports them. For example, try to disable all the "Nodes" type elements:


As a result, the users visiting the page editing form will see its significantly simplified version - without the author, text type selection, promotion and versioning.


As the administrator, you have the View hidden fields permission which ignores the changes made by Simplify. If you want to put administrators on an equal footing with all the registered users, check the Hide fields from admin users option.

By default, the Simplify module allows you to hide the editing elements of nodes, blocks, comments and taxonomies.

Hooks and integrations

The module provides two hooks for adding your own exclusions to any form. Their use is very simple:

  • hook_simplify_get_fields_alter() - is used to change the list of exclusions; here you can add your own options or remove the existing ones
  • hook_simplify_hide_field_alter() - in this hook you hide a given field by modifying the array containing the form


Simplify is a module that is simple by design but is a great help for novice editors. It is good to consider using it on corporate websites where the user may be overwhelmed by the number of options available. Referring to the experience of our Drupal agency in cooperation with clients, I recommend it, especially if you put a lot of emphasis on edit forms.

If you are interested in CMS optimisation, check out the article on 6 ways to improve editors' productivity.

Jan 22 2021
Jan 22

Paragraphs are one of the solutions competing for the title of the most convenient way to create content in Drupal. They are a great and consistent concept, however their UI leaves much to be desired. Thanks to the Geysir module, you will be able to improve your paragraph experience.

It is a module that cannot be easily ignored. We liked it so much that it has become one of the key elements of the Droopler distribution created by Droptica.


The first developer release of Geysir was introduced in September 2016, and the stable version was published exactly one year later. There were two major updates in 2020; many of the bugs they fixed were reported by our Drupal developers.

Module's popularity

Geysir is a relatively new module. According to the official statistics, it is used by about 500 websites. About 20% of this number are installations of the aforementioned Droopler.

Module's creators

The module has four maintainers from the Amplexor company, namely: Sander Vleugels, Jochen Verdeyen, Kevin Van Ransbeeck and Jan Lemmens. Together with 11 other developers, they have created 140 commits so far.

What is the module used for?

The module introduces a convenient interface for handling paragraphs, operating directly in the frontend part, bypassing the administration panel. Thanks to Geysir you can avoid the time-consuming browsing of the list of paragraphs. All you need to do is place the cursor over the content you are interested in and click the edit icon. In addition to editing, you can also add new paragraphs and move existing ones.

[embedded content]

For more videos on how Geysir works, check out our article on how to shorten time creating marketing campaigns using landing pages.


You can download Geysir at https://www.drupal.org/project/geysir - it has no configuration. The Paragraphs and Entity Reference Revisions modules are required for its operation. You can enable access for individual user roles via the "Manage Paragraphs from the front-end" permission.


Module's use

After launching Geysir, you will notice a "Paragraph overlay" button in the upper right corner of the page. It is used to switch between the edit modes.


Activate the button and go to the subpage with paragraphs. Note that from now on, you do not need to use the page edit form in order to change something. You can just use the icons provided by Geysir:


In the above screenshot from the Droopler distribution, you can see four new options:

  • Add a paragraph in the selected place.
  • Edit a paragraph.
  • Cut and paste a paragraph to move it within the page.
  • Delete a paragraph.

All these operations work via AJAX without the need to reload the page.

You will surely be interested in what adding and editing paragraphs looks like in this case. Well, the forms are launched in a modal window:


The advantage of this solution is the extraordinary speed of introducing changes. What is important, this method of content modification is much easier to understand, which makes training the employees responsible for the website easier. Try to create at least one website using Geysir, and I am sure you will notice a significant difference to the standard edit page.

Regarding the disadvantages of the Geysir module - note that the paragraph editing form above uses mostly the frontend skin. The skin of the administration panel (Seven, Claro, etc.) is sometimes overwritten here. Hence, functionalities such as views from the Media module require special treatment in order to ensure full compatibility and a consistent UI.

Hooks and integrations

The Geysir module provides one hook: hook_geysir_paragraph_links_alter () for changing the list of icons depending on the context of their use (paragraph type, parent entity and the reference field used in it).


If you use paragraphs, give Geysir a chance. It is a module that may cause some problems at first, but in the long run it will significantly speed up your work, which we can absolutely confirm in the case of many projects that we have carried out in our Drupal agency.

If you need a ready-made and proven solution, I encourage you to familiarise yourself with the Droopler distribution that we develop, which has a number of visual improvements to work between Geysir and Bootstrap 4. It is open source software and you can install Droopler yourself at no cost.

Jan 21 2021
Jan 21

In the era of increasingly distributed architecture of applications and web portals, there is a need to provide flexible methods of authentication while maintaining convenience for the user. From this article, you will learn how to easily create an authentication server and client application in Drupal using OAuth2 and OpenID Connect.

Distributed systems, their scaling and maintenance is a problem for many clients who come to our company to take advantage of the Drupal consulting services. Very often, there is a need to implement a central login system for all platforms belonging to a wider federation of websites. Large companies and organisations have separate portals – we have created image-building websites, intranet systems and Drupal Commerce services for them many times, taking into account various functions. The need to register a separate account and log in by users in every single place separately seems to be an archaic way of dealing with the problem. After all, who among us does not make it easier for themselves to register on websites on a daily basis – for example by employing quick registration methods using an account on a social network or a Google profile?

Why not do the same, especially since – as it will turn out in a moment – using Drupal for this is very easy.

OAuth2 and OpenID Connect

In order to shed some light on the whole problem, one should, first of all, focus on the commonly used standards in web applications that are used in the authentication process.

The first is OAuth2, an open standard for authorisation that does not require sharing authenticators between applications. Access to resources (if it has been granted) is being verified on the basis of a token issued to client applications by the authorisation server.

As OAuth2 was designed with authorisation in mind, that is – with granting specific access to given resources; it is not really directly intended for a standard user authentication (logging-in) process. For this purpose, it was decided to propose an additional (authentication) layer to the OAuth2 protocol, which standardises this exact process in it. This technology is called OpenID Connect and – apart from the logging-in process – it also unifies the method of exchanging user profile data between applications. We will, therefore, take a look at how to employ both technologies in practice.

Installation of the modules

If you want to set up both the OAuth2-based authentication server and the client applications based on OpenID Connect, in Drupal, you can basically use ready-made solutions. In the case of a server, you have several appropriate modules, including the most popular one (simple_oauth). In our example, we will use the OAuth2 Server module. It is slightly less popular and has not yet been released as a stable version for Drupal 8 and 9, but it is supported by significant companies and organisations related to Drupal.

Additionally, the second client application module, OpenID Connect, is a project being maintained and developed by exactly the same organisations and development team. You can, therefore, be sure that both projects will be developed simultaneously and that no problems with their compatibility will arise at a later time.

The modules' installation is standard. First, you need to download and install the modules on our server:

composer require drupal/oauth2_server
drush en oauth2_server -y && drush cr

Then, in a similar way – for the client:

composer require drupal/openid_connect
drush en openid_connect -y && drush cr

The main dependency needed to install the server is the oauth2-server-php library which provides the basic mechanisms to fulfil this role. If you are using Composer in PHP, all dependencies are already terminated automatically for you.

Server setup

The setup of the OAuth2 Server module is mostly based on entities. Therefore, among the things it provides are the entity of the server, client, token, etc. Our setup must begin with defining the server. So, we go to the setup page /admin/structure/oauth2-servers.


And add a new server (Add Server). In the next step, we see the server entity form:


In the simplest configuration variant, we leave all the values selected by default and filled out. In addition, we check the "Use OpenID Connect" option as the default layer used in the logging-in process.

As you can see from the settings, the authentication and authorisation process takes place without the use of the authentication data sent by the client, but on the basis of an authorisation code – exchanged then for the access token and the refresh token, which are exchanged during the communication between the applications. The technical details of the OAuth2 protocol go beyond the scope of this article, so if you want to know more about how the individual options and the protocol itself work, you can do so using the official documentation.

In the next step, we should define the clients that can connect to our server. We must, however, have at least one client application in order to do this.

Client setup

OpenID Connect is a very user-friendly module also in terms of setup. To configure the clients you want to use, go to /admin/config/services/openid-connect.


As you can see, there is a list of clients in the form. The module, therefore, allows you to easily login using, e.g., well-known social networks. Each type of client is defined as a separate plugin (OpenIDConnectClient), which makes it easy to extend the project with completely new clients. Our example, however, is about connecting to our own server, so we will use the client for generic uses (Generic).

The configuration is quite simple because it consists of defining the client's name and the so-called secret key, as well as providing the server addresses:


While we are at it, we will add a small improvement, namely – replace the logging-in form with a login button using our authorisation server. It is very simple and accessible from the setup form:


Great! The client looks ready to use. The only drawback is the lack of a convenient option of changing the name from "Generic" at the moment without a bit of coding, but the result still looks great for such a quick setup:


Server setup part two

We have a pre-configured server, as well as a ready client. So, let us define our client in the server setup so that it knows it can connect to it and request access to its resources. Drupal is a very secure CMS compared to the competition, but the security is also based on its correct setup.

Always remember that it is up to you to verify and configure what client applications should be able to connect to the server and use its resources.

In order to add new clients, go to the Clients tab, and then click the button for adding new clients.


You should see a form, the data of which should be filled out in the same way as what you set up in the OpenID Connect module in the client application.


We save the form, and it is ready... almost. You still have to grant the appropriate permission, so that it would be possible to use the OAuth2 server at all. In order to do this, go to the /admin/people/permissions page and assign the Use OAuth2 Server permission for the anonymous user.



All is set. So, let us check the actual logging-in scenario. First, we will register the test user on our server so that they can log in into our other applications.


Go to the client's application (login form) and click the Log in with Generic button (form screenshot).

You are redirected to the server login page on the server along with the destination parameter destination


After correctly entering the login and the password (test:test), you should see this additional step ...

the form

...in which you decide as a logging-in user whether you actually want to authorise our client page to your user data from the server, on the basis of which a local user account will be created.

After approving it, you are redirected to the client application page as a logged-in user:


Success! We can now fully enjoy our central login system.


The possibility of creating a central login system is a more and more frequently occurring need among the clients who have various types of distributed services, sites, and applications. By choosing Drupal, you can focus on implementing specific business rules, instead of reinventing the wheel. Using the ready-made solutions, such as OAuth2 Server or OpenIDConnect, supported by well-known organisations, gives you the certainty that you will easily implement the mechanism you need – even without the need for detailed knowledge of the protocols used in them.

In our Drupal agency, we always use the already available solutions which we often extend, and we adapt Drupal modules to the specific business model. I hope that the above article and the modules used will also prove useful in your project.

Jan 08 2021
Jan 08

Website statistical data is required knowledge if one wants to effectively manage the website, and thus – determine the directions for its further development. Thanks to numerous Drupal modules, you can make the necessary improvements also via integrations with Google Analytics. In this article, you will find information about the GoogleTagManager (google_tag) module, thanks to which you can conduct an effective and structured analysis of your website.

The need to put external scripts on websites dates back to the 90s, when webmasters got a taste for counters and guest books. Over the past three decades, simple external services have evolved into advanced and powerful solutions such as: Salesforce, Hotjar or Mautic, the implementation of which we provide at Droptica. Modern websites use dozens of tools to research user behaviour, collect the data on visits and for A/B testing. Today it is difficult to imagine effective marketing without them.


The Google Tag Manager service was launched in October 2012, and the Drupal module to support it was released in February 2014. A stable version of the module for Drupal 8 was released only at the beginning of 2018. The development was quite slow, however google_tag was very stable from the beginning.

The module's popularity

It must be said that the module has won over a large group of users. According to official statistics, it is used by over 51 thousand websites while more than half of this number are websites based on Drupal 8/9.

Module's creators

Jim Berry from Boombatower is responsible for the maintenance of the module. He is a developer who has made a huge contribution to the Drupal community. He is the author of over 1500 commits in dozens of projects.

What is the module used for?

The google_tag module is used for advanced integration with Google Tag Manager, reaching much further than simply pasting the GTM script into the website code. Here you have access to user roles and exclusion lists, among others. I will present all these functionalities later in the article.


You can download the module at https://www.drupal.org/project/google_tag. After the installation, add a new container and enter its ID obtained in the Google Tag Manager panel. You can find the module settings in the Configuration - System - Google Tag Manager menu.

Module's use

The google_tag module has a default configuration that will work for the vast majority of applications. However, it is worth looking into the advanced settings, which give more control over the included scripts.

Containers list

A novice user will certainly ponder what the list of containers available in the configuration panel actually is. Well, the latest versions of the module allow you to handle more than one GTM container (in other words: various unique identifiers assigned by Google). Such a solution works perfectly when you have a page farm for which you can separate common scripts stored in a shared container.


When adding a new container, you will see a form with the default settings filled out. If you do not want to waste time customising each of the containers, you can specify the default settings in the "Settings" tab.

Adding a container

The form for adding a container mainly contains its unique identifier (Container ID) obtained from Google and a label that will be used to recognise individual containers within the Drupal administration panel.

Google Tag Manager - Container add

In the "Advanced" tab you can find three interesting settings:

  • Ability to rename a data layer. In most cases, the standard dataLayer is enough, but it is worth keeping this option in mind in case of a conflict. To clarify: a data layer is an array (more precisely - an object) in JavaScript that is used to transfer data from a website to a GTM container.
  • Support for allowlist and blacklist options, described in more detail in GTM help. This is a rarely used, but useful functionality that allows for additional blocking of some tags in the production environment before they are ready for implementation, among other things.
  • Configuration of the current environment which enables switching between the production and development set of tags.

Google Tag Manager - Container add advanced

A bit further down you will find the exclusion settings. The GTM script can be activated and deactivated based on:

  • The current path in the URL (by default, tags are not launched on admin pages).
  • User Roles (A common case of use is disabling analytical scripts for the administrator role).
  • HTTP status code (e.g. 404).
  • Content type.

Google Tag Manager - Container add exclusions

Module configuration

In the settings tab there is a configuration common to all containers. There are several options to improve the performance of your website and make debugging easier.

Google Tag Manager - settings

The first four settings are for the optimisation of the JS script delivery that supports Google Tag Manager. I recommend leaving the recommended values here, and at the same time I would like to warn you against possible errors returned in the website log. During projects in our Drupal agency, we often encountered a situation where the GTM script file was not generated due to the lack of directory permissions.

Hooks and integrations

The google_tag module provides the following hooks:

  • hook_google_tag_insert_alter () - unlocks or blocks a given container if you want to make its operation dependent on factors other than the standard ones (i.e. role, path, content type and HTTP code).
  • hook_google_tag_snippets_alter () - changes the default JS code that supports GTM.

In addition, it is possible to implement plugins providing Conditions for placing the Google Tag Manager script on the website.


In a previous article I discussed in detail the integration of Drupal with Google Analytics. I am sure that use of the above, together with the google_tag module described in this text, will make website analysis even more effective and orderly. The google_tag module has almost become an industry standard over the past few years. I recommend using it and exploring the possibilities that the world of Drupal tags and data layers opens up for us.

Dec 18 2020
Dec 18

Security Kit is a module that helps with eliminating the likelihood of exploiting security vulnerabilities on your website. Thanks to a multitude of features, such as Anti-XSS, Anti-CSRF, Anti-ClickJacking you can get yourself a peace of mind and comprehensively define a security policy for your website.

At our Drupal agency, we value the security of our customers' websites and make every effort to ensure that the solutions we provide are as bug-free as possible, which is why our development team uses tools to achieve this goal optimally. We use modules provided by Drupal's outstanding community, which facilitate this process. For example, when auditing an acquired project, we use the Hacked module, and while implementing the solutions required by your projects, we are always taking advantage of the Security Review. Today I would like to introduce you to another module that will help you secure your website – Security Kit (SecKit).


The first version of the module was released on 26 March 2011. The latest update was released on 28 August 2020. The module is now considered to be feature-complete by its developers – new features are currently not being developed, and the updates focus solely on patches.

Module popularity

The module is used by about 56,000 websites, including 25,000 based on Drupal 7 and 26,000 on Drupal 8.


You can find detailed popularity statistics here.

Module developers

The module was developed by p0deje. It is currently maintained by Acquia and Catalyst IT. The vast majority of commits were provided by p0deje (141), jweowu (26) and mcdruid (24).

As of now, the module has four maintainers: mcdruid, jweowu, badjava, and p0deje.

What does it do?

Security Kit combined with Drupal offers additional options and features that improve security, reducing the risk of exploiting vulnerabilities on your website, by adding Anti-XSS, Anti-CSRF, Anti-ClickJacking, HSTS and CORS implementations. The module enables you to define a multitude of security policies – you can find a description of each configuration option in the "Settings" section.

Let's take a closer look at what it can do for you!


Features that help lower the possibility of exploiting cross-site scripting (XSS) vulnerabilities on your website. XSS is a type of website vulnerability that allows the attacker to execute any JavaScript code directly on the end device. XSS may result in leaking data, such as login and password, credit card details, user account information and much more. There are a number of types of XSS attacks; if you want to learn more, you can start exploring them here.


Cross-Site Request Forgery (CSRF) is an attack type that allows the attacker to trick end users into performing specific actions on a website. A CSRF attack may, for example, result in the end-user losing their funds, changing their email address linked to the website, changing their password and any other action which the user can perform.


Clickjacking is an exploit which enables an attacker to trick end users by displaying a concealed xframe, which the user can unwittingly click to run a given action on another website. Attacks of this kind can be used, for example, to farm likes on the attacker's Facebook page. The latter type of attack now even has its own name – Likejacking.


HTTP Strict Transport Security (HSTS) security policy that minimises the risk of man-in-the-middle attacks, which entail modifying a request before it even reaches the server.


Cross-origin resource sharing (CORS) is a mechanism that allows you to specify a list of trusted domains from which the user can download resources on your website.


The module does not require any external libraries to work correctly. Security Kit can be installed in a standard manner, but – as always – we do recommend using composer:

composer requires drupal/seckit


Cross-site scripting

This section contains settings that boost your website's security performance in terms of XSS-type attacks.


Content security policy

Security policy enables you to identify trusted content sources. Serving content from untrusted sources may lead to security issues, such as data leakage and malware distribution. You can read more about this here.

Send HTTP response header

If you select this option, the CSP policy is enabled.

Enable Upgrade Insecure Requests

If you select this option, all HTTP requests are redirected automatically to HTTPS.

Report only

If this option is selected, all the cases of content security policy breaches will not be blocked, only logged.


This option defines a security policy for all content on the website, such as scripts, styles, images, media, frames, etc. If you do not specify a separate policy for a given content type, the CSP will use the policy specified in this field.

This allows you to provide trusted sources for particular content types, such as script, object, style, img, media, frame, font.


Path used for reporting requests violating your CSP policy.


If you want your CSP policy to be saved in one file, here you can specify a path. If this field is filled, the settings per content type are omitted.

X-XSS-Protection header

Each browser has its own internal safeguards against XSS. X-XSS-Protection header enables you to disable the default anti-XSS protection built into your browser, run the safeguards along with modifying unsecured content to protect users from XSS attacks or run protection mechanisms that will block all dangerous content. If you would like to learn more about the header, take a look here.


This section contains settings that protect your website from cross-site request forgery attacks.


HTTP Origin

If you select this option, you enable the validation of the HTTP request source, thus enabling CORS protection.

Allow request from

A list of accepted requests.


This section contains settings that improve your website's security in response to ClickJacking attacks.


X Frame options

X-Frame-Options configuration

  • Disabled - disables the X-Frame-Options header.
  • SAMEORIGIN – makes it so that the page can display xframes only served from the same domain.
  • DENY – locks all xframes.
  • ALLOW-FROM – allows you to specify a list of domains with xframes enabled.

You can read more about the XFrame header here.

You can also find the header specification here.

JavaScript-based protection

Enables anti-clickjacking protection using JavaScript. This solution will not work for users who block JavaScript using browser plug-ins such as NoScript.

Custom text for disabled JavaScript message

Enables you to provide a message that will be shown to users blocking JavaScript on your website, as well as users whose browsers do not support JavaScript.


A section containing settings improving SSL/TLS security.


HTTP Strict Transport Security

Enables the Strict-Transport-Security (HSTS) header – enabling this option will increase security by reducing the risk of man-in-the-middle attacks such as SSLStrip. You can read up on HSTS here.


Defines the max-age value of the HSTS header. Max age is the number of seconds for which the website is treated as HSTS-enabled by the end-user.

Include Subdomains

Enables HSTS for all subdomains – by default, the HSTS header is only sent from the main domain.


Most popular browsers have HSTS preload lists with sites that are defined as HTTPS-enabled. If you want your domain to be added to the HSTS Preload list, you need to check this option.

Expect CT

Expect-CT header configuration options allow you to enable reporting and enforcing the Certificate Transparency policy. The Certificate Transparency Policy defines the sources, delivery and signing mechanisms of certificates when using TLS connections. You can read more about this here.

Expect CT


Enables Expect-CT header.


Defines the max-age attribute for the Expect-CT header. Max age is the number of seconds after receiving the Expect-CT header during which the user's browser considers your website to be compliant with Expect-CT header.


URI for reporting Expect-CT errors. Errors are reported if the user does not receive correct CT information.


The optional header parameter specifies whether the user should enforce the Certificate Transparency policy or only report in case of an error.

Feature policy

Configuration options for the Feature-Policy header, which determine the API configuration and behaviour, as well as features provided by the browser, for example, it allows you to limit the APIs used for interacting with user's camera or microphone, as well as change the default behaviour of the autoplay attribute on mobile devices. You can find out more about this here.

Feature policy

Feature policy

Checking this option enables the Feature-Policy header.


Defines the Feature-Policy header policy.


Configuration of the remaining module options that do not belong to any particular category.



Enables the From-Origin-Response header. This option specifies websites on which the resources from your website can be embedded. You can find out more about this in the header specification.

Allow loading content to

Enables you to specify a list of domains, where your content can be embedded (if From-Origin is used).


Enables the Referrer-Policy response header.

Select policy

Defines the policy for the Referrer-Policy header. Information about this header and available options can be found in the specification.

Disable autocomplete on login and registration form

Checking this option will disable the ability of the browser to fill in the login and registration forms automatically.


The presented module enables you to configure many options that increase the security level and performance of your website. It also provides you with a number of ways that allow you to define security policies, while the added security mechanisms help protect your website against popular attacks. Our Drupal developers recommends deploying the SecurityKit module.

Dec 17 2020
Dec 17

Google Analytics is, by far the most popular tool to track your web page visits, used by tens of millions of sites around the world. Integration with Google statistics is the most basic and essential function of every CMS, which means it is also available in Drupal – you can enable it with the google_analytics module.

The module has numerous interesting features, which can be easily missed among the many configuration options. In this article, I will showcase some of the most useful options, based on experiences with large Drupal corporate websites.


The google_analytics module has a long and rich history, as the very first development version was released in February 2006 for Drupal 4. The first stable release saw the light of day a year later, in March 2007. The current version – 3.x – was released in early 2019. Unfortunately, dynamic changes in the module have recently slowed down considerably, perhaps as a result of changes in the development team.

Module popularity

The google_analytics module is one of the most popular Drupal add-ons, and the official data report that it is used on 323,000 pages in total. The latest 3.x version is used by more than 27,000 Drupal 8 and 9-based websites. Module authors Currently, developers from two companies are responsible for maintaining the module: IXIS (Mark Byrne, Mike Carter) and Acquia (Jakob Perry). By far the largest number of commits was made by one user – hass, who has been inactive on drupal.org for quite some time now.

Together with the people mentioned above, 66 people in total have been involved in the development of the module since 2006. You can see their contributions at committers website

What does it do?

The google_analytics module, as the name suggests, is used for integrating Google Analytics statistics with Drupal-based websites. Although this integration is very simple and basically boils down to placing a small script provided by Google somewhere in your HTML code, using a dedicated module for this is very much worth it, as it will enable you to tailor your visit tracking to your needs and eliminate unwanted things from your statistics.


You can download the module from https://www.drupal.org/project/google_analytics. After setting it up, all you need to do is to provide the code provided by Google (it starts with UA-). If you forget to enter the code in the settings panel, you will receive a warning when you log in as an administrator.

You can find the module settings in the Configuration → System → Google Analytics menu.

Using the module

The vast majority of users use the module in its default configuration – they only provide the tracking code, and thus all the following features remain active:

  • exclusion of statistics on administrative pages;
  • enabling the tracking of external and mail-to links;
  • recording downloads as events;
  • tracking the usage of pop-up windows provided by the Colorbox module;
  • anonymisation of IP addresses sent to Google.

All of the above features will be described in more detail later in this article.

Multi-domain support

Drupal has extensive support for multiple domains within a single project, and in such case, it is crucial to include an additional column concerning the current domain or subdomain in the statistics. The google_analytics module fully supports multi-domain configurations, which can be further customised with a single checkbox.

ga multidomain

Excluding pages and users

Another very important feature offered by the google_analytics module concerns disabling tracking if certain conditions are met. Just like in the case of block configuration, you can select the pages where your tracking code will be enabled or disabled, which will allow you to eliminate unwanted locations that disrupt your results.

Google Analytics - Wykluczenia stron

You can do the same thing for certain user roles. By excluding administrators, you will make sure that your activity on the website will not be tracked.

Google Analytics - Role użytkowników

Additionally, users can decide for themselves whether they want to be tracked. If you care about their privacy, select the following option:

Google Analytics - Opt-in

Users with the role of "Opt-in or out of tracking" will be given the option to disable tracking in their profile options.

You should pay particular attention to the "Track User ID" option. If it is checked, Google Analytics will start distinguishing users by their Drupal identifier. Using this feature may be very tempting from the point of view of the quality of the data collected, but it entails major changes in privacy policy to ensure compliance with the GDPR.

Given the privacy point of view, the "Anonymize visitors IP address" option, which is also crucial, is hidden in the last tab. It cuts off the last part of the user's IP address sent to Google Analytics, making the tracking less accurate but more anonymous.

Tracking links and downloads

The standard Google Analytics tracking code does not offer features that enable tracking external links and file downloads, which is why you will undoubtedly appreciate the automatic modification of Drupal link behaviour thanks to JavaScript. After clicking on a link, GA receives an event containing the URL. This way, you are able to estimate the popularity of links and files.

Google Analytics - Download

Some of the other options in this tab enable you to:

  • Track events in Colorbox;
  • React to changes in the URL;
  • Use "In-Page Analytics" service – the visual map presenting the popularity of your links – in a more precise manner. I would recommend this feature in particular when the person responsible for marketing can quickly introduce in-depth changes to the website (refer to our article about quick campaigns using landing pages).

Message tracking

Another small yet very significant addition is tracking messages displayed at the top of the page. By using this, you can use a message about successfully placing an order as a separate event, which in turn can be used as one of the Google Analytics tracking objectives.

Google Analytics - Messages

Search and advertising tracking

The "Search and advertising" tab has some more niche functions:

  • "Track Internal Search" tracks searches on the website;
  • "Track AdSense ads" sets up integration with ads running on the website via AdSense and enables advanced effectiveness reports;
  • "Track display features" activates advanced marketing features, including remarketing. This option requires special provisions in the website's privacy policy, as it significantly impacts compliance with the GDPR.

Google Analytics - Search, AdSense, Remarketing

Customised dimensions and metrics

Google Analytics reports offer extensive possibilities of expanding columns and rows in your tables with custom elements, using dimensions and metrics.

The google_analytics module allows you to add up to 20 custom metrics and dimensions, including tokens defined in Drupal. Here are two examples that will make it clearer.

The dimensions describe the page in question. They can be a category or a tag. For example, by adding a non-standard dimension in the form of an article category, you can determine the popularity of a given topic.

Google Analytics - Dimensions

The metrics measure objects. Google Analytics is able to sum up data and carry out operations on them. When you add a metric with a value of 1 when an article is promoted, you can sum up and compare the number of promoted and standard impressions in the report.

Google Analytics - Metrics

Other options

Among the other available options offered by the module, there are:

  • Local caching of Google Analytics code;
  • Aggregating multiple language versions of pages in the statistics;
  • Defining additional parameters to be provided to Analytics;
  • Launching your own scripts before and after executing the GA code;
  • Developer mode.

Hooks and integrations

The module does not offer any hooks. As far as integration is concerned, it works mainly with Colorbox.


The google_analytics module is an extremely powerful tool, which will undoubtedly be appreciated by users who appreciate accurate and effective web analytics. Despite the rather small set of integrations with other modules, it offers in-depth customisation, which allows you to adapt the configuration to your needs.

Projects that are developed at our Drupal agency usually take advantage of Google Analytics. We have already mentioned in our other articles that advanced integration with GA is one of the important advantages of Drupal as a CMS for building large websites.

Dec 09 2020
Dec 09

When working on a project, there are many ways to increase the security of a website. One of them is the use of automated security tests that assist developers in eliminating as many security bugs as possible.

At Droptica, our Drupal developers focus on delivering the safest solutions. The Drupal CMS itself helps us in this, as it is safer than other CMSs. Thanks to the huge community focused on opensource projects, one of which is Drupal, clients, on the one hand, receive effective solutions, and on the other hand, can be sure about their security. At this point, it is worth to mention a special team dedicated to this issue, which is the Drupal Security Team.

In this text, I would like to introduce you to the operation of one of the tools to increase the security of your website – the Security Review module.


The module was released on 4 November 2009, and the most recent update was introduced on 4 October 2019. The module has a version for Drupal 7 and 8

The module’s popularity

According to drupal.org, 30,000 websites are using the module, 28,000 of which are Drupal 7 and 2,000 are Drupal 8.

Module’s creators

The module’s creator is the user named greggles. The module is supported and developed by the Acquia, CARD.com and Google Summer of Code organisations. The most commits were provided by the users coltrane (111), banviktor (58) and greggles (8).

What is the module used for?

The module performs an automatic website audit detailing many attack vectors that can lead to security errors. Here is the list of some of them:

File permissions

Saving files to the server’s root directory is dangerous and may lead to a remote code execution error. An attacker can use this vulnerability to take control of a website. More information on the correct configuration of permissions can be found at this link.

The list of tags accepted by the text formats available in the CMS

Some HTML tags are considered unsafe. This means that they may allow an attacker to take control of a website. Drupal has an HTML filtering engine that removes malicious tags - this test checks if the filtering is set up correctly.

Error reporting

Drupal may disclose information about errors to unauthorized persons. An attacker can use this information to refine an attack or find more vectors.

Unsafe file extensions

Some extensions are considered unsafe. This means that they can cause security errors such as remote code execution. This allows an attacker to take control of a website, and Security Review checks whether Drupal enables the transfer of files with unsafe extensions.

Database errors

Many database errors triggered by a single IP address are a sign that someone is trying to make a SQL injection attack. The module informs if multiple database errors were triggered from the same IP address.

Login panel brute force

Multiple failed login attempts are an indication that someone is trying to get into another user’s account. You are being informed about it.

Trusted hosts (HTTP host header attack)

Correct configuration of Trusted Host protects against HTTP host header attack, a detailed description of the settings is available at this link.

Views access

Security Review recommends that access to Drupal views should have at least minimal ‘access content’ control. This test checks whether the views have at least a minimum level of access control.

Security Review does not introduce any security fixes but only suggests where vectors of attack may be present. These are suggested changes that need to be analysed by a specialist.


The module installation is standard, but we suggest using the Composer:

composer require drupal/security_review


Under the address


you can configure the module by selecting roles that are not trusted. Security Review uses this as a basis for checking whether the users with not trusted roles have permissions to the functionalities that may cause security errors. You can also choose which items from the checklist you want to omit and choose the method of checking the trusted hosts.


Role configuration

The module provides two types of permissions: ‘access security review list’, ‘run security checks’. First, you need to configure the trusted roles that will be able to read reports and run the scan. In order to do this, go to


and configure the permissions for selected roles:


Module’s use

The module has already been configured. To run an audit, just go to


and click “Run checklist”, and Security Review will conduct the audit. You can also use the drush command:

drush secrev


Every test has a summary that you can see by clicking on the “details”. An example for “Errors are written to the screen”:


Moving on to the error logging settings, you can see that Drupal shows all the information, including the backtrace:


In the case of a production version of a website, set this option to “none” in order to minimise the risk of disclosing information that could help an attacker to hijack the website.

Similar information is provided for each of the security errors detected during the audit. All items should be reviewed manually, and appropriate changes should be made – if required.

Alternative modules

The Paranoia module identifies all the areas where a user may be able to trigger the custom PHP code and tries to block them. This reduces the possibility of a remote code execution error occurring. In addition, the module protects the main admin account (account with id 1), preventing its editing and blocking the possibility of uninstalling itself using the standard way (to uninstall the paranoia module, you need to edit the database manually). All the functionalities provided by the Paranoia module are intended to increase the security of a website.


The Security Review module is an extremely important and useful tool. Thanks to the information collected by the module, you gain invaluable knowledge of what should be done in order to improve the security of your website. After analysing the results, you can eliminate some of the attack vectors. Our team recommends using this module when creating a website.

Dec 03 2020
Dec 03

Recurring payments are gaining in popularity and are also increasingly used by well-known brands. You will find this type of a settlement model in Netflix, Spotify, or Apple Music, among others. Undoubtedly, they are convenient for e-business due to the regularity and timeliness of payments, full automation, and security. If you want to implement this method of collecting payments, I encourage you to read this article. You will learn how to do it in Drupal Commerce.

What are recurring payments?

These are payments that are collected from customers between selected periods of time. Most often, these payments are made monthly, but there are also other models. Some systems collect payments once a year, others – once a week. It is also possible to define a quarterly cycle. Other time intervals are less common.

What can you sell using recurring payments?

Netflix and Spotify mentioned in the introduction are systems with a database of files (video, audio). In order to have access to them, one must make recurring payments.

In our Drupal agency, we implemented a similar project – using Drupal, of course. After making a payment, the user gets access to the system and unique PDF files. The client has the option of purchasing a single, specific file, as well as paying for a monthly or annual subscription. The latter option allows them to get access to all files in the system.

A similar system that we developed at Droptica is Training Realm. It is a web application that offers users the ability to log training sessions, create training schedules and adjust the difficulty of training cycles to the user's level. And as you can probably guess, we also used the recurring payment service in this case.

In the examples above, you can see that recurring payments are most often associated with digital products or services. Of course, this solution can be implemented to sell physical products. A perfect example is diet catering. The system automatically charges a monthly fee for the food to be delivered over the course of the next 30 days.

As you can see, the uses are many. Recurring payments are very convenient for businesses, as they provide them with regular income over a predictable period of time.

Installation of the recurring payments module in Drupal Commerce

I will present enabling and configuring the Commerce Recurring module on the basis of the Droopler distribution. We have prepared a starter package for Drupal Commerce there – just enable the d_commerce modules (screenshot below) to get a ready-made Drupal-based Commerce system.

Installing the Droopler system is very simple. Instructions for Composer can be found here.

If you already have the Droopler system, you need to install the Commerce Recurring module.

Download the appropriate Recurring module files and any additional modules needed for this example with the command:

composer require drupal/commerce_recurring drupal/facets_pretty_paths drupal/commerce_paypal

After running these commands in the terminal, you should see this effect:


In the next step in Drupal, go to the module list page (/admin/modules) and enable the following modules:

  • d_commerce 
  • d_commerce_product 
  • d_commerce_products_list
  • Commerce Recurring

For recurring payments, you will also need a payment module that supports recurring payments. In this entry, the example will be based on the Commerce PayPal module.

You can download the module using the command:

composer require drupal/commerce_paypal

The description of how to enable and configure the module can be found on the drupal.org project website.

Configuration of the Commerce Recurring module

After installing the module, we will see two additional pages in the admin panel:

  1. Billing schedules /admin/commerce/config/billing-schedules
  2. Subscriptions /admin/commerce/subscriptions

We will start with the settings on the Billing schedules page. Here you can decide whether the client will pay monthly, weekly, or daily. Or maybe you want to charge every 13 days? Yes, you can configure such a payment period as well.

In addition, you will also set the parameter deciding when the payment is to be collected: whether it should be immediately after the purchase or maybe at the end of the set period (e.g. at the end of the month).

You will also decide whether the payment is always to be collected on the first of the month or if it should be collected on the same day of the next month in which the purchase was made (e.g. purchase on the 13th of the month, so payment will always be on the 13th of every month).

Another parameter is proportionality, e.g. for annual payments: if someone makes a purchase in July, you will define whether they pay the amount for a whole year or only for half a year, and the next payment for a whole year will be in January.

At the end of the form, you will decide what to do if the payment fails (e.g. you can retry the payment in 3 days).

As you can see, the configuration options are many. Everyone will find a configuration that fits their business model.

Recurring monthly payments

Below you will find an example of form settings for recurring monthly payments. Payment will be charged in advance and always made in full per month (calculated from the date of purchase by the client).

In the event of a payment failure, the system will try to process the payment three more times before disabling the subscription.

This is how it looks in the form:



The full description of the settings for this form can be found in the documentation on the Drupal Commerce page.

Adding recurring payments to a product

In this case, you will see what a recurring payment looks like in relation to a product, e.g. the diet mentioned above catering.

It is a common practice to create a separate product variation that allows for a subscription. In general, every product can have a variation that will differ in price, SKU code, and/or other characteristics.

For example, an e-commerce platform dealing with the sale of clothing may have a "T-shirt" product created the variations of which will be different colour versions. In order to create variations, go to

  • '/admin/commerce/config/product-variation-types'

or through the menu

  • Commerce->Configuration->Products->Products variation types and then click "Add product variation type".

In this simple form, enter the name of the variation to be created and select "Allow subscription".


Every created product type allows you to add one variation. So, if you do not want to lose the existing products, you have to create an additional product type, the variations of which will be subscriptions.

To do this, go to '/admin/commerce/config/product-types' and click on "Add product type". Fill out the form from the drop-down list and select the previously created variation ('subscription' in the case of this example).


Then you need an actual product that the end-user can add to the shopping cart. You can add it by going to the page "/product/add". From the list of product types, select the previously created "Subscription product". Fill out the form in accordance with the fields being displayed, and then click "Save and add variations". You will see a table showing all the created variations related to this product. Click "Add variation". In the displayed form, fill out the fields such as SKU and price.

The title field, in this case, is the name of the variation being created. As mentioned earlier, one product can have any number of these, and the name of the variation itself, along with the product name, will be displayed in the order and the cart. In the case of a subscription, you can create variations divided by period, e.g. a month, half a year, a year. For this example, we have created a monthly subscription so that we will name the product variation "monthly" and in the Billing schedule field, we will select the monthly interval that we created earlier.


After clicking the "save" button, you return to the list of variations of a given product, as can be seen on the list, the title of the variation ultimately consists of the product name and the associated variation name created.


In the next step, you can go to the product view, add it to the cart and go through the purchase process. After successfully completing the payment and placing the order, if it contained any product with which a recurring payment is associated, a subscription will be created, which you can manage at '/admin/commerce/subscriptions' or through the 'Commerce->Subscriptions' admin panel.


A more detailed description of the module's operation can be found here.

Creating standalone recurring payments

So far, we have created a subscription as a separate product that the client can add to the cart also with the products that do not necessarily have to be subscriptions. But what if you do not want to create products and variations, e.g. if you want to give users the option of repeated payments?

The Commerce Recurring module also allows you to add recurring payments. This can be done in the same place where the list of subscriptions created on the basis of orders is located, by clicking the "Add subscription" button and selecting the "standalone" option. Then you fill out the form as required. Note that in this situation, it is required to specify the user to whom the subscription will be assigned.


More detailed description can be found here.


Drupal offers a wide range of possibilities to create tailored e-commerce solutions. Learn more about Drupal Commerce from our other blog posts:

If, on the other hand, you need specialist support, check out our Drupal Commerce page.

Dec 02 2020
Dec 02

During a website audit, it is possible to detect whether changes have been made to the Drupal core, modules and contrib themes. How to do that? The most effective way to do this is to use the Hacked! module.


The module was released on 8 October 2009, and the last modification was introduced on 13 February 2020. Hacked! has a version for both Drupal 7 and 8.

Module's popularity

Drupal.org reports that the module is being used by approximately 16,000 pages of which 15,100 are Drupal 7 pages and 900 are Drupal 8 pages. In the case of the Hacked! however, this is not very reliable information, as it is a module that should only be used in development environments for a short time and should be uninstalled after the work is done. So, one could rather say that 16,000 pages have the module installed incorrectly.

Module's creators

The user ivnish is maintaining the Drupal 7 module. Nobody maintains it for Drupal 8 at the moment.

What is the module used for?

The Hacked! module is an indispensable tool in the work of every professional Drupal agency. At Droptica, every new webpage accepted for Drupal support is being scanned with the Hacked! module for changes in modules.

We carry out checks in order to find any manual modifications to the Drupal modules and core. There are several goals for finding such changes:

  1. If possible, the Drupal core and contrib modules should not be changed. Drupal is a very flexible system, and, in most cases, you can achieve the desired results by acting according to good practices. If we find changes introduced by previous teams in the code, we try to transfer them to our modules and implement them in accordance with the Drupal standards.
  2. If the changes cannot be introduced into our own code, we move them to the tracked patches to be able to track them automatically and apply them with every module update.

We follow the above steps to be able to update modules easily and quickly to the latest versions without the risk that we will remove or break any functionality that someone has hidden in a contrib module. At this point, I encourage you to read the article on how to Keep Your Website Safe And Up-To-Date With Drupal Support.

Without the Hacked! Module, we do not have easy insight into changes introduced to a given contrib module, and in the case of an update, tracking down the modifications without using this module will be time-consuming.


In order to install the Hacked! module, go to the project's page at drupal.org or use the Composer we wrote a separate article:

composer require drupal/hacked

After the installation, you can configure the module by going to


The module has one configuration option:


Ignore line endings/include line endings: Depending on the operating system on which the module was modified, line endings are being determined differently. Setting this option to "Ignore line endings" will ensure that all line ending coding differences will be ignored.

In other words: if the developer opens the file in Windows and saves it while "Include line endings" is selected in these settings, then differences in line endings will be listed during the file check.

Generating a change report

After installing the module, go to


or use the drush command:

drush hacked-list-projects 


drush hlp 

The report generation process takes up to several minutes, depending on the number of files to be checked.

Review of changes

The Hacked! module provides a page with the report. We can find it under:


or by going to the "reports" tab in the admin menu, and then using the "hacked" link


In the given example, you can see that the module "Better exposed filters" contains some changes. Let us check them out:


If you have the additional Diff module, you can easily see the exact changes in each file:


Changes can also be observed using drush commands. In order to list the modules containing changes, use the command:

drush hlp


In order to list the names of the files containing changes, type:

drush hacked-details [the module machine name]

or use the alias:

drush hd [the module machine name]



In order to list the modifications in individual files in a given module, use the command:

drush hacked-diffd [the module machine name]

which will return changes between files in the same way that the git diff command does

Changes to the sample file:


Alternative modules

There are several file integrity checking modules, including MD5 Check, File Integrity Check, but they are not widely used. MD5 Check generates a checksum for files and on this basis informs the admin about changes. File Integrity Check, on the other hand, creates a "fingerprint" of the entire page and informs the admin if there are modifications to it.

Extension modules

We recommend installing the Diff module, which allows one to clearly track the changes between the current version of the file and the one downloaded by the Hacked! module.


The Hacked! module solves the problem of searching for modifications in the Drupal core and contrib module files. It provides a functionality which, in combination with the Diff module, allows you to see the differences between the original and modified files clearly.

Nov 27 2020
Nov 27

Drupal is being chosen as a platform for building websites, among other things, due to its flexibility. If you want a system ideally suited to your business model and better than the competition's systems, Drupal will prove to be perfect. One of the areas you can customise in Drupal is the user permissions system. Take a few minutes to learn about the permission management abilities of Drupal.

General information

Drupal allows you to manage access from the admin panel and from the code level. In this post, I will present these two possibilities and the most common examples of their use.

Roles and permissions in the Drupal core

If this is your first time dealing with Drupal and its permission system, you should know that there are three elements used for granting permissions:

  1. User
  2. Role
  3. Permission

When installing Drupal, you create a root administrator account in the system (identifier 1 in the database). It can be compared to the root user in Unix systems. This user has access to all subpages and settings in the system.

You can add more users to the system. These could be, e.g. the editors responsible for creating the content, or the moderators deciding whether to post the added comments.

If you want to assign a permission to a given user, you do it indirectly by assigning a role to them. There is no association between a user and permissions in Drupal. There is a user-role association and a role-permission association.


How to add an editor role and assign the appropriate permissions to it

This is probably the most common issue encountered in Drupal. You need to let users into your system, but you want to limit their rights to the content management only. You do not want to give the rights to change the system configuration or to add new users.

In order to achieve this, follow these steps:

  1. Add a new role on the page "/admin/people/roles/add/".
  2. Assign the selected permissions to the role on the page "/admin/people/permissions/". For the content-related ones, check out the "Node" section. Below you can find more information on the permission list.
  3. Assign the selected user to the new role on the page "/admin/people/".

Then log-in into the account of the selected user and check out whether they have the appropriate permissions. Maybe you need to extend them or take them away. If you are unfamiliar with the Drupal's permission system, such a test with logging-in into the user account is always worth carrying out.

You do not need to know the password to the user account you want to log-in into. You just need to install the module Masquerade. Thanks to it, you can log-in into the account of any user.

Drupal core permissions overview

When entering the page "/admin/people/permissions/" for the first time, one can get a little scared. This is probably the longest configuration page in Drupal.

Let us start with the table header. You will always see the word "PERMISSION" in the first column. In the next cells of the first row, there will be the names of the roles. The more roles you add (you can add them on the page /admin/people/roles/add/), the more of them you will see in this table.

Then, looking at the first column in its entirety, you will see a long list of permissions. The permissions are divided into sections. The sections are the names of modules. The "Node" section mentioned earlier is named so because the permissions in this section are defined in the "node" module (you will find it on your disk in the core/modules/node directory).

Some sections have only one permission, e.g. the "Block" section has the "Administer blocks" permission only. Others have many more of them.

If this is your first time dealing with Drupal permission settings, I suggest that you read the names of all permissions. The names themselves explain what a given permission is for.

Anonymous & Authenticated

There are two system roles in Drupal that cannot be removed:

  1. Anonymous User
  2. Authenticated User

The first of these roles is responsible for all non-logged-in users. For example: if you want to add the ability to view user profiles for all non-logged-in for the "View user information" permission, tick the checkbox in the "Anonymous User" column.

"Authenticated User" is the role assigned to all logged-in users. It is important here to understand the permission inheritance. If you assign a permission to "Authenticated User", then all other roles (except anonymous) will be given this permission immediately.

Example: You have the "Editor" role in the system. You assign the "View user information" permission to the "Authenticated User" role. Everyone with the "Editor" role will also be given the permission because they are also considered to be logged-in users.

Moreover, keep in mind that if you select any permission for the Anonymous role (e.g. "View user information" again), but do not select it for the "Authenticated User", the logged-in users will not be able to access the selected section ("View user information" – they will not have access to user profiles).

Worth remembering

  • In Drupal, you can add an unlimited number of roles.
  • The list of permissions is defined by modules in modulename.permissions.yml files (more on this can be found further in the text). 
  • The "Authenticated" and "Anonymous" roles are separate – if you select something for "Anonymous" only, the logged-in users will not be given this permission.
  • To test permissions, it is good to use the Masquerade module.

Own permissions in the code

Sometimes there is a need to define your own permissions, e.g. to administration pages defined by new modules or to modify access to the pages defined by the Drupal core.

How to define a permission

You just need to add the modulename.permissions.yml file in the new module (or in the existing one, if you already have your own modules created). If you do not know how to create your own modules, I encourage you to visit the website.

The permission file is a file in the YML format. A simple example can be found in the Popup Message module, right here.


Being defined in the file is a unique name for the permission (e.g. "popup message administration"), and then – the names being displayed on the page "/admin/people/permissions/". You can provide a title in the "title" parameter and additionally – a more detailed description in the "description" parameter.

This is enough to define new permissions. After creating the file and clearing the cache, you will see the new permissions on the "/admin/people/permissions/" page.

How to use a permission

Most often, permissions are being used when defining routing. Take a look at the file.

In the "requirements" section, you can add the "permission" parameter. In this way, you can define the users (or rather roles) with what permission can display the page defined in routing.

The second method is to check out the permissions in your code. User object in Drupal has the "hasPermission" method. In this way, you can check out whether a given user has the selected permission.

// Get the current user
$user = \Drupal::currentUser();
// Check for permission
if ($user->hasPermission('display popup message')) {
// Do something.

It is worth to take a look at the hasPermission method here. As you can see, the user ID is being checked there. If the id equals 1, the user gets access without further checking if they have selected roles.

How to check whether the user has a role

Drupal also offers a ready-made method to check whether a given user has a role with a specific name. Provided below is an example of how you can do it in the code.

// Get the current user
$user = \Drupal::currentUser();
// Load user entity.
$user_entity = \Drupal\user\Entity\User::load($user->id());
// Check for permission
if ($user_entity->hasRole('editor')) {
// Do something.

Additionally, there are also methods related to the Authenticated and Anonymous roles:

  • $user-> isAuthenticated();
  • $user-> isAnonymous();

How to check permissions for operations on an entity

In the application code, you can also check the permissions to operate on selected entities (e.g. Node or User). You can perform certain operations, e.g. depending on whether the user has the right to edit a given entity or to display an entity.

Entities in Drupal have the method access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE). A simple example of use is provided below:

$nid = 545;
$node = \Drupal\node\Entity\Node::load($nid);
$user = \Drupal::currentUser();
if ($node->access('edit', $user)) {
// Do something

Defining content permissions

Drupal allows you to manage access to display and edit at the level of a single entry (node). This topic was thoroughly described in our other blog post. Grzegorz Pietrzak described it in the article Drupal Node grants.

Ready-made modules for Drupal related to permissions

There are already many ready-made modules extending the capabilities of the Drupal core. You should check them out before you start writing your own permission-related modules.

Below is a list of a few selected modules that are worth checking out and testing:

Also, check the page and take a look at other modules. Maybe some of them you will find useful.


Drupal is a very flexible system. Just looking at the possibilities regarding permissions, you can see the multitude of configuration possibilities. If you are building a large website with many editor levels or an internal application (e.g. an intranet system) where the users must have limited permissions, Drupal will do the job very well.

If you need support from Drupal specialists on permissions or other issues, use the services of our Drupal developers.

Nov 13 2020
Nov 13

Theme creation in Drupal is not as easy as it may seem. Therefore, there is space here to make your work easier. Often, however, we take shortcuts for this purpose, but these do not always bring the desired results or contradict Drupal's philosophy and generally accepted best practices.

Probably many of you know that as in any other CMS or framework we work on, in Drupal, we can achieve the same goals by choosing different paths to reach them. In the course of my experience, I have faced common mistakes made by Drupal beginners repeatedly, and I have managed to track many codes created by novice and experienced Drupal developers. I have seen how much different the approaches they use. As part of this article, I would like to introduce 7 tricks I have selected (or just shortcuts) that make it easier to work on creating a theme, which many programmers I have never heard of.

Due to the fact that with each release of the Drupal subversion there are various significant changes, I would like to emphasize the examples discussed here that are compatible with the core 8.9.x version. All presented tricks, although they may be sometimes controversial in use, they are fully consistent with the art and can be used for projects.

1. Use of the #context key in the rendering array

One of the common problems when creating templates is the ability to pass data between them. This usually requires programmers to perform complex operations, e.g. when processing templates. The challenge becomes even more difficult when some hooks have already been cached and data upload was still needed. There may be many ideas for solving the problem, but with the Drupal 8.8 version, the problem is solved by the #context key.

Suppose we have implemented hook_preprocess_node, in which we add some additional element using a dedicated template, but we would like to still have access to the node object in it. This is where the #context key comes in handy.

function my_module_preprocess_node(array &$variables) {
  $node = $variables['node'];

  $variables['my_custom_element'] = [
    '#theme' => 'my_custom_theme',
    '#title' => t('My custom theme title'),
    '#context' => [
      'entity' => $node,

This makes it possible to pass any data from one rendering table to another. You can fit anything in it, e.g. an instance of an object that we will need in further processing:

function my_module_preprocess_my_custom_theme(array &$variables) {
  $node = $variables['#context']['entity'];
  // Do whatever you needed with the node entity in your custom theme...

It's worth mentioning that this variable is also available in hook_theme_suggestion_alter, which can further facilitate making suggestions for additional context-dependent template names.

2. Cache support in twig templates

More and more demanding graphic designs of websites, as well as page optimization (in terms of the amount of HTML code returned), forces us to use some shortcut solutions, e.g. extracting the field value directly in the entity template (node type).

Solutions such as

{{ content.field_my_reference_field.0 }}

displaying only single field instead of the content variable can have disastrous consequences in the form of cache problems. In the rendering arrays, apart from the final HTML code, there are also keys responsible for storing such cache metadata: tag, context and max-age. If you want to be sure that the metadata will be collected correctly by the renderer service, just add one magic line in the template:

{% set rendered = content|render %}

In the example of a node template, it will be the content variable, but it can be any "main" variable of your template. Passing such a main rendering array through the render filters allows you to correctly collect all cache metadata, without having to display the entire content variable. At the same time, the solution does not have any negative impact on the performance of code execution, as long as we use cache mechanisms.

3. Theme suggestion without using hook_theme_suggestion_

Yes, it sounds like something completely crazy. However, this solution is available "out of the box". It is enough to add the suggestion to the values hidden in #theme or theme_hook_original in any rendering array (e.g. in hook_preprocess_HOOK) keeping the template naming convention.

As a result, the variable value set in this way

function my_module_preprocess_paragraph(array &$variables) {
  $paragraph = $variables['paragraph'];

  if ($paragraph->bundle() === 'my_awesome_bundle') {
    $variables['theme_hook_original'] = 'paragraph__my_custom_theme_suggestion';

records a suggestion for a given base template (paragraph), allowing you to create a template file named: paragraph-my-custom-theme-suggestion.html.twig Nevertheless, I would limit this solution to exceptional cases. For general use, I would recommend a hook dedicated for this purpose.

4. Safe filter replacement | raw

This filter is generally considered to be potentially dangerous (increases the possibility of successful XSS attacks) and is used in single cases. But it should be avoided as much as possible. I suggest looking for a better way, especially since one of them is extremely easy to use, as you will see in an example.

Let's assume that we have a field that is to finally display the image, but for some reason we would like to omit all the HTML code generated along the way.

The easiest way to do this is:

{{ content.field_my_image_field|render|striptags('')|trim }}

Experienced Drupal developers know that such a solution, instead of displaying an image on the page, will display the whole as plain text encoded into HTML entities. Yes, you can add a raw filter, but you can do it differently using Drupal's Render API with the #markup key:

{{ {'#markup': content.field_my_image_field|render|striptags('')|trim} }}

The method is perhaps a bit less readable than with the filter, but it is safe. HTML code will still be filtered here and only allowed safe tags will be passed through.

5. Referencing a template file from a different theme/module

If you haven't used Twig mechanisms such as include, embed or extend in your template files, I suggest to take the DRY rule into account in every aspect of programming (or web development in general). Themes are the places that suffer most from duplicate code, both in template files and in style sheets.

Many times I have encountered the entire template file was copied, e.g. from an inherited theme or a module, only to add some surrounding HTML code or modify a single template block. The same effect can be achieved by referring to a parent file using the aliases @module_name @theme_name. Suppose we have a template file (card) in our sample module named custom_card

  {% block card_header %}
  {% endblock %}
  {% block card_content %}

{{ content }}

{% endblock %} {% block card__footer %} {% endblock %}

And now in our theme, we would need to add some additional elements in the header block, e.g. an icon. The most common thing is to copy the entire template code, but this can be done more simply and without repeating the code:

{% extends '@custom_card/card.html.twig' %}

{% block header %}
{% endblock %}

6. View reloading using InvokeCommand

As you know, the Views module allows to create views that use AJAX technology. This is done to dynamically switch between the different pages of the view, but also to display the results of the response to value changes from the provided form. But what to do when the content of the view needs to be refreshed due to performing some action outside it, e.g. after sending a request to the controller from another block? Or to submit a form on the same page? Well, there are two very convenient functionalities available in the Drupal core.

The first one is the default RefreshView event registered on the view, which causes the view to be refreshed using AJAX (I recommend that you enter it in the browser console on your example view and observe the effect).

The second mechanism is InvokeCommand, which allows in the AJAX response to return the jQuery method call, along with the given parameters on the DOM element. Combined, this gives you this example code:

class MyCustomController extends ControllerBase {

   * Perform the update and refresh the view.
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   Ajax response.
  public function doUpdateAndRefresh(): AjaxResponse {
    // Perform some sort of logic needed for your controller.

    // Refresh the view.
    $response = new AjaxResponse();
    $response->addCommand(new InvokeCommand('#my-view-block', 'trigger', ['RefreshView']));

    return $response;


In my example, there were forms for user approval inside the generated view. In response to the entry of such a form, I needed to display an updated list. As you can see, basically one extra line did all the magic without any extra effort.

7. Use of Drupal.debounce

For the very end I want to describe something which is not so much a trick as good practice. The Underscore.js library is bundled with Drupal core, but many developers do not use it at all. It includes a number of functionalities. One of the most common cases where the capabilities of this library are not used is the so-called deboucing, i.e. preventing multiple code execution in response to a given event - most often it is a change in the width of the browser window.

I have come across code many times that resembled:

function onResize(callback) {
  var timer;
  return function (event) {
    if (timer) {
    timer = setTimeout(callback,100, event);

$(window).resize(onResize(function(e) {
  // Resize implementation goes here.

Of course, this is an exemplary and the simplest implementation, and such code will execute correctly. The question is: why reinvent the wheel? Answer: to improve Drupal compatibility in the core of Drupal, and also to increase the convenience of work for developers - there is a debouncer port from the underscore library.

Just add a dependency to your library

- core/drupal.debounce

and add the following implementation in the JS code:

$(window).resize(Drupal.debounce(function () {
  // Resize implementation goes here.
}, 100));

Isn't it easier? And most importantly, we use something that has already been well written once.


Although I have come across a lot of interesting approaches to working with themes in our Drupal agency, it must be emphasized that many things come with experience. Especially novice developers should follow Drupal's philosophy from the very beginning. They should understand why they are doing something in a certain way. This allows us to see Drupal's capabilities more easily and learn to use them to increase the comfort and efficiency of work, without losing the cleanliness of the code.

Oct 28 2020
Oct 28

A Drupal multisite is an installation which allows us to use one codebase to serve multiple websites. In this post, I will explain in detail how Drupal multisite works, what approaches can be taken to set up a multisite installation. I will also explain some of the settings that may be important for a multisite which are not applicable when we build just one website on Drupal.

The basics of a default Drupal multisite

A Drupal website comprises a few major things:

  1. Drupal core
  2. Contrib and custom modules
  3. Theme
  4. Database
  5. Configuration

When a request from the browser is handled by Drupal, one of the first things Drupal does is bootstrapping the database and loading configuration. From the database and configuration the system knows:

  • which from the available modules and themes are enabled,
  • how everything is set up:
    • where are public and private files folders,
    • which blocks are where,
    • what content is available,
    • what is on the front page,
    • which menus are in which regions, what links are in which menus, 
    • pretty much everything else about how the website is configured. 

To connect to the database, Drupal reads the connection information which is held in the settings.php file (which typically sits in /sites/default folder).

Notice the default folder. It is called default because it is a fallback folder when no other folders are found. In a single Drupal install, typically no other folders are set up and most websites are run from the default folder.

In a multisite installation, however, we set up separate folders for separate websites.

For example:

  • /sites/example-one.com
  • /sites/example-two.com

If we create such folders, a new request will examine the base domain (base URL as Drupal calls it) and will try to match it to the correct folder. The order is as follows:

When a request with a base URL of www.example-one.com comes in, Drupal checks if there is:

  1. A folder named /sites/www.example-one.com and looks for settings.php there.
  2. If there is not, Drupal will check a higher-order domain folder - /sites/example-one.com in this case. 
  3. If it does not find settings.php there, it will move to the /sites/default.

We achieved a multisite - many websites on one codebase

If we have 2 folders for 2 different domains, we can have 2 separate settings.php files which connect Drupal to two separate databases, which load separate configurations and use various enabled modules and themes.

In essence, we end up with 2 different websites, which have their own databases, content, files and configurations, even though they sit on one Drupal code.

If we add additional folders, we get additional websites without the need to duplicate code.

Drupal can run hundreds of websites from one installation like this.

Sites.php file helps to map domains for folders

To help with the mappings of base URLs to folders, Drupal offers a sites.php file which can be used to assign base URLs to correct folders.

In the /sites/ folder we are offered a file which is called example.sites.php. Change its name to sites.php and Drupal will use it. The configuration of mappings is quite simple:

$sites['an-old-domain-to-map.coom'] = 'example-one.com;

This file allows us to map several domains to one website if we need to and helps a lot with development because development environments typically have different URLs than production ones.

$sites['localhost.example'] = 'example.com';

Some dev teams use this feature also to keep the sites folder clearer when there are hundreds of websites with various domains sometimes in foreign languages. The dev team can have short clear folder names.

'] = 'brand-x-fr;

This is also sometimes useful if the domain for one of the websites changes.

Which website can use which modules

Typically, we are used to a situation where

  • all modules are placed in the modules directory (or sites/all/modules in Drupal 7 and previous versions),
  • all themes are placed in the themes directory (or sites/all/themes in Drupal 7 and previous versions).

If we have one website on the system, there is no need for any other configuration. We add only the modules we need.

In a multisite installation, however, there might be a need to specify which websites can use which modules or themes. In a large system with hundreds of websites and administrators, such restrictions might be crucial to only allow such functionalities on each website which work well together.

We can control this in 2 ways:

1. Via installation profiles

Each website on Drupal is built on an installation profile. Typically this is the standard or minimal profile which is shipped by Drupal out of the box. You chose between these when you install Drupal and you can see them in the /core/profiles folder. None of these 2 profiles has any modules or themes but a profile can provide these.

Drupal for example ships with a demo_umami profile which is a demo profile and includes both: a demo_umami_content module and an umami theme. If you install a standard installation, you will not have access to the umami theme from the admin panel for example.

If you have to control which websites have access to which themes or modules you place these in your custom installation profiles. Only the websites installed on a particular installation profile will be able to access and use what it provides.

What is cool is that profiles allow for inheritance. You can, for example, create one profile with drupal commerce modules and then 2 additional child profiles which will then be able to access the Drupal commerce modules.

While performing Drupal services for our clients we have implemented various scenarios with different levels of granularity. You could even create a child profile for each website to be able to have very granular control. This might however be a bit of an overkill.

2. Per website modules via the website folder

Modules and themes can be also added to the website folder. In our example, we could put them into:

  • sites/example-one.com/modules
  • sites/example-one.com/themes

Modules and themes placed in these directories will only be available to website example-one.com.

As a rule of thumb, you should probably avoid having too many modules here since it probably goes against the concept of a multisite to have completely different code for each website, but sometimes there is a need to add a few per-website tweaks or create for each a subtheme for a website which overrides a few things in a shared base theme.

Updating code once, running update 100 times

One of the great things about a multisite is reduced maintenance. If you have 100 websites on one system and a new version of Drupal comes out, you only have to update the code once instead of 100 times.

That said, remember that settings and databases are separate for all 100 websites. You do have to run the update.php script for each one separately!


Above I explained in detail how Drupal multisite works under the hood. In essence, it is a very simple and yet a powerful feature of Drupal which allows companies to reduce maintenance and technical debt and keep maintainers sane if they have to maintain many websites.

Oct 23 2020
Oct 23

Nowadays we have social media everywhere, so having the ability to share content on your website is essential.

By default Drupal doesn’t provide social media sharing buttons out of the box. However, when delivering Drupal services, we use modules that can help with this. The most popular solution is the AddToAny module.

AddToAny module provides a huge number of share buttons including the universal (‘+’), Facebook, Twitter, Pinterest, Reddit and many more.

And popular AddToAny features list is also impressive:

  • Floating share bars for mobile, desktop, and various site layouts; 
  • Image share buttons to share your images; 
  • Share counts and share count recovery;
  • Google Analytics integration; 
  • Vector sharing icons made for mobile, Retina and high-PPI displays; 
  • Universal sharing button and smart menu; 
  • Visitor personalization; 
  • International support (i18n/localization); 
  • Accessibility and graceful degradation; 
  • Cross-browser and backward compatibility; 
  • Optimized performance and efficient loading via world-class CDNs; 
  • Complete control for publishers & developers of all sizes


The first version of the module was released on 15 April 2008, the latest update - 15 may 2020.

The module can be installed on:

  • Drupal 7 (7.x-4.16 stable release version); 
  • Drupal 8 (8.x-1.14 stable release version);
  • Since 8.x-1.13+ it supports Drupal 9 as well.

All stable releases for this project are covered by the security advisory policy.

Module popularity

According to the statistical data from the module's page, it is currently used by about 47.000 websites.

Module creators

The module is created and maintained by the only person - micropat (see his profile).

What is the module used for?

It is a highly customizable module, allowing to share content probably to any social media. It has a very friendly and excellent documentation with many examples.


To install AddToAny go to the webpage or do it via composer:

composer require drupal/addtoany

Configure placement

By default, share buttons are disabled and placed in Manage display section of each content type, e.g. Structure > Content types > Blog post > Manage display. Be sure it is enabled before we continue.

add2any placement

Configure AddToAny

To configure AddToAny options, go to Administration > Configuration > Web services > AddToAny.

addtoany config

Let's go through each section briefly.

Buttons section

buttons config

AddToAny uses SVG sharing icons that can be scaled to any size, the default value is 32x32 pixels. You can customize the share buttons by editing the "Service Buttons HTML Code" box. More details can be found in the official documentation, where you will find the additional feature examples, such as:

  • Share event handling & modifying; 
  • Templates & endpoint parameters; 
  • Link tracking & URL shorteners; 
  • Custom color buttons; 
  • Image share buttons; 
  • Share counters; 
  • Share count recovery; 
  • etc. 

Here are a few examples.

Like buttons:

like buttons

Share counts buttons:

counters buttons

Under the universal button section you can also customize the + button or even remove it:

no plus button

Additional Options section

Here you can add some custom JS or CSS code for AddToAny with no need to do it programmatically.

additional options section

As an option, you can for example set a custom color to perfectly match any design's color scheme. Just add the following JS code to your "Additional JavaScript" box on the Configuration page.

 a2a_config.icon_color = "#0166ff"; 

 buttons js adjusment

Entities section

In this section you can toggle the content entities where AddToAny will be available to interact with.

entities config section

Once the AddToAny Share Buttons module is installed and enabled, a few sharing buttons will appear on your page. Let’s check out how they look.

page with buttons

By default we have a “+” icon (called the “Universal Button”), next Facebook share is there, as well as Twitter, and email. Clicking the “Universal Button” you will see all available share buttons for other services.

expanded services

And here is an example of Twitter sharing popup. When a visitor clicks one of the buttons, a pre-populated post pops up.

twitter popup

Let’s dive into the documentation and see if we can adjust the template.

Voila, you can change the default message, by adding the following JavaScript code:

var a2a_config = a2a_config || {};
a2a_config.templates = a2a_config.templates || {};
a2a_config.templates.twitter = {
    text: "Reading: ${title} ${link} by me",
    hashtags: "sharing,social"

Hook & Templates

If you think that standard settings is not enough, you can try extending the addtoany-standard.html.twig template.

The default theme implementation to standard AddToAny buttons includes the following variables:

  • addtoany_html: HTML for AddToAny buttons;
  • button_image: URL for universal button;
  • button_setting: Setting of button;
  • button_size: Size of buttons;
  • universal_button_placement: Value of 'before' or 'after' to place button;
  • link_url: Value of URL to share;
  • link_title: Value of page title to share.

There is also one hook, allowing you to programmatically alter the entity types that the AddToAny pseudo-field is available for:

 * @param array $types
 *   The entity types.
function hook_addtoany_entity_types_alter(&$types) {
  // Add the "taxonomy_term" entity type.
  $types[] = 'taxonomy_term';

Alternative solutions

There are a few other options that you might want to investigate. Here is the list:

Has less settings options and services. According to the description this module delivers the most clean solution without making a lot of external calls, having tracker scripts, or even connecting to ad servers.


Now you have all the necessary information on how to add social links to your Drupal site on the example of the AddToAny module. However, if you want to know more about how to most effectively use this module for your website, please contact our Drupal consultants. Once you have installed this module, you will get a very customizable platform with many fine features, which makes your content easy to share.

Oct 02 2020
Oct 02

The Views Bulk Operations module is used when performing bulk operations on results to tables or other items created with Views. In this example, I will show you how to add your own action that will change the state (Workflows) of selected entries.


The action is performed on all selected entries and automatically performed in Batch queues so as not to overload the system and not to "crash" the page when the process takes too long. If you know what you are doing and you have reasons for it, you can turn off the queuing option in the field configuration.

VBO installation and configuration

The Views Bulk Operations module can be installed by downloading and unpacking the package in the modules/contrib directory or by using the composer command, which will download the latest stable version of the module.

composer require drupal/views_bulk_operations

After installation, the module does not need to be configured in any way, you just add the appropriate field to the page (or block) created by the Views module.

  • Add a new Content view that creates the page.
  • Set the display format to Table. It is not necessary, the checkboxes on the table simply look more natural
  • Add the title field
  • Add the Views bulk operations field


Action configuration for a VBO field

In the field configuration, you can mark which mass actions can be performed on the results. There are over a dozen predefined actions, such as:

  • deleting entries
  • publishing
  • sticking


The above list is compatible when the view displays Content. If you add the view that displays Users, you will notice that the list has different actions.

Adding own action to VBO

The goal is to add your own actions on entries (Content) that will change the state (Workflows) of the selected entries.

Entry states are not available immediately after Drupal installation. In order to do this, you need to enable two additional modules that are directly in Drupal, you do not need to additionally download anything.

Go to the page with modules - admin/modules

Enable the modules: Workflows and Content moderation


Workflows configuration

For the purposes of this post, I will use automatically-defined states for the Editorial type, which is available immediately after enabling the Content moderation module.

All you need to do is enable a given type of state transition for the selected content types.

  • On the page admin/config/workflow/workflows edit the Editorial type
  • Set the Article content type


This operation will add a new field to every add/edit article form.


To the view where the VBO field is, add

  • a field displaying the state of a given entry - Content: Moderation state
  • a filter that will limit the display of entries of the Article type

If added is a filter restricting entries to published only Content: Published (= Yes) then remove it. It will block the display of entries that have a state of e.g. Draftor Archived, which are not being published by definition.

Own action code

Create your own module end enable it. In my case, the module's name is d_workflows

In the module's directory create a directory structuresrc/Plugin/Action

Create in it a new class file for the action to change the state of the entry into Published.

Filename: PublishNodeAction.php

 * Content moderation publish node.
 * @Action(
 *   id = "d_workflows_publish_node_action",
 *   label = @Translation("Publish node (moderation_state)"),
 *   type = "node",
 *   confirm = TRUE
 * )

class PublishNodeAction extends ViewsBulkOperationsActionBase {

Class annotation is important here.

You set in it an id for the action – this can be any unique value. It is worth to include in its name the name of the module and what the given action is doing.

Label is the value that will appear in the VBO field configuration

Type is the type of entity, for which the new action will be available. In this case, it is node, but it can be, for example, user, taxonomy_term, or any other.

This class inherits from ViewsBulkOperationsActionBase

It requires declaring two methods:

  • execute() - what is to be executed for each record
  • access() - who can perform the action

Example of a code for the execute() method

 * {@inheritdoc}
public function execute(ContentEntityInterface $entity = NULL) {
  if (!$state = $entity->get('moderation_state')->getString()) {
    return $this->t(':title  - can\'t change state',
        ':title' => $entity->getTitle(),

  switch ($state) {
    case 'archived':
    case 'draft':
      $entity->set('moderation_state', 'published');

  return $this->t(':title state changed to :state',
      ':title' => $entity->getTitle(),
      ':state' => $entity->get('moderation_state')->getString(),

The first condition checks whether the given entity has the state setting option enabled.

In this case it is only Article. When the action is initiated on entries with no states enabled (empty $entity->get('moderation_state')->getString()) it will be interrupted and an information about it will be displayed.

The condition can be easily extended by e.g. checking the content type for the entity


Further down the code, the current status of the entry is being checked and if the condition is met, the code changes its status into Published.

$entity->set('moderation_state', 'published');

Example of a code for the access() method

   * {@inheritdoc}
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    if ($object instanceof Node) {
      $can_update = $object->access('update', $account, TRUE);
      $can_edit = $object->access('edit', $account, TRUE);

      return $can_edit->andIf($can_update)->isAllowed();

    return FALSE;

In this simple condition, it is being checked whether you are operating on Node type objects and whether the user performing the action has the authorisation to edit and update it. Otherwise, the code will return a FALSE, and the action will not be executed.

The whole PublishNodeAction.php file looks like this:

get('moderation_state')->getString()) {
      return $this->t(':title  - can\'t change state',
          ':title' => $entity->getTitle(),

    switch ($state) {
      case 'archived':
      case 'draft':
        $entity->set('moderation_state', 'published');

    return $this->t(':title state changed to :state',
        ':title' => $entity->getTitle(),
        ':state' => $entity->get('moderation_state')->getString(),

   * {@inheritdoc}
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    if ($object instanceof Node) {
      $can_update = $object->access('update', $account, TRUE);
      $can_edit = $object->access('edit', $account, TRUE);

      return $can_edit->andIf($can_update)->isAllowed();

    return FALSE;

A new action will be available in the VBO field edit



Experienced Drupal developers as well as Drupal consultants ensure that adding new actions to Views Bulk Operations is simple and comes down to creating an additional class with two methods. Based on this simple example, you can build more complex mass actions on entities of various types.

Oct 01 2020
Oct 01

Creating groups of users with access to selected content is one of the frequent requirements set out in specifications for web portals. The Group module allows saving hundreds of programming hours by providing ready-made and easily extensible mechanisms. Check how many useful functions you can find in this module.

Group was created as an alternative to Organic Groups (OG), in which relationship mechanisms are based on fields and content. Created in the group module, on the other hand, were full-fledged entities with their own fields that can be extended and exported. Every group can have its own users or uniquely configured permissions.


The origins of the module date back to the Drupal 7 version, for which the first dev version was released in 2010. The Drupal 8 version of the module was first released in March 2016 and is still being developed today. The latest stable version 1.2. was released on 4 August 2020.

Module's popularity

The Group module is quite popular and is currently used by over 9,000 websites. The vast majority, about 8,200, are projects based on Drupal 8.

Module's creators

The main keeper of the module is Kristiaan Van den Eynde (kristiaanvandeneynde), responsible for almost 900 commits to the module. The module is financially supported by Factorial GmbH and has been supported by other companies and organisations in the past. Of course, the development of the module and its sub-modules is also supported by a large crowd of Drupal developers.

So far, 56 developers have contributed to the development of the module; the full list can be found here: https://www.drupal.org/node/711148/committers

What is the module used for?

The Group module solves a problem that cannot be solved in Drupal with the help of built-in mechanisms. It allows you to divide users into groups within which you can both manage user rights and create content dedicated only to the group members.

It is an extremely complex project from the programming point of view. It has several classes and functions that provide key functionalities like permission support, cache, or integration with Drupal's core modules. There is a gnode sub-module in the module's repository that allows you to create relationships between content and groups. The Group module can also be extended with the functionality of creating subgroups, and this is possible with the use of Subgroup or Subgroup (Graph) modules.

Examples of using it:

  • classroom management at schools, where teachers function as administrators, students are members of a given group, and they all have access to common materials,
  • access to paid content by limiting the accessibility of materials for group members (an example can be found in our article Drupal Commerce - Sell electronic products)
  • portals for organisations/communities with a hierarchical structure (several co-dependent units, but with different members and administrators)
  • organisation and management of conferences (registration for lectures, access to materials, discussions). Group is therefore a great tool when you need to create closed user groups with access to specific content.

The Group is therefore a great tool that we use as part of Drupal services to create closed groups of users with access to specific content.


You can download the module at https://www.drupal.org/project/group

After installation, a new group will appear in the Groups (/admin/group) menu between the Configuration and Users tabs in the main system menu.

Group provides a new type of entity, so in the submenu, you will find links to pages such as group types or list. It also has a configuration page, where it is possible to set an administration skin for group-editing, group users pages, etc.

The Group module does not require any specific configuration to be able to use it.

Module's use

In order to create groups, you must first define at least one group type. To do this, go to "/admin/group/types" and create a new group type. This process is similar to creating a new content type or a vocabulary, but also has additional configuration fields related to the permissions of users in given groups.

create groupe type

After creating the group type, you can configure the group fields, as well as the associated form and group display views.


In order to define the rights, you also have the option of going to the Permissions tab, under which you can define basic permissions broken down into:

  • anonymous users,
  • group members,
  • users not being group members 
  • group members with a defined role in the group

Available is also an advanced configuration of the permissions of a user from outside the group with the use of system roles.


It is possible to define roles for a given group type (similarly to the roles defined in the Drupal's core). It is possible to do it in the Roles tab:


One of the most important tabs is Content, where you can install available extensions for a group, and these include content types, group membership or subgroups (after installing the previously mentioned modules).

content 0

After going through all the forms, creating new groups of as given type becomes very simple. You just go to the group list page (/admin/group) and add the groups you need.


As you can see, there are quite a lot of configuration options, especially regarding module permissions. However, they are necessary for its proper operation and it is easy to appreciate their advantages during the use of the module. You can find a very interesting application of the Group module in the Open Social distribution.

Hooks and integrations

The module has the ability to modify links with entity operations embedded in a block on the group's website using the hook_group_operations_alter hook, which in its arguments accepts a table of links and a group object.

Group provides integration with the following modules:

  • Views, offering plug-ins such as: access, argument, default argument, relationship.
  • Tokens - 21 tokens for group and its contents.


The Group module is very mature and programmatically complex. It adds a mechanism for creating groups and their related content that you cannot find in a clean CMS Drupal installation. It was written with due care for the high quality of the code, while at the same time ensuring its easy extension with new functionalities. If this module fits the needs of your project, our Drupal consultants recommend to use it without hesitation.

Aug 28 2020
Aug 28

On July 13, we released another version of the Droopler distribution. In version 2.1, we focused on the functionality needed by many companies nowadays – we have added e-commerce. Check out what exactly the new version of Droopler – one of the most popular Drupal distributions – brings. 

Why e-commerce?

Recent months have forced many companies to switch to online sales. Since March 2020, the number of searches for the phrase "e-commerce" in search engines has increased significantly. More and more companies are looking for ready-made solutions that will enable them to conduct sales via the Internet.


Therefore, at Droptica we have decided to introduce a ready-made e-commerce functionality to the Droopler system. As in previous versions of Droopler, also in the case of e-commerce, our goal was to create a functionality that is nice-looking, easy to manage and ready to use right after installation. 

We provide all this for free and as open source code. 

E-commerce in Droopler

Droopler is a distribution in which we try to use the best Drupal core elements and the best Drupal modules within one system. We combine them into a coherent whole that is convenient to use and add a ready-made template adapted to mobile devices.

That is why in version 2.1 we have used the module Drupal commerce and we have created a ready-made online store on its basis. We have added one example product type and created a product listing. 

Everything looks very nice right away; you do not have to worry about graphic designs or creating CSS styles. This is already done in Droopler 2.1

Check out the demo version

We have also prepared a new demo version showing the e-commerce capabilities of Droopler. Just go to the website https://droopler-commerce.droptica.com and see it for yourself. 


On the home page consisting of paragraphs, you can see selected products. This is one example of how you can promote selected products. 

The list of all products can be found on the website https://droopler-commerce.droptica.com/shop This list is based on the Views and SearchAPI modules. On the left side, you can filter products by category (faceted search). 

Sorting options are available above the product list. The user can change the order of the products being displayed according to their needs. 


When visiting the page of a given product, you see a photo gallery, the product price, the option to add it to the cart, and its description.

The basis is Droopler, so the editor can add any of the 16 existing paragraphs to the product description and make the product page look very eye-catching.

In the header of the page, the user can see the number of items in the cart. From there, they can go to the purchase page and complete the order.

Purchases can be made as a logged-in user and as a guest. 

You can go ahead and test all the purchase steps by clicking around the demo version. 

Adjust the system to your needs

Droopler is based on Drupal, so you can adjust it to your needs. You can also do this with an e-commerce system built on Droopler.

Do you need an online payment system? No problem – there are over 100 free payment modules.

Do you need dedicated shipping options? You can find an appropriate module for this also.

All modules can be found on the website https://www.drupal.org/project/project_module

While working on version 2.1, we have also prepared new additional modules dedicated to Polish companies:

If you have very uncommon requirements, ask us for help. Droptica is a Drupal agency that helps to adapt Drupal (also Drupal Commerce) and Droopler to the individual needs of its clients.

More information on Droopler

By releasing subsequent versions of Droopler, we want to create a convenient tool for business owners and people from marketing departments. With Droopler, we want to help companies in their marketing and sales activities.

From the very beginning, the system is available for free. Information on how to download it can be found on the website droptica.com/droopler/
We have also built a tips section – "Droopler tutorials" – where we describe how to work with Droopler.

If you need help with Droopler, you have found a bug, or you have an idea for new functionality, please notify us here: https://www.drupal.org/project/issues/search/droopler

Aug 27 2020
Aug 27

In one of my last posts, I provided examples of Drupal-based corporate websites. The first one referred to the companies of the medical industry, the second one – to the companies operating within the industrial sector. I presented the Drupal functionalities, as well as the dedicated solutions that the organisations mentioned in this article introduced in their websites. In this text, however, I would like to present Drupal-based websites from the commerce industry.


The company offers co-packing products and accessories. Therefore, it represents an industry in which competition is fierce – the more reasons for an online store to stand out. And so, there are a few attention-grabbing elements that really make this commerce attention-grabbing.

The first thing is the attractive form of displaying banners and photos on the home page. Slide in was used here – by scrolling the page, the mentioned elements "slide" into their places. The effect is eye-catching and makes you want to stay on the store's website. 

The second thing is definitely the search engine. When typing a search term, suggestions appear. This way, you can find the given product faster – you can immediately see if such a product even is in the store at all. And if it is available there, after calling this product you are taken to a page where further filtering options are provided. It is important because, remaining "on the product", you begin to narrow down the search in terms of the features of this product. All this means that you are encouraged step by step to look for the goods you want to find – you do not give up, and we do not leave the website. 


Another thing is the menu. It is located in the upper left corner. After clicking it, a list with categories appears. After selecting the "+" sign, the given category expands – you see the next subcategories, and in the next steps you go to the page with this very product. 

Speaking of the menu, it is worth mentioning the rather frugal form of presenting the headline. In addition to the aforementioned search engine, there is also a shortcut for logging-in into the customer account and a shopping cart. All this makes the whole thing legible and easy to navigate.

When browsing the Drupal-based Hermes store, it is impossible not to get the impression that it was very well-thought-out and designed with the customer in mind. So, if you are considering starting your commerce, this example can be a great inspiration. And in combination with the Drupal consulting, you can gain knowledge and advice on how to make your customer stay in your store as long as possible and choose what they are looking for.


It is one of the most well-known brands that probably does not require a detailed introduction – and also another Drupal-based store. You can find here other amenities for the customer, as well as inspiration.

Have you wondered how to make the search engine more attractive? If you add to the Hermes' example a product image along with the information about the number of variants available in the store, you may obtain a really attractive effect. This is how it looks like at JYSK. You might say it is nothing, but this detail makes all the difference. It undoubtedly meets the customers' expectations and makes searching for a product significantly easier.


Let us go further. If you offer many products and have many categories, why not present these categories as a gallery on the home page? Thanks to the solution proposed by JYSK, the customer who visits the store receives a visual, and at the same time – friendly, message. You can see then that the owner of the store took care to make it easier for the visitor to navigate the brad product offer. 


The above solution is continued. After selecting the category, you are still being guided through photos with subcategories, until you finally choose the given product. Between individual steps you can find, e.g. the section with a blog/guide regarding the category you are currently in. It is good to pay attention to this because on other websites the blog is often placed "beside" and sometimes it is a separate element – here it is an integral part of the purchasing process and supports the customer in choosing the product that meets their expectations.


And when you are finally taken to the cart, there is also a well-thought-out solution that takes into account the decisions that the customer may be considering. "Availability check" and "online reservation" caught my attention. 

By checking the availability of the goods, at the very beginning, you can check out whether the product is in stock and in how many brick and mortar stores.


When selecting the checked button, a pop-up appears, where – after entering the city – you receive information about the quantity of the product in the specific store. It is good to mention here that there is also information available about the latest inventory update – I think it is very important knowledge for the user, on the basis of which the customer can be sure that they are viewing the most up-to-date. A similar pop-up with its functionalities appears when making an online reservation.


When conducting sales online, you should not forget about the sales at brick and mortar shops – but rather support them in order to provide the customer with a broad range of possibilities and present them with options at every step of the shopping experience. And finally – the customer panel. JYSK took care of the basic functions such as: the profile, the order history, the wish list, and the list of recently viewed items. The FAQ section can be checked here. And just like the blog section placed within the purchasing process, the most frequently asked questions and answers are at hand.



Probably almost everyone knows the Wilson brand, but maybe not everyone knows that their online store is built on Drupal.

In this case, I also have to start with the search engine again, because it seems that of all the previous examples, this one looks the best. Moreover, it shows that with Drupal you can develop functionalities that may seem inflexible at first glance.

The main difference is the fact that after entering a phrase, you are taken straight to the store, where the page with the desired product, categories and quantity is displayed. In addition, I must mention that the design is characterised by minimalism, thanks to which the whole is uncluttered.


However, I want to focus on the element that makes this store unique and distinguishes it from others. In the main menu, there is a CUSTOM button, which allows for the possibility to "design" a product according to individual needs and tastes.


After pressing the button, you are taken to the model (in this case – of a tennis racket) and the selection option.



And this is where the adventure begins, one could say. The possibilities of personalising the product are really wide. From the colour, gloss, type of coating, through the choice of the shades of the logotype, to the use of patterns resembling the ones on the rackets of the world's most famous tennis players. Posting here more screenshots made by me would take up too much space, and at the same time – prevent the interaction with the store's capabilities. So, I encourage you to visit it and personalise a tennis racket yourself. However, I will attach here the final view of the product, including the information about the estimated time of order completion.


The above example is perfect if your business offer includes products that are being personalised for your customers. With Drupal, you can achieve a unique effect that will keep up with the expectations, and at the same time provide the user with an unusual experience. So, when you will be preparing a brief for a Drupal agency, and your vision will resemble Wilson's example even a little, I encourage you to include this example. Thanks to this, Drupal team will understand your idea well.

Let us go back for a moment to the home page with the option for finding a dealer. 


The use of a map turns out to be extremely useful here. After selecting the brick and mortar store you are interested in, its detail appears on the side of the screen, which provides additional filtering by category. In the case of Wilson, the search can be narrowed down depending on the sports discipline in the context of which you will be able to purchase appropriate equipment and accessories.


This Drupal-based cosmetics shop may be a good example of a product presentation and designing a customer panel.

As for the former, the gallery plays a key role. Every subpage with a specific type of product is created according to the following pattern: banner, best seller product, other products. Additionally, some of them have information about the stock ending in the warehouse. In addition, there are also references to the content on the blog - so if you have doubts about which product to choose or you want to broaden your knowledge, you do not have to leave the subpage, because everything is here in one place. 




Although there are a lot of photos, you do not get the impression of being overwhelmed with their number. So if you are considering a similar style for your store, use a professional design service.

The second element is the already mentioned customer panel. The clear menu draws attention. Navigating and finding your way around your profile is easy and pleasant, which means that the customer may log in there willingly.


Further down the panel, some blocks allow for previewing the content in reference to the panel menu item.



And finally, the WAM publishing house as an example of a Drupal-based store with a large number of books. The distinguishing feature of the home page is its transparency. My attention is drawn to the thematic blocks with books from a given series. Thanks to using the slider, you do not have to enter the given block, but by pressing the arrow, you can move the titles.


After selecting a book, you go to the product page, where we can learn more about the publication. You also have the option to download an excerpt from the book. 


An interesting fact in the store during the ordering is the option of shipping the purchased product as a gift. The customer can choose not only the recipient of the goods but also a decorative packaging. As a result, the buyer of the product to be a gift does not have to worry about packaging anymore. This is a convenient and useful option.


By choosing a Drupal-based store, you can take advantage of its many possibilities. Depending on what you expect, what you sell, you have a chance to build e-commerce so that your customers stay on your website as long as possible, and the number of conversions is as high as possible. I hope the above examples have inspired you, and you will want to use some of the solutions.

Aug 24 2020
Aug 24

Building an online community is a big challenge for many organisations. In times of remote work, online communication systems are becoming more and more needed. Not only companies are looking for intranet systems, but many NGOs also have changed meetings face-to-face into online meetings. In this post, I will show you how Open Social ® can help you with remote team collaboration.

Open Social ® is an open source Drupal-based system. The official website of the project is https://www.getopensocial.com. At Drupal.org, installation instructions can be found under the address: https://www.drupal.org/project/social. Here you can also see that the project was launched in 2013. This means many years of development, which can be seen in the significant amount of functionalities available in the system. 
The project has recently received funding of EUR 1.25M. The money will be spent on even faster application development. 

Who uses Open Social ®

According to the website https://www.drupal.org/project/usage/social, currently, more than 800 community systems around the world are based on Open Social ®. One of the most interesting implementations is the Greenpeace organisation, a more detailed description can be found on the webpage:


The installation is similar to Drupal. You can find all the information you need here: https://www.drupal.org/docs/installing-drupal.

It is best to download the system files using Composer – the command for this can be found at: https://www.drupal.org/project/social.

In Open Social ®, during installation, you have additional options in the form of functionalities that can be turned on. There are a dozen or so of them, some are checked by default on the configuration form. Everyone can decide for themselves what to install. 


If this is your first Open Social ® installation, I suggest checking all options in order to see the full system capabilities after installation.

If you plan to use Open Social ® in your organisation, I recommend that you first do a trial installation on some test server or locally. I would conduct the proper installation only after a minimum of several days of testing and getting to know the system. 

System header

After the installation, you see a bar with links and icons at the top of the page, while on the left side - the logo, the "Explore" section for browsing content and users, and the icon that opens the search window. 


On the right side, there are icons for adding content, list of my groups, notifications for the currently logged in user, and the link to the profile. 


The header is also adapted to mobile devices. You can easily use the system on your phone.

The entire header looks very nice, and you immediately know what the icons are for. The people working on the UX/UI did an excellent job here. 

Main page

The home page is divided into two columns. The left column with a width of 67% is a stream of the latest information for a given user – the so-called "wall".

There is a form at the top of the left column allowing for adding content. The content may contain text and graphics. You can display the content only for logged-in users or also for non-logged-in users. 


The right column contains a few small sections with the following elements:

  • upcoming events for which the logged-in user is signed up,
  • upcoming events from the whole system,
  • new posts ("Topic" content type, I will describe it later),
  • newest groups,
  • new users. 

These elements in the right column allow for a quick review of new content and new users in the system. 

Home page content (and more)

Every post a user adds on Open Social ® is very similar to the posts added on popular social networks. Therefore, adding and reading this content is very intuitive.

A single post contains the following information:

  • post's author,
  • where the given post has appeared (e.g. in a group, in an event, etc.),
  • date of publication of the post,
  • visibility (who can see the post, e.g. only logged-in users, or members of the selected group),
  • graphics (optional),
  • post's content,
  • number of likes,
  • comment sections,
  • in the upper right corner, the author has options to edit or delete the entry. 


Groups – creating a new group

Creating groups, adding users to them, and creating content within groups is the key function in the system. For example, you can create groups for:

  • people working on a single project,
  • people with the same interests in the organisation,
  • people working in the same office or city.

When creating a group, in the first step, you provide the type. You can choose one of the following types:

  • "Public group". Everyone can see the group. Anyone can join without the moderator's approval. The content added to this group will be visible to logged-in and non-logged-in users.
  • "Open group". Everyone can see the group. Anyone can join without the moderator's approval. The content added to the group will be visible only to the users logged-in to the system (they do not have to be group members in order to read the content).
  • "Closed group". Everyone can see the group in the listings, but it can be joined only after being invited by the moderator. The content in the group is visible only to the group members.
  • "Secret group". The group is not visible in listings (e.g. new groups). The group can be joined only after being invited by the moderator. The content in the group is visible solely to the group members.
  • "Flexible group". Here you can set the group parameters individually. 


As you can see, the list of group types is very long and allows for various options and adapting it to any organisation.

In the second step of creating a group, you provide a name, description, and photo. You can also define the location: country, city and even street. Therefore, you have the ability to assign groups to specific locations. 


I recommend adding a photo because then the groups look nice in the system. 

Groups – browsing and adding content

After creating a group or entering an existing group, you will see a page consisting of three parts:

  • The group's header, where you can see the group's name, photo, group type, number of members, edit link and group menu. The menu contains links to the content (Stream), group information, events, topics, members list and member management page.
  • The left column having the width of 2/3 of the page, containing the content added to the group.
  • The right column contains information about upcoming events, new topics, and new people in the group.



An event is a type of content available on the system that includes a name, description, photo, as well as start and end dates. This works in the same way as Facebook events. 

An event can be assigned to a group and have limited visibility (public - for logged-in users or group members).

As part of the event, you can create content, e.g. inform about the event programme. You can also view the list of people signed up for the event.


"Topic" content type

It is used to create longer posts. In the form for adding this type of content, at the very beginning, you choose one of the three options:

  • blog
  • discussion
  • news


Then you add the header and the main photo. You also have an option to limit the visibility and to assign it to a specific group. 

In the "Description" field, you enter the text that you want to share with the website users. 

You can also add files as attachments to the message. 


"Landing Page" content type

It is a type of content built on the basis of the Paragraphs module. The editor can create a landing page from 7 available ready-made components. It works exactly the same as in the Droopler distribution; it just offers a little less options.

This type of content is great for promoting events or groups outside. For example, the editor can make a landing page with a description of an event or group. Then he can launch a paid campaign on Facebook, LinkedIn, etc. in order to attract users to that page. 

This way of building landing pages is very helpful in marketing activities. 

In the video below, you can see what adding sections within this content type look like.

[embedded content]

User profile 

The user profile is an integral part of any social media platform. The developers of Open Social ® have also created an attractive-looking person profile. 

At the top of the page, you can add the user's photo and a background photo. There is also a space for providing the role within the organisation and the name of the organisation (e.g. Developer at Droptica).
In order to facilitate contact, you can enter the telephone number. 

At the end, you can write something about yourself, your experience, and your interests. 


Private messages 

In addition to sending messages visible to people from the group or all users in the system, it is also possible to send private messages to selected users. 

As in popular social networks, you can send a message to a single user or create a group chat and talk privately with several selected people. 

The module needs to be enabled after a default installation. 

Adjusting the system to one's own needs 

Many functionalities are ready when installing Open Social ®. However, there is nothing to prevent adding new ones. The whole system is based on Drupal and is written in PHP. Open Social ® is made available as an Open Source project. You can freely modify it and adjust it to your needs. 

Five irritating things in Open Social ®

Of course, not everything in the system is perfect. Here are a few things that bother me:

  1. Adding a post reloads the page – it would be helpful for it to be in ajax, as we are used to in social media. 
  2. When adding a comment in a post on the home page that is not at the very top, you are not taken to that comment – you have to scroll down the page again to see it. 
  3. When editing an event, there is no "cancel" button to go back to the previous page without saving the changes. 
  4. Breadcrumb like "Page" content redirects to a subpage/node, and there you will see a blank page with the short text "No front-page content has been created yet."
  5. Another thing I feel is missing is the media module to reuse the same pictures easily. In Droopler 2.x, when this module was added, using the system became more convenient. 

Five cool things in Open Social ®

There are also some functions in the system that I must praise the authors for:

  1. Cutting out the images being added to different types of content makes them look very eye-catching. 
  2. The navigation looks nice – the icons are well-matched. You immediately know what and where to look for.
  3. A single post looks very similar to the one from Facebook or Twitter; anyone will easily navigate the system with such a content presentation. 
  4. The animation opening the search engine looks interesting. 
  5. The Landing Page is a very useful type of data for marketers. It is good that it has been taken into account. 



If you are looking for a system that will provide your organisation with online communication or internal communication within the company, you should seriously consider using Open Social ®. It costs you nothing to check it out, because it is an open source project, and you can install and test it for free. You can also extend it as you wish because it is Drupal

Aug 21 2020
Aug 21

Drupal Commerce is a comprehensive tool for selling physical products over the Internet. In this post, we will show you how to set up a store with little effort, in order to sell electronic products, or more precisely – to sell access to any files. In addition to Commerce, I will use the Group module to achieve the goal.

In the previous post on building a shop in Drupal we showed how to configure the Commerce module to start selling various types of physical products. 

We will take a further step now – I will show you how to configure the system to sell electronic products, such as e-books, music or any other files, using Commerce in Drupal.

This goal can be achieved in several ways, and one of them is the combination of the power of Commerce and the Group module.

Why this method?

  • Not much coding,
  • authorisations handled by the system and the Group module,
  • you sell access to a private group in which the client sees its content,
  • simple way to expand the system for selling, e.g. video courses consisting of many parts,
  • files are being uploaded via the upload field, attached to the content type,
  • product contains a simple reference (field) to the group to which it is to be available after paying.

How does it work for the admin?

  1. You sell access to the group where the files for downloading are available.
  2. You add a private file to the content associated with the group.
  3. You create a product (Commerce) and provide the selected group as a reference.

How does it work for the client?

  1. Product added to the cart.
  2. Creating an account for the client during the purchase process. This must be set in the Commerce configuration. Having an account is necessary to assign the client to the group where files to which they are to receive access after a successful payment are added.
  3. Redirection to payment.
  4. After the payment is completed, access to the group is granted. Adding the client to the group works automatically and is carried out by an additional code that must be added.
  5. The user is redirected to the profile where they have access to files and groups.


install the Commerce and Group modules along with dependencies. 


In addition to the Group module itself, enable the Group Node module (it is part of the Group module) – thanks to it you will be able to determine which type of content will be associated with a given group.

Add the group type – the admin/group/types subpage

At this stage, in the type edition, you can add fields, set its permissions, roles and define the type of content associated with the group.


Add the new group – the admin/group subpage


If only one group type is created, then every group being created will be of that type. If there are more, select which type it should belong to when adding the group. 

On the admin/structure/types page, add the kind of content to be used as the content type in the group. 

Add a private file field to it.

Make sure you have a properly configured private file system in your Drupal. Next, in the field configuration, set the file to be kept as private, thanks to which it will not be visible to non-authorised people.


Create a content type related to the group.

The admin/group/types / manage/GROUPTYPENAME/content page lists the types of content that you can associate with a given group type.

You can do this using the Install button

Thanks to this, it will be possible to create the content intended only for the members of a given group. Thus, each file connected to the content will also be available for viewing only by the people in the group.


Add content with the file to the group

Edit the group and go to the Nodes tab

Here you can add to the group the existing content or create a new one. 
When creating a new entry, add a file to it. Now you can test if in fact, only the members of the group have access to the file. 


Add a new product type that will be used to sell electronic products. A detailed description of how to do this can be found in the previous section concerning the Commerce configuration.

In the product type, add a new field that will be a reference to the created group. 

Field type: Reference -> Other…
Position type: Group

The field can be single- or multi-valued.
In the field settings, check the types of groups to which the reference should apply.


In Commerce, you should have at least one payment method configured.

It is after a successful purchase process, and when the order status becomes "completed", that the membership to the selected group will be granted.


The main functionality that is assigning the client to the selected group with the file is carried out using the PHP code, which you have to write yourself, e.g. in a new module.

The example of such a code that assigns the client to the groups from the reference field is built using EventSubscriber, because your system should monitor and react only when the order is paid.

The solution I used
I have created a new commerce_groups module

A service has been added to the module – the file commerce_groups.services.yml

    class: '\Drupal\commerce_groups\EventSubscriber\AttachUserToGroup'
    arguments: ['@entity_type.manager']
      - { name: 'event_subscriber' }

The service is defined in the AttachUserToGroup class
One argument was added – entity_type.manager, because I needed to inject it as a dependency in the object constructor (Dependency Injection)
The event_subscriber tag informs Drupal that the class wants to log events triggered by other modules. 
The event we want to register is defined in the getSubscribedEvents method in the AttachUserToGroup class, inheriting from EventSubscriberInterface

static function getSubscribedEvents() {
  $events['commerce_order.place.post_transition'] = ['orderCompleteHandler'];

  return $events;

commerce_order.place.post_transition is an event triggered after successful payment for the product.
orderCompleteHandler is a method that contains all the logic of what is to happen when a given event occurs. 
Below is an example of a working code that, after a successful transaction, assigns the client to all groups from the field_group_ref reference field.

     * Add customer to group.
     * @param WorkflowTransitionEvent $event
     * @throws \Drupal\Core\Entity\EntityStorageException
    public function orderCompleteHandler(WorkflowTransitionEvent $event) {
      /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
      $order = $event->getEntity();
      $uid_value = $order->get('uid')->getValue();

      $gids = [];
      foreach ($order->getItems() as $order_item) {
        /** @var \Drupal\commerce_product\Entity\ProductVariation $product_variation */
        $product_variation = $order_item->getPurchasedEntity();
        $product = $product_variation->getProduct();
        $group_value = $product->get('field_group_ref')->getValue();
        foreach ($group_value as $group) {
          $gids[] = $group['target_id'];

      /** @var \Drupal\user\Entity\User $account */
      $account = User::load($uid_value[0]['target_id']);

      foreach ($gids as $gid) {
        /** @var \Drupal\group\Entity\Group $group */
        $group = Group::load($gid);
        if ($group) {

Displaying files in the group.

The quickest method is to create a view that on the main page of the group will display all the added files in the content related to the group.



Commerce and Group are two large, actively supported modules that, when combined, show the true power of Drupal. In an easy way, with a minimal amount of coding, you are able to build a complex and expandable system for selling both physical and electronic products. Both modules will be available in Drupal 9 – the latest version of the system.

Jul 13 2020
Jul 13

Creating components using the Paragraphs module offers incredible flexibility in building pages based on Drupal. One of the common restrictions is the issue of reusing the same paragraphs in very similar components. If the only thing that limits you is the set and layout of fields, the Paragraph View Mode module will help you.

The very first lines of the module's code were created as a dedicated module for one of the projects we implemented. I quickly noticed, however, how such a functionality could be useful in the whole Paragraphs module ecosystem. Currently, the module has a stable 1.4 version and is covered by the Security Advisory Policy.


The first version of the module was released in July 2019. Since then, I have been actively following the list of issues, implementing patches and new functionalities. The last patches were introduced to the developer version in July 2020.

Module's popularity

According to the statistical data published on the module's page: https://www.drupal.org/project/paragraph_view_mode, it is currently used by about 450 websites, which translates into approximately 10 uses per week.

Module's creators

The first draft of the module was created in order to address the needs of a current project. After its initial release on the drupal.org website, I introduced some additional improvements and new functionalities. The community also helped, e.g. with making the module compatible with Drupal 9.
Currently, I am the only person who worked directly on the module's code. The module itself is supervised by two maintainers who respond to all issues as quickly as possible.

What is the module used for? 

Paragraph View Mode is a sub-module for the Paragraphs module. Its advantages will be appreciated by both, developers and people responsible for editing content on a website. It may be necessary when:

  • you are building a website from many components, and some of them are very similar, e.g. they use a similar set of fields;
  • you want to minimise the number of components with regards to the administration;
  • you think about streamlining the frontend part;
  • you want to ensure better organisation of templates with regards to the UI and directly within the code;
  • you want to avoid using many complex field-based modifiers, e.g. lists.

As you can see, this module can offer several useful functions, and all this goes hand in hand with the simplicity of this solution in accordance with the so-called "Drupal Way".


You can download the module from the https://www.drupal.org/project/paragraph_view_mode webpage or via composer:

composer require drupal/paragraph_view_mode

After the installation, go to editing the selected paragraph type, the default path is usually:
In the "Paragraph View Mode" drop-down section, select the option “Enable Paragraph view mode field on this paragraph type" and then save the form.


The module will automatically create a "Paragraph view mode" field with a configuration widget (available in the manage form display tab).
The widget's configuration consists of two fields. The first field is the selection of available display modes. The module automatically receives a list of only those that are unblocked on the current paragraph type, while you can decide which of them you want to display on the list of options in the form.

The second field is used to define the default value of the field in the absence of its value (e.g. for a newly created paragraph).


With the module configured in this way, you can dynamically switch the display modes directly in the page adding/editing form.


Plans for the future

The basic functionality of the module is already completed, and it is hard to come up with new functionalities. Recently, however, I created a new issue https://www.drupal.org/project/paragraph_view_mode/issues/3150153, in which I plan (with a little help from the community) to develop the functionality of linking the field value with the display mode of the form and its dynamic substitution. I also intend to continue supporting Drupal 9 and future versions.


The Paragraph View Mode module, despite its low complexity, offers a lot regarding the efficiency, convenience and – above all – flexibility of the editors' work. In addition, it allows the Drupal developers or the person responsible for the website to reduce the amount of work needed to organise and maintain the components on the website, thus reducing the overall cost of maintaining the website.

Jun 01 2020
Jun 01

I recently wrote an extensive article about a headless CMS. I discussed the pros and cons of building a headless and listed some considerations you should take into account when deciding whether headless is right for you.
Today I want to focus on why you should really consider Drupal if you need a headless CMS.

Headless CMS space is growing

The headless CMSes space is exploding in recent years. This is mostly due to 2 factors:

  1. The emergence of javascript frameworks which allow for the creation of superb user experiences. React, Angular and Vue are great in building these, but they require a backend for content storage.
  2. The publish once, push everywhere idea which is adopted along with the rise of the Omnichannel brand presence and the advent of Digital Experience Platforms. Content now has to be distributed via all the channels in which Drupal is present.

Both these movements are helping the headless CMSes thrive. This happens in 2 ways:

  1. The existing CMSes are adopting to the headless approach. This happened with Drupal API first initiative and inclusion of JSON:API and services modules into Drupal core. Wordpress followed along with making the REST API available.
  2. New entrants to the market, which are focusing only on providing the headless version. These are both - open source and proprietary solutions or mixtures of both worlds.

As a product owner, you have a plethora of options to choose from. It might be difficult to drill down and make the right decision. If I were to recommend the options, I would suggest going with Drupal most of the time. Here is why.

Drupal is mature and is a fully ready headless CMS

If you intend to invest in a headless CMS that will power your websites for the foreseeable future, you have to select a solution that is stable and solid. One which has a clear roadmap of development and will be still relevant and supported in years to come.

Drupal has started the API first initiative years ago and the community was working very hard to get it done. The Services and JSON:API modules are now in Drupal core. They receive the full support of the core project team. You can be sure that they will be available with each drupal release and that they will be working correctly.

Drupal itself is a very mature CMS. Powering over 1 million websites it is backed by a large community of developers. If you chose Drupal you get an enterprise-level solution which will be well supported in the future. 

The contrib space offers a massive amount of modules which extend the base functionality. You can build very custom solutions just by combining already existing code, without having to write too much yourself. This is a huge benefit compared to other, less popular solution on the market.

For more information about drupal benefits, check out the why Drupal page.

The REST API is ingrained into Drupal

In Drupal, the REST API is not an addition plastered on to Drupal as an add-on. The APIs are deeply ingrained into the CMS. Interacting with the API is the same as interacting with the CMS via the browser. This brings magnificent benefits:

  • All the Drupal goodies work out of the box. The fine-grained permissions mechanisms, the workflows, relations, processes etc are executed in just the same way if you request data via API or try to access it via the frontend.
  • All modules which extend Drupal, will work with services (if they are applicable of course). 
  • You can create your own modules and they will work the same way for the headless part of the CMS and for the frontend part.

Thanks to deep integration, the REST APIs are extendable and the way they work can be altered. The best example is the JSON:API extras module and the services module. These both are great examples of how much power the developers have over how they want the APIs to operate. These are of course just examples. Your development team will be able to tailor Drupal to your needs.

JSON:API module is JSON:API compliant

It is worth mentioning that the JSON:API provided by Drupal strictly follows the JSON:API specification. Thanks to this, any developer familiar with the standard can very quickly start working with the API without having to learn a lot of Drupal.

But I want GraphQL

Here you go. The GraphQL module from contrib allows you to expose graphql schemas from Drupal. The module is used by over 1000 websites. It is thoroughly tested by the community. This is another example of how mature Drupal is. Even a solution which is not “the default one” gets a massive amount of usage, testing and support. 

Great tutorials and examples

As with every large community, and especially the Drupal one, a lot of effort is put to educate and help new users onboard. Drupal boasts of a fantastic and very vibrant community, which is always ready to suggest solutions and lend a hand. 

When it comes to the headless approach to building a CMS this is the case in particular. There even is a Drupal distribution built to be an API first, headless CSM. It is called contenta CMS. Contenta is an interesting starting point for building a headless Drupal. It is also a fantastic repository of examples and approaches to real-life requirements. The contenta GitHub account is full of examples in practically any available frontend technology.

Vast vendor support

Last but not least, it is important to be sure that your headless CMS can get the support it needs. Drupal stands out here as well. With a wide selection of drupal agencies which provide drupal support, you will always be able to find expertise to run build and maintain project. If you choose a inch, new solution, the number of vendors will be limited and so might be the expertise. 


If you are about to invest in a headless CMS, you should choose a robust, stable working solution with great support and flexibility. Even though there are many options out there, the majority does not offer the guarantee of stability and predictability, because they are too young. 

Drupal stands out as the robust flexible, API fist solution with a mature community, predictable release cycles, a plethora of contributed modules and a clear vision into the future.

Drupal should at least get to the shortlist of the options you are considering.


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web