Upgrade Your Drupal Skills

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

See Advanced Courses NAH, I know Enough
Dec 02 2020
Dec 02

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

So we wanted to implement the great Bootstrap Toasts feature in our social productivity Drupal distro OpenLucius. HTML framework Bootstrap provides Toasts out of the box. After some trial and error, the end result seems fairly easy to use for everybody. So here is how:

  1. Override status-messages.html.twig in your (custom) theme with the code underneath;
  2. Initiate Toasts in Javascript.

1. Override status-messages.html.twig in your (custom) theme

So place the Twig template override file with this code in your theme. For example in YOURTHEME/templates/misc/status-messages.html.twig. Clear your cache and Drupal should take this file for generating messages, instead of the core one with the same filename. More on Twig template naming conventions here.

2. Initiate Toasts in Javascript

In your (custom) Javascript make sure to initiate the Toasts


3. Et Voilá

The messages will also stack nicely in case of multiple messages, with multiple types (status, warning, error). Ánd have a nicely coloured header depending on message type (green, orange, red).

Additional info from the Bootstrap documentation

Things to know when using the toast plugin:

If you’re building our JavaScript from source, it requires util.js.

  • Toasts are opt-in for performance reasons, so you must initialize them yourself.
  • Please note that you are responsible for positioning toasts.
  • Toasts will automatically hide if you do not specify autohide: false.

On the Toasts documentation page, you'll find the configuration options, for placements, autohide, etc.


For all you 80ies babies, here is the other Toasty! He scared the crap out of me when here appeared out of nowhere somewhere in the 90ies, especially with the high singing lady that accompanied him :)

Wrap up

So there you have it for great toast instead of boring Drupal messages, no offence :) Want to see it in live action? Try OpenLucius and see for yourself! Or you can download and install it yourself via our drupal.org project page. More info on Toasts here on getbootstrap.com.

Nov 24 2020
Nov 24

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last months we had more than 300 people testing the alpha-3 version of OpenLucius: a social productivity platform -build into a Drupal distro. We interviewed them and soon came to the conclusion that the base layouts needed big improvements. It was received as 'mhew..', we agreed. So we went to work and released alpha-4 today. We implemented a complete new base theme from scratch: clean, lean, fast and Bootstrap 4 based. Goal is to leave all the room for custom branding and other design needs.

Below you'll find some screenshots and short explanation of the alpha-4 version, I intentionally kept the screens quite low resolution: it's best to experience the real deal in the live test environment, or go to the project page on drupal.org and install it yourself.

Below you'll find some screenshots and short explanation of the alpha-4 version, I intentionally kept the screens quite low resolution: it's best to experience the real deal / try it for yourself.

So yeah, we revamped everything:

  1. Overall layout and navigation;
  2. Activity streams;
  3. Social posts;
  4. Messages;
  5. Document management (files and folders);
  8. Chatrooms (where are they?).

1. Overall layout and navigation

  • All markup was rebuild from the ground up, based on Bootstrap 4. This way we got rid of all the cluttery html and designs, it's now as Bootstrap-native as humanly possible.
  • The main navigation went from the left sidebar to the top of the page, this also leaves room for extensions / extra menu items and new goodies in the future.
  • The basic color scheme is now minimalistic: black and white with primary and secondary 'action colors'.
  • Also, the platform is much more responsive now: easy of use on mobile devices improved beyond compare.

  1. Main navigation, including a 'Groups' drop-down (with activity badges);
  2. Quick add button;
  3. User area;
  4. Group name / page title;
  5. Sections within groups (including activity badges);
  6. Action buttons.

2. Activity streams

  • This is the default homepage, where you'll find all activity from all your groups in one stream;
  • All activity is now clearly bundled per day, per group. Instead of one big blurred stream of everything together as in previous versions the case was;
  • In the right sidebar you'll find all your groups, including activity badges;
  • (Every group now has a dedicated activity stream);
  • (Every user now has a dedicated activity stream).

3. Social posts

  • Clean new design, with great new image experience;
  • Comments and likes (AJAX based) build into freshly styled components.

4. Messages

  • The new screens for message lists -and message detail pages;
  • With comments and likes;
  • And likes on comments :) ;
  • The message as well as the comments can be enriched with file attachments.

5. Document management (files and folders)

  • The layout for 'Docs & Files' is also completely rebuild;
  • It's now based on DataTables, that brings all goodies like: instant search, sorting and a paging.
  • The table is responsive now;
  • It's still possible to manage folders to organise your files.


  • Inline with other UI improvements, the like area is now also nice and clean.


  • Also inline with other UI improvements, the comment area including attachments is improved.

8. What about the chatrooms / channels per group?

Well, in previous versions this was integrated in the activity streams. That wasn't received very good, so we split them up. In this alpha-4 release the activity stream is fully working and restyled as you can see above.

The realtime chat will be back in a future release within a dedicated section for it. For now it's 1 step back, a next release it will be 2 steps forward for the chatrooms / channels. The activity streams already made that 2 steps forward because of this approach.

Wrap up

Alright, there you have it for a major design update for OpenLucius: a social productivity platform -built into a Drupal distro. You can download and install it yourself open source: check out the project page on Drupal.org. If you'd like to try it this instant, go to the product page and hit the 'try now' button.

Always looking forward to new feedback.

Nov 05 2020
Nov 05

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Nowadays I use Paragraphs in almost every Drupal project: it's very flexible, has a professional ecosystem, and content managers love it. Also, I never ran into a brick wall when it came to new user stories from product owners. To choose a background -and text color per paragraph (or row/section/block/component) is something áll Drupal content managers want. So here is an explanation on how I implement that. This works in Drupal 8 and 9.


  1. Install the Color Field module.
  2. Add the Color Fields to your Paragraph(s).
  3. Configure the 'Form Display' for the Color Field.
  4. Implement dynamic classes via HOOK_preprocess_paragraph() in your .theme file.
  5. Print the variable classes in each paragraph's wrapper html element.
  6. Add styling in your CSS stylesheet.

I assume you already have some paragraphs set up with help of the Paragrahps module.

1. Install the Color Field module

You can find this module here on Drupal.org, it was born in the Drupal 7 era and also has releases for Drupal 8/9. It's stable and has a large install base: ~40.000 Drupal sites at the moment.

The module provides a field in which end-users like Drupal content managers can choose a color in a user-friendly way: just choose from a (predefined) color palette.

Install it with:

composer require 'drupal/color_field:^2.4'

Or a newer version if you're reading this in the future.

2. Add the Color Fields to your Paragraph(s).

Now add two fields to your Paragraph:

  • Background Color
  • Text Color

  1. Choose 'Color'
  2. Provide name, in this case: 'Background Color'.
  3. Also add a field for 'Text Color'

Best practice is to keep the field names somewhat generic so you can easily share it in all other Paragraphs where you want content managers to set background -and text color:

3. Configure the 'Form Display' for the color field

Next up, configure the Form Display for the content managers:

  1. Click on 'Manage Form Display' in your Paragraph Twig template file.
  2. Choose color boxes.
  3. Enter the default colors for pre-selected color boxes as 6 digit upper case hex.

I think this config is useful so content managers can only choose from color defined by for example a style guide and can't use an exotic, 'I like this' color. Avoids 'You are not your user!' stuff.

Above config results in this for content managers:

As you can see, it's now very easy to pick a predefined color and even switch on the fly to test out what works: power to the CM!

4. Implement THEME_preprocess_paragraph() in your .theme file

Drupal content managers can now choose a background -and text color, but how to make sure this also works in the frontend?

First up: preprocess your paragraph in your .theme file:

(.php extension needed for syntax styling, in Drupal this is just 'yourtheme.theme')

Why use dynamic css classes and not inline styles? Because classes is best practice above inline styling first of all. But also to provide more technical control: you want to style p, ul, ol, h2, h3, a, etc in the color as chosen by content manager. But maybe want an exception, like style the links another color/tint. If you use dynamic classes, you can style those within your css stylesheet, in case of inline styling that's not possible.

Explaining the Drupal preprocess code

  1. Implement HOOK_preprocess_paragraph(): this will run for every paragraph uniquely, else this whole thing wouldn't have worked.
  2. Get the input from the Drupal content manager (the picked color in hex).
  3. Populate a Twig variable with a html class.
  4. Helper function to provide correct class based on content manager input (the picked color).

Make sure you always use all capitals for everything you do regarding to the hex color code. At first I couldn't get this to work, took me a while to find that all hex-stuff must be capitals: here in .theme file ánd in 'Form display' paragraph settings.

5. Print the dynamic classes in the paragraph's html wrapper

Here is an example on how to print the dynamic classes in your paragraph:

In best practice this must be done via attributes.addClass(classes), but hey: you can do that :)

And if you make the color field required for content managers, this variable won't ever be empty.

6. Add styling in CSS stylesheet

Now that classes are printed dynamically, based on chosen colors by Drupal content managers -final thing is styling in css file. Here is an example:

And that's it. There is some redundancy regarding the hex colors, but if you have a better idea: please let me know.

Wrap up

So there you have it for making Drupal content manages very happy! At least, that is my experience in all Drupal websites I equipped with this. And it also make me very happy as a Drupal consultant/developer, because I don't have to be subject to the constant new insights of Drupal product owners. They can try endless combinations without me and see what works. Again: power to the Drupal Content Managers, get out of their way!.

Sep 01 2020
Sep 01

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last blog post I shared how to implement rich text in a custom Drupal 9 form, I faced similar issue with files in OpenLucius: couldn't find native, clean and complete working example for multiple files upload. So I figured it out, here is the example code:

Previously I mostly relied on contrib modules for multiple file uploads in Drupal forms, like Plupload. First of all, at the moment that module isn't available in Drupal 9.

Furthermore, such contrib modules are great: they gave me a kick-start. But to get to 100% of requirements was always kinda hard and with upgrades they can be a showstopper, I'd like to stay as lean and native as possible.

So the more native, the better. I was really glad I found the native form api element '#type' => 'managed_file' and its option to upload multiple files '#multiple' => TRUE, which basically provides this Drupal AJAX form element:

End-user functions

When implemented correctly this form element generates an ajax-based form in which end-user can:

  • upload files without page refresh;
  • have a preview of which files will be saved;
  • even delete them before submitting the form.

The Drupal code

For a fully working version, please check the ol_messages module in the Drupal social intranet distro OpenLucius.

So, extracted from OpenLucius, here is the example Drupal code. Also see code explanation underneath.

Explaining most important Drupal code for multiple files upload in custom form

Load Services via Dependency injection

This is an example on how to inject Services via Dependency Injection in a Drupal Form, OpenLucius uses these Services to facilitate everything. In this gist I added the needed code from those services in helper functions.

Build the multiple files upload Drupal form

  1. Set default form values. For the multiple files upload we need $hdd_file_location, which is pretty self explanatory, no? :)
  2. You can also facilitate the edit mode within same form, I stubbed some code for that here.
  3. Facilitate message_id, also needed for edit mode.
  4. Define the name field (title) for the message.
  5. Implement a rich text editor, more details here.
  6. Here is where the multiple-files-upload-magic starts: define a field with '#type' => 'managed_file'
  7. Define the required '#upload_location'
  8. Essential: define '#multiple' => TRUE
  9. Also required to make sure no harmful files can be uploaded, not even in temporary file directory. This is facilitated in a helper function in this gist, as said normally done via a Drupal Service.

Facilitate submitted values in submitForm()

  1. Get name (title) of the message, with an extra XSS security check. More on Drupal security
  2. Get the body value of the rich text editor, check this blog for detailed info.
  3. Security check for body value.
  4. Here is where the multiple files code starts: put the submitted files data in $files variable.
  5. Save the files via a helper function, which most of the times lives in a Service: since multiple modules probably want to save files. And you want it to be testable and overrideable. Want a working example? Check ol_messages module code in OpenLucius distro.

Save uploaded files permanent and attach them to an entity

  1. Drupal will provide an array with file id's via the formSubmit(), we loop through those here.
  2. Set all individual files to Permanent with Drupal core function setPermanent().
    (!) If you don't do this, the uploaded files will stay in temporary file directory and will be deleted on ~next cron run!
  3. Get the file name via Drupal core function getFilename().
  4. Now the file is 'physically' uploaded to the disk, you need to do something with it, else it just sits there like an orphan. In OpenLucius we implemented a custom entity (ol_file) which we use to facilitate files in all kinds of ways in different groups: as an attachment, as a chat item, as a file repository item, as a comment attachment and more.
  5. This bulky code facilitates a nice message for end-user. I put some effort in here so user will get most accurate feedback as possible after uploading a file.

Lastly, some helper functions

As said, these normally live in Services. But to keep this example compact I put them in this gist.

  1. To facilitate edit mode: get current message data.
  2. Build file location. In OpenLucius we have some extra subfolders like group id and user id, to keep file directories a clean as possible.
  3. Allowed file extensions, you could load this from Drupal core settings. But this gives more flexibility: you can change allowed extensions per file upload field.

Wrap up

OK, that's it for now. I hope this will kick-start a multiple files upload implementation in your Drupal project in a native, clean way. So it's flexible, scalable and future-proof!

-- Cheers, Joris

Aug 25 2020
Aug 25

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

I needed to implement a rich text editor in a custom form (for the Drupal intranet distribution OpenLucius). I couldn't find a complete working solution right away, but I figured it out. So, for anybody who needs rich text editing: here is some example code.

See the Drupal form file that contains the code underneath. This it not an installable module, but a mockup file that lives in 'your_module/src/Form'. More info on building custom forms.

The form also uses Dependency Injection for a Form to implement a custom Drupal Service.

Explaining most important Drupal code

Make Rich text editor available for end-user

This is all you need to get the editor to work, assuming you're working in a (standard) Drupal install, that has the 'basic_html' filter defined. A Drupal Minimal install doesn't have this, but of course you can also configure your own Text Format and use that in this custom form.

Handle rich text in submit of custom Drupal form

  1. Get the body via $form_state->getValue('body')['value'];. The ['value'] part took a bit of research.
  2. For security reasons sanitize the data with help of check_markup($body,'basic_html');. Drupal 9's filter.module still provides this function that you can use in this more procedural way.
  3. / 4. I mocked up the 'edit' mode. If you implement that, here is how you can switch between saving a new entity, or updating an existing one.

Wrap up

Ok, that's it for now. It's not that much, but hopefully valuable if you want to implement a rich text editor in your custom Drupal form.

Aug 18 2020
Aug 18

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last month we implemented a user story for our Drupal distro OpenLucius: we needed to send clean html from Drupal 9 modules. This should also be scalable, as in: different modules should be able to mail different content in a consistent template. After some time of coding and trying different modules and options within those modules, we finally got it together in a nice, clean and scalable way.

So I thought more people would like to send nice html mails from Drupal 8/9 programmatically: I extracted the code and produced an isolated example module, even installable.

Copy and run off

I published it here on Github, so you can copy it and run off with it to do whatever you need. At the moment it's not a published Drupal.org project with all kinds of configurable stuff.

Install instructions

Clone this repo and install it like a custom module in Drupal; I haven't set it up with Composer / Packagist. The drupal module has a dependency on Swiftmailer module, which has a dependency on the Mailsystem Drupal module. After you installed it, these three modules should be enabled:

Config instructions

Configure Mailsystem
Head to /admin/config/system/mailsystem and copy this config:

  1. Formatter: choose 'Swiftmailer'
  2. Sender: choose 'Default PHP Mailer', somehow it didn't work when I choose 'Swiftmailer' here. That took a loooong time to figure out.
  3. Choose your active theme (custom or contrib), this is needed so Swiftmailer will detect your clean html Twig override for the emails:

Copy Twig template override

Copy the file 'swiftmailer--lucius-html-mail.html.twig' to your custom theme's '/templates' folder. This is the clean html email template override which Swiftmailer will use later on and you can tune anyway you like.

Swiftmailer config
FYI, all 'Transport settings' in Swiftmailer config can be left to default (see /config/swiftmailer/transport).

Explaining the Drupal code

1. hook_mail() in .module file

First of all, to make use of the Drupal's mailing system: you need to implement hook_mail in the .module file:

  1. Get global site name -and email.
  2. This took a loooooooooooooooooooong time to figure out, but you need to define these headers to make Drupal html mails work.
  3. Additional parameters to fill Twig html email template.

2. Custom Drupal Mail Service 'lucius_html_mail.mail'.

I implemented a custom Drupal Service 'lucius_html_mail.mail', for among other things scalability: this service handles all generic stuff for email sending, while other modules can use this service via Dependency injection and send mails with different parameters: message content in this case.

  1. Define our custom Mail Service and inject 2 external Services.
  2. Constructor to facilitate the 2 external Services.
  3. Build the mailing variables, loop through users, get name and email, finally send mails.

3. Drupal Route and Controller to test and send example emails

I defined a route '/send_test_mail'. If you head over to that url in your browser, the code in sendTestMail() will execute.

If all is ok: all users will receive the example mail.

!) So make sure you're testing this in an environment where mails can't go to the outside world, we use local Docker with Mailhog for example. (!

  1. Drupal's Dependency Injection in action: inject our custom Service 'lucius_html_mail.mail'.
  2. Prepare all paramaters for the mail with static example texts. Then send the mails via our Service method 'sendMail()'.
  3. Simple helper function to get all users.

So, if you head over to '/send_test_mail', all users should receive an email that looks like this:

4. Custom Twig override file 'swiftmailer--lucius-html-mail.html.twig'

As mentioned earlier, swiftmailer--lucius-html-mail.html.twig should be copied somewhere to your custom theme's /templates folder. I found this html code in this open source repo. It's even responsive and uses a lot of inline styles, needed to make it compatible to all major email clients.

As you can see, there are Twig variables, mostly I use the values in the $message array. These variables match the parameters we build earlier. Function Lucius_html_mail_mail() (hook_mail) turned our parameters into one $message array, which can be used in the Twig template as shown in above image.

So tune this template anyway you like, or implement a complete new one with other variables. It's all in your hands now, make it the way you want in a clean, responsive and scalable way!

Handy: Twig template file override suggestions

If you turn on Development mode in Drupal, you can see all template suggestions to go even further down/up the road:

Wrap up

Ok, that's it for now. Hopefully you're now able to implement nice clean emails for your Drupal 8/9 system. If you need more explanation, or you can't get it to work: please let me know.

Aug 04 2020
Aug 04

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

As a Drupal developer / consultant I think it is important to stay up-to-date on module releases, so that I don't code unnecessarily and manage projects as efficient as possible. So here's my batch of this month -all Drupal 9 compatible!

1. Super Login

Enhances Drupal's login features, with things like:

  • Logging in with email address as well as username;
  • More user friendly layouts;
  • Dynamic caps lock warning message displayed when typing login password;
  • .. and ~11 other great features.


2. Simple Like Button

I release this last month, of course this needs to be here (:


3. Site Alert

Put up site-wide messages easily, for example: place an alert, a maintenance downtime message, or general information.


4. Mail Login

If you use Drupal's core login features, users need to login with their username. This light weight module makes sure they can also use an email address, which prevents a lot of support calls.


5. Editor Advanced Image

When you insert an image into content via a Rich text editor, maybe you want to add an extra class, title or id: for styling -or SEO purposes. This module will facilitate that for your Drupal website.


6. Simple Password Reset

When a user requests a new password in your Drupal site:

  1. They'll get a login link emailed;
  2. If clicked, they'll get a screen with a 'login button';
  3. If they click that: they'll be redirected to their user edit page where they can change password.

This module make this process more easy:

  • It skips the login form and brings the user right to profile edit page.
  • It logs the current user out, so they don't get an access denied error, where Drupal defaults to otherwise.

These measures will prevents a lot of confusion and support calls, trust me.


7. Nice login

When you implement a (custom) Drupal theme, the default user login page also needs styling, a lot of the times this is not done because of other priorities. Install this module and you'll be done in no time with styling the Drupal login form.


8. Poll

Create and manage polls right away in your Drupal website. As mentioned on the project page, it's features include:

  • Per-poll options for anonymous voting;
  • Whether voting is required;
  • Open / closed polls;
  • A block to display the latest poll;
  • Views integration;
  • Performance: well integrated with render caching and BigPipe, uses Ajax for voting;
  • Fully multilingual, translate polls and choices.


9. Environment Indicator

Very handy module that clearly shows in what environment your browser currently is, for example: local, test or live. So you're a lot less likely to perform actions in the wrong environment like clearing cache, managing content, change config, etc.

We've all been there, but don't have to be anymore now (:


10. Modal Page

Modals windows are used for different use cases like:

  • Drawing attention to piece of information;
  • Collecting configuration options;
  • Warnings / messages.
  • Blocking the application flow until information required to continue is entered;

Drupal core doesn't have an option to show content in a modal window out of the box, install this module and you'll have.


11. Smart Date

You can use the Drupal core Date field for all kinds of purposes, but it lacks some user-friendliness and functionality. This module enhances the Date field in these areas:

  • Admin UI;
  • All day events;
  • Zero duration events;
  • Formatting;
  • Performance.


12. Search Index Wipe

The Drupal search index can be massive on sites with humongous amounts of content. Sometimes it's too much for the Drupal's default 'search purge' function to handle. That is where this module steps in: it can handle massive search index wipes.


13. Entity Update

I think all Drupal developers have been through this: create a custom entity, implement it and content will follow. Then suddenly you'll need to change or add a field, so change the schema of your custom Drupal entity. To implement this change, you'll have to truncate all content of this entity type, which is kind of nasty if there is already 'production content'. This module can help you solve this problem.


14. Weight

Add a Weight field to your Drupal content type, that you can use for sorting. For example: sort a view manually by the number filled into your Weight field, so not chronologically or alphabetically.


15. Similar By Terms

Makes it easy for Drupal site builder to show for example 'Similar content' in a block, based on taxonomy terms.


16. Easy Breadcrumb

Drupal's default breadcrumb function is kind of meh to implement, this popular module makes your breadcrumb life a lot easier.


17. Login Popup

Drupal's default login and register features are separate pages, which can interrupt user's workflow. This module provides them in a popup / modal window.


18. Mobile Detect

While most responsiveness can be done with css / media queries, sometimes you just want to alter the page based really on a device, like hiding blocks on an a mobile device for example. This module implements the mobiledetect library for you to use in Drupal.


19. View Mode Page

Drupal's core is equipped with View modes, to facilitate different layouts for the same content like:

  • Full pages;
  • Teasers;
  • Rss.

But within Drupal core it's not possible to create pages of the same content type in different view modes (layouts). This module makes that possible: "Create separate pages for different view modes for a given content type." as the Drupal project page clearly states.


20. CKEditor Entity Link

When installed, this module will make it possible for Drupal content managers to insert a link to any entity type: content, files, taxonomy, tags, users, etc.


21. Tooltip Taxonomy

Show tooltips to your Drupal website visitor with help of Drupal's taxonomy. Easy manageable by content managers.


22. Font Awesome Icons

Use the Font Awesome icon library in your Drupal website with this very popular module.


23. Entity Blocks

If you need entities (nodes/content, files, users, etc) to show in a block, this module might come in handy: "Entity block module lets you create blocks that can reference an entity." For example: show a certain piece of content in a block on the homepage (in a selected Drupal View mode)


Wrap up

Alright, that's it for now, hopefully this Drupal module list can kickstart your specific need in a new or ongoing Drupal project. I'll publish another one next month, so stay tuned via my monthly Drupal newsletter!

Jun 25 2019
Jun 25

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

I would like to stay up to date on all available open source / 'contrib' Drupal modules. 'There is a module for that', this applies to many use cases within Drupal; a deadly sin to build something that already exists, or is partially available. We keep track of the latest module releases every month, including what we noticed about module updates in the past month:

1. Clientside Validation

The Form API from Drupal is very comprehensive: neatly building, formatting and developing forms, in the broadest sense of the word, are interwoven into the system. There is no clientside validation as standard, simply put: that as soon as a visitor enters a 'form element' (for example his first name), that field is immediately validated. And not just after clicking on the 'Save' button.


2. Forms Steps

Giving enough attention to forms on your website is essential; these are often a conversion point and you want nothing to stand in the way. A multi-step form can increase your conversion rate by 300%. With this module you can easily create such a form in Drupal.


3. Better Search Block

You can make the standard Drupal search box beautiful by overriding using Twig templates. But if you want a less technical approach, this module could help: it offers some configuration options such as:

  • Making some layout elements adjustable
  • Making the placeholder text adjustable
  • Mini animations as soon as a visitor clicks in the box.


4. Multiple Registration

A powerful permissions and roles system is embedded in the Drupal core, but offers only one registration page for website visitors as standard. If you want different registration pages on your website, for different roles (for example, customers and suppliers), give this module a try.


5. Simple XML sitemap

An XML sitemap is essential for your website SEO. There are several Drupal modules that generate this XML sitemap for you, but this one seems to be the most popular with nearly 45,000 installs. This also supports the latest Google standards, regarding multilingual content.
Googlebots will thank you later.


6. Advanced Text Formatter

Within the Drupal core you can set according to which View mode an entered text field can be shown to the website visitor, for example 'default', 'teaser' or 'trimmed'. If you want more control over the way in which the entered text is displayed, install this module so that you can configure by field:

  • Automatically cut text on a certain number of characters.
  • Adding an ellipsis (...) as soon as a sentence is truncated.
  • Always cancel on whole word.
  • Tokens for adding automatically dynamic information.
  • Allow certain html tags.
  • Apply specific Text Format.


7. Menu Item Extras

Do you want to add extra fields to menu items? Install this popular module. You can see it as 'Fieldable menus', so you can store and display all kinds of extra information with a menu item.


8. Visitors

Don't want to give away all your data to Google? Or do you run Drupal as a social intranet with private data? Then you can install this module to generate statistics. It gives reports about the visitors to your website, in diagrams and other textual statistics. Some of the available reports:

  • Pages that have recently been visited
  • Pages that are often visited
  • Page visitors per month / week / day
  • Total number of visitors
  • Number of unique visitors
  • Number of registered users
  • Visitors by country, city
  • Number of visits per page per city

For the complete list, check the module page:


9. Geofield Map

Easily create beautiful maps using this Drupal module, it is built on the popular Geofield module and works in both the frontend and the backend with interactive maps makes management easy for content managers. The 2.x version even supports custom markers and images, based on dynamic data from that folder. Watch a live demo here.


10. Views Bulk Operations (VBO)


This module has been around for a long time, but recently received another update. Using Views you can configure Drupal content lists in the broadest sense of the word: you can make a list of basically everything that lives in Drupal with it - from simple blog overviews to complex search pages with facets integrated in Solr.

This module expands Views with the possibility of having an action on all items in such a list: a 'bulk operation' as an extension of this limited function of the Drupal core.

An example is bulk editing of a selection of nodes. Exporting data to excel or csv is also possible via this additional module.

11. Monolog

Drupal core has a good log, in which you can find notifications, warnings and errors. But sometimes you need more reporting: this module offers integration of the Monolog library- "Logging for PHP". It integrates with Drupal Watchdog: the core log, so the module works with the Drupal core and contrib / open source modules.


12. Field Defaults

You can configure your content model in Drupal using content types and fields. After / during this configuration you build your website, after which you will fill it with content. Sometimes the content manager discovers after a while that an extra field is needed (for example an 'Intro Text'). You can easily add that field in Drupal, but with all existing content items that field is empty. This module comes in handy: as soon as you create a new field, it can automatically supplement all existing content with a chosen default value for that field.


13. Allow site iframing

For security reasons a website may not load within an i-frame, the Drupal core prohibits that by default. If you want to bypass this intentionally, this mini module offers the solution.


14. Upgrade Status

A module mentioned in the Drupal Keynote by leader Dries Buytaert in the past DrupalCon. Specific for Drupal 8 installations: this module scans all code and reports whether it contains 'deprecated code'. Simply put, that is code that no longer works in Drupal 9. To make it easy to upgrade to Drupal 9 at a later stage, it is important not to have a deprecated code anymore, this module provides a good insight into that. Also: if you use the correct IDE, it will immediately indicate inline with the code.

View this directly in the Driesnote


15. Views Bulk Edit

An addition to the Views Bulk Operations module: provides bulk updating of 'entity values': for example, filled-in text fields in content item, or categorization using Taxonomy


16. Mobile Device Detection

Nowadays the responsive layout of your website is determined in the frontend: the html / css / js determines what it will look like on a certain screen format and also determines whether certain blocks are visible or not.

If you want to catch this on the basis of the website visitor's device, then take a look at this module. Depending on the device, you may or may not have certain Drupal blocks displayed to the website visitor, based on the device.


17. Quick Link

Traced as a result of this blog: this module offers an implementation of the Quicklink library from Google Chrome Lab for Drupal. Quicklink is a lightweight JavaScript library (compressed less than 1 kb) that enables faster consecutive page loads by following in-viewport links.

How Quicklink works
Quicklink makes attempts to speed up navigation to subsequent pages. It:

  • Detects links within the viewport (using Intersection Observer)
  • Wait until the browser is inactive (with requestIdleCallback)
  • Checks whether the user has a slow connection.
  • Prefix of URLs to the links (using
    or XHR).

Under construction
The module has just been released and is currently under heavy construction, but absolutely one to watch.


18. Freelinking

A 'looser' way for content managers to create links. By default you must enter a 'hard' link to a page, but after installing this Drupal module you can also use, for example, the page title, in which case you enter: [[nodetitle: Title of the Page]].

This module automatically turns this into a working link.


19. Hook Event Dispatcher

There are several articles about why you have Drupal events or Drupal hooks They are both in Drupal 8, hooks are from the legacy era (Drupal 7 and earlier) and events originate from the Symfony framework which Drupal 8 is built on. The creator of this module believes that the hook system is outdated, but that is an ongoing discussion.

Anyway, this module ensures that Drupal dispatches some hooks as events, so that those hooks can be implemented as events. Because that way of implementation would be better. Among other things, it is about:

  • Entity hooks
  • Form hooks
  • Preprocess hooks


20. Modules weight

Drupal executes code in modules on order of weights of modules. The module with the highest or lowest weight is executed first. As a result, it is possible that a certain code can overwrite each other because they have the same type of application. It is not possible to set which code has priority, so with the help of setting the module weight.

In the 'early Drupal 7 days' we did this by hand: directly adjust the values of the weights in the database, now there is a module for which you can simply configure this, nice:


Wrap up

That's it, for this month then. Hopefully you are well informed about the latest module releases and you will care a lot because 'there is a module for that'. For another xx cool Drupal modules - stay tuned next month!

Jun 19 2019
Jun 19

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last month we worked in a project where we implemented a progressively decoupled Drupal platform. We needed a React.js frontend to to all kind of magic that was less available in Twig. Also, this way frontend engineers and backend engineers could work more loosely together, which is great.

Main reason we choose progressive decoupled instead of fully decoupled is because we wanted to make use of Drupal's roles, permissions and authentication, plus some other Drupal native stuff that in fully headless would become very cumbersome to deal with.

Check out this blog on 'How to decouple Drupal in 2019' and find out if you also need Drupal beheading or not.

React libraries dynamically in Drupal

The target was to implement the React.js libraries in Drupal pages, so React would load withín Drupal and we could use all native Drupal goodies like authentication.

By the way: you can also use Drupal authentication when fully decoupled, check this article

So, the thing with React is: every time you release a new version of your App, you'll have to render a new build, that sort of looks like this:

More specifically, the .js and .css files we need to load in Drupal are defined in asset-manifest.json:

So, those files need to be loaded in Drupal, and change every time you run a new build in your React App for example with npm run build.

But you can't add these React javascript libraries to your theme's YOURTHEME.libraries.yml because with the next build the links be be different.

hook_library_info_build() to the rescue

Aaaah, so Drupal 8 provides us with hook_library_info_build() that will save our day (づ。◕‿‿◕。)づ

Now, how we did this:

Implement the Drupal hook in your .module file (For highlighting's sake, I added .php, loose that. #nobrainer):

As you see, it will read React's asset-manifest.json and registers all .js and .css files of React.js as a library in Drupal.

Next up, you can render this library for example in a Controller like this:

Wrap up

So that's how we integrated React.js within Drupal pages and combined the power of a React frontend with the power of Drupal goodies, in a 'progressively decoupled' way.

Please let me know if you have any questions.

Mar 18 2019
Mar 18

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

As a digital agency, we develop many platforms and websites for different clients. In the past years, we often encountered the following problem: a developer produces something on his laptop that does not work instantaneously on the laptop of another developer. We had to look for the difference in laptop software and settings. This took time, is frustrating and a complete waste of energy, because this misery can be avoided if all systems are 'containerized' through Docker.

A notorious statement is:

It worked on my machine

This problem is caused by the fact that the laptops / servers differ in, for example:

  • Operating system;
  • PHP version;
  • Database version.

A minimal difference in the settings within an application (eg PHP or MySQL) can also take a long time to discover.

Also a difference in write permissions can take a lot of time to find out.

In addition, each platform or website has its own system requirements anyway: for example, one is ready for PHP 7 and the other requires PHP 5.6.

Docker solves these problems: it ensures that a website always lives in the same persistent environment in terms of operating system, associated applications and settings. Wherever you are running the website: locally or an online server - Mac, Linux or Windows.

Advantage for Drupal product owners (website owner)

  • Faster development and test processes.
  • Higher quality in deliveries due to consistency of underlying architecture.
  • Faster and stable live deployments.
  • Consistent continuous integration, which shortens the time to live of new functions. This applies to both support issues and complete sprints.

Traditional Drupal vs Drupal in Docker containers

Put simply, within Docker the application is linked to the environment, so that it always has the right server stack.

Traditional Drupal
You can see in the above workpiece that within a traditional environment, the Drupal website is separate from the server stack. The server stack therefore differs per environment (laptop or cloud server), giving you the aforementioned problems and frustrations as soon as you want to have it working elsewhere.

Drupal in Docker containers
In the Docker scenario you see that the Drupal website is inextricably linked to the server stack:

  • A bare bone OS (operating system).
  • The required server applications.
  • Libraries and settings.

Drupal bug tracking made easier

For example, the Drupal website always has exactly the same environment and it does not matter where you install it. So independent of laptop or server: it will work the same everywhere. Or, not work anywhere which is also important so you can bug-track in your Drupal website.

Without Drupal in Docker, the latter scenario also happens too often: a bug in the Drupal website can not be reproduced because it dóes work locally.

Plug and play server applications and tools

Where it used to be difficult to install required server applications on your laptop, that is now relatively quickly arranged.

Think about

You download this and it works instantaneously within a container, where your application can connect to.

Continuous Integration (CI) of Drupal applications

Because all environments are always the same, Drupal test trajectories will take less time. Because where you traditionally had to test all environments again - now you know (almost) for sure that once the Drupal application works locally, it works on the test, acceptance and live server.

We are currently further integrating Docker into our CI street. For an interesting article on continuous integration, see here

Why Docker?

There are several variants of virtualization software to solve the 'it worked on my machine' problem.

So why Docker? 5 reasons:

1. Docker is popular

Research shows that Docker is applied on a large scale. Cloud monitor DataDog saw March 2016 13.6 percent of customers running on Docker. A year later that number has grown to 18.8 percent - a growth of almost 40 percent in 12 months time.

RightScale noted in its RightScale 2018 State of the Cloud-report that the implementation of Docker has increased to 49 percent from 35 percent in 2017.

More than 3.5 million applications have been placed in containers with Docker technology and more than 37 billion containerized applications have been downloaded. source

2. Docker is relatively easy and safe

Compared to other virtualization software, Docker is relatively quick to learn for a dev-ops engineer. In addition, the containerization provides an environment that is faster and easier to keep safe.

3. Docker loves everything and everyone

Docker is also built in such a way that it can be used on other popular dev-ops applications like Puppet, Chef, Vagrant, and Ansible. Source.

4. Embrace by the big

Docker cooperates with Google, Microsoft, Amazon, Cisco, HP, IBM, RedHat, VMWare (source), whereby the necessary standardization was also made.

5. Docker versus other Virtual Machines

There are several similar virtualization techniques, but Docker's container architecture makes the difference. Simply put, you can run multiple applications on one VPS - where other virtualization techniques require one VPS per application.

Docker containers are isolated, but share the underlying operating system and -if necessary- applications and libraries.

With Docker you can use your server resources more efficiently: you can run multiple Docker environments on one VPS - this is not possible with other Virtual Machines. For more benchmarking details herein, see also this blog.

Docker says

Docker is the world’s leading software container platform available for developers, ops and businesses to build, ship and run any app on any infrastructure.


No Lock-in: Multi-Linux and Windows. Multi-Cloud.


Increase Security, Enable portability and lower costs in 5 days without changing app code.

Source: Docker.com

There is more

Some additional reasons to use Docker:

  • Local SSL relatively easily, via LetsEncrypt.
  • People can collaborate more quickly and easily on an application, without needing all kinds of dev-ops knowledge.
  • Because your application is instant portable you can switch from hosting provider easier.
  • Large projects can be more easily split up into small teams, using CI tools like Jenkins the code from different teams is integrated.
  • Create sandboxes quickly and destroy them, so that everything stays clean.
  • Docker has a large ecosystem.
  • Complex micro-service becomes possible within a container

Misc Docker stuff

Nice fact: lmctfy

Few people know this, but most of you have been using containers for years. Google has its own open-source container technology (Let Me Contain That For You). Every time you use Google functionality (Search, Gmail, Google Docs), you will be assigned a new container. source

Docker's ecosystem

Some popular parts in Docker's ecosystem:


Docker conferences are held annually, this year it takes place in San Francisco. For more info, see Dockercon.com.

Challenges and points for attention

  • Consolidation of Database data
  • Live environments for customers: some customers would like to host themselves, but do not support Docker yet.
  • On MacOS, some Docker related actions are unnecessarily slow.
  • All developers have to master the technique before your organization can completely adopt.

Wrap up

The it worked on my machine problem is a thing of the past with us, but some systems have to be completed but we are almost there.

This saves everyone, including product owners (our customers) a lot of time and energy. Deliveries go faster and better, what more do you want?

Questions or additions? Let me know!

-- Cheers, Joris


Feb 22 2019
Feb 22

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

It is good to keep abreast of available open source 'contrib' Drupal modules. 'There's a module for that', applies to many use cases within Drupal; it's a sin to build something that already exists. We keep track of the latest module releases every month, this is what we noticed about module updates in the last month:

1. Rabbit Hole

An ingenious module, somewhat superlative, but I was surprised that I never saw it before. This Drupal module solves an issue that has required attention for Drupal implementations for years: you want to use certain content, files or Taxonomy terms combined for building specific other content pages - you do not want to use them as individually accessible pages.

For example: you have a page where a slideshow with 10 images is shown. Those 10 images are 10 manageable Drupal nodes in the backend. If you do not do anything about it, then your slideshow probably works fine, but those 10 nodes are also individually accessible anonymously - and indexable by Google (╯°□°)╯︵ ┻━┻

That is what you want to avoid: your SEO is broken and people can end up on pages that are not part of your website at all - and probably not styled -yikes!

We always solved this in custom code: access to relevant entities give a 404 page not found. But this module made it generically configurable, very nice!

Oh yeah, if you use the XML sitemap module: do not forget to exclude items.


2. Quick Link

Following this blog on the track: this module provides an implementation of the Quicklink library from Google Chrome Lab for Drupal. Quicklink is a lightweight JavaScript library (less than 1 kb compressed) that enables faster consecutive page loads by following in-viewport links.

How Quicklink works
Quicklink attempts to speed up navigation to subsequent pages. It:

  • Detects links within the viewport (using Intersection Observer)
  • Waits until the browser is inactive (with requestIdleCallback)
  • Checks whether the user has a slow connection.
  • Prefetches from URLs to the links (using
    of XHR).

Under construction
The module just recently arrived and is still under heavy construction at present, but absolutely one to watch.


3. Image Effects

A popular evergreen module, which was named in Drupal 7 era ImageCache Actions: contains a bundle of actions that you can apply to an image.


4. Weight

If you want to set the order of content in a list (eg Drupal nodes), you will need a field to facilitate this. Drupal does not offer this by default, but this module helps you: after installation you can give content items (for example Drupal nodes) a weight, making them appear higher or lower in a (non-chronological) list.

Interesting in this context is Comparison of Node Ordering Modules.


5. Automatic User Names

This Drupal module can automatically generate a username from other User fields (eg first name and last name). Because this username is automatically generated, it is no longer necessary to have it filled in manually. That is why this module also deactivates the username field. The Real Name module can be a good addition to this.


6. Role Expire

This is a simple module that allows administrators to manage expiration dates on user roles. A common application of this module is the implementation of subscriptions in the form of a magazine, where someone has access to protected content for a certain period of time.


7. Twig Field Value (Drupal theming)

A popular Drupal module, with which Drupal themers can get partial data from render arrays. So that there is more control over exactly which data ends up on the screen.


8. Entity Browser

Developer module to provide a browser / selector / selector for a Drupal entity. It can be used in any context in which a content manager has to select one or more entities and something has to be done with it (content, image, video, audio, etc)

Possible applications:

  • to produce an entity reference widget;
  • use in a wysiwyg editor.

An example is the File Entity Browser module, a kind of media browser, that uses this Entity Browser module.


9. Paragraphs Previewer

An extension for the popular Drupal Paragraphs module. By default, there is no possibility in the backend to view a preview of an input piece of content in Paragraphs: you first have to save the entire content article (the node), then refresh the frontend and see what it looks like. This module solves this by giving the possibility of a preview in Paragraphs, in the backend.

You will have to make sure that the html/css styling of the Paragraph in question is also fully included there and is not dependent on a global context (eg page, section, div, etc classes).


10. Views Parity Row

In Drupal you can work with View Modes because content from the same content type in different places in a Drupal website can look different, some standard View Modes are:

  • Full Content
  • RSS
  • Search index
  • Teaser

You can add unlimited View Modes yourself. A list of all active View Modes can be found under DRUPAL_SITE_URL/admin/structure/display modes/view.

Now Drupal core also contains the Views module: for making lists in the broadest sense of the word. In such a Drupal View you can specify which View Mode of relevant content you want to show (teaser, full content, rss, etc). But you can only choose one in the View, so you can not alternate them. And you might want that in some cases; that is the issue that this module solves: different View Modes in one View, phew :)


11. Leaflet

Leaflet is an open source JavaScript library for mobile-friendly interactive maps. This module integrates Leaflet into Drupal. An alternative to Google Maps or MapBox for example.


12. Background Images Formatter

This module offers an image formatter that allows you to set an image in the background of a css tag. The images come from a Drupal entity field and not from a configuration page or a custom Drupal entity or anything else, so it's very easy to set up and manage - as the project page describes.

The module also contains a sub-module to process responsive images.


13. OtherView Filter

Within the Drupal core you can easily create lists, for example of content or users, using Views. Sometimes within the many unwise standard options you just fail to build in that one exception: for example one or more specific content items that you do not want to have in the list.

If you install this module, you can have the results of one View excluded in the other. This sounds like a Rube Goldberg machine and perhaps a custom query is better, but that depends on the use case, the budget, system scale, future wishes and your development knowledge.


14. Taxonomy Formatter

Drupal Taxonomy is a powerful, flexible system for categorizing content. The standard formatters merely build a lot of divs around the terms in the frontend. This module adds a new formatter that gives you more influence on these layout options.


15. Copy Prevention

This module applies a number of techniques making it more difficult to copy content from your Drupal website:

  • Switch off selecting text.
  • Disable copying to clipboard.
  • Disable right mouse button for all site content.
  • Disable right mouse button for images only.
  • Protect/hide images for search engines so that your images are not shown in search results.

If you really do not want information copied, then you should not put it on the internet, technically savvy people can always copy content from a public Drupal website, but this module makes it more difficult for non-technical people.


16. Consumers

A developer api module used in Contenta CMS, a Headless Drupal distribution. This module itself does not contain functions for end users, but facilitates an API for other modules to build on.

In this case Consumers can be registered (similar to https://developers.facebook.com), for decoupled Drupal installations to offer variations based on who makes the request. All these options are managed under a joint umbrella so that other modules can use them.


17. Nagios

This module integrates Drupal into the Nagios monitoring system and provides instant central insight into Nagios of:

  • Is the Drupal core up-to-date?
  • Are the Drupal contrib modules up-to-date?
  • Are the Drupal site settings correct?
  • Many other safety aspects in Drupal


18. Autoban

Drupal security module, which analyzes visitor behavior: when suspicious actions are detected, the relevant IP address is added to a blacklist.

There are various settings possible, so you can adjust how strictly the module occurs.


Wrap up

Ok, that's it for this now, next month I expect a new modules updates, so stay tuned!

Sep 16 2018
Sep 16

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

'There's a module for that', this applies to many use cases with Drupal. What is not possible with modules we develop tailor-made instead. But because customization is costly, it is good to keep abreast of the available modules. I try to keep track of this every month; although that does not always work, at least here is what struck me about module updates in the last month:

1. Security Kit

Has been quite some time in development and quite popular, but recently received an update. Always good to mention once again, within this Drupal module a number of measures are taken against common safety issues:

  • Cross site Scripting
  • Cross-site Request Forgery
  • Clickjacking


2. Twig tweak

Provides a number of handy Twig extensions, which makes the life of a Drupal developer / themer easier. See also this cheat sheet for the concrete possibilities.


3. Field Block

For me a blast from the past, we used this module a lot in Drupal 7 installations. It offers a light weight way to position the output of your fields via blocks on a page. Blocks with relevant fields can then be placed lean via the Context module for example.

If you compare this with positioning via for example, Panels, Display Suit or Views it is very lean and mean.

However, a caveat: this approach is meant for developers, if you want to build non-technical content manager pages this is a less suitable method.

It is also possible to position fields with the Layout Builder, nowadays in the Drupal core. See this video.


4. Track da files

The Drupal 8 core has a good file management system, for both public and private files. But there are no statistics / reports in, this module provides for this to include the following features:

  • One list with all files
  • Number of downloads per file
  • IP address statistics
  • Export data to CSV


5. Heading

When you work with Paragraphs, you will understand the usefulness of this Drupal module: you simply need a simple header field which you can position between paragraphs or other sections in your page: plain text and choose h1-h6.


6. File hash

An addition to the standard Drupal file system, with which all uploaded files are uniquely characterized by a hash. With this you can, for example, detect duplicate files and verify copies against original files.

A unique hash per file is stored in MD5, SHA-1 and/or SHA-256 format.


7. Smart IP

This Drupal module collects all kinds of visitor information based on the IP of the user, such as:

  • Place of residence
  • Country
  • Time zone
  • Postal code (approximate)
  • Degrees of latitude and longitude (approximate)

Please note the necessary reports regarding AVG / GDPR.


8. Freelinking

A 'looser' way for content managers to create links. By default you have to enter a 'hard' link to a page, but after installing this Drupal module you can also use the page title, in which case you enter: [[nodetitle:Title of the Page]].

This module automatically creates a working link.


9. Facets

Building a relatively easy "faceted search" in Drupal 8: filtering as you may know from Marktplaats.nl. This module works with the Drupal core search or the commonly used Search API module.


10. Show email

A micro module that can show the e-mail address on a user profile page.


11. Iframe

Generates an extra field, which you can use to load an external website via an iframe. You can set height and width, optionally set a title and attributes for frameborder and scroll styling.


12. Views Bulk Edit

Change bulk values of fields in nodes or other entities. This module uses the popular Views Bulk Operations module.


13. Menu Item Extras

Do you want to add extra fields to menu items? Install this module. You can see it as 'Fieldable menus', allowing you to store and display all kinds of additional information in a menu item.


14. Redirect after login

A mini module, with which you can set which page someone ends up on after logging in.


15. Lockr

When you work with encrypted data (eg user data), Drupal always needs a key to decrypt it, otherwise you can not use that data in the Drupal platform. If this key is on the same server, a hacker would potentially still have all the data at hand. If this key is on a different server, it will be a lot more difficult. This module provides for the latter.


16. Automatic IP ban (Autoban)

Drupal security module which analyzes visitor behavior: when suspicious actions are detected, the relevant IP address is added to a black list.

There are various settings possible, so you can adjust how strict the module operates.


17. Bootstrap menu items

A fan of the Bootstrap HTML framework in your Drupal site? Then this module may be useful: make easy drop-down menu items and separators between menu items.


18. Chosen

Makes the selection of items (eg Drupal taxonomy terms) a lot easier for content managers in your Drupal system.



19. Paragraphs jQuery UI Accordion

Do you use Paragraphs and want to show an accordion? You guessed it: this module can help a long way in the right direction.


Wrap up

Ok, that's it for this month. Expect a new version next month!

May 07 2018
May 07

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

The new platform for SOS Children's Villages was recently launched, after 3 sprints with a lead time of 3 months and a team of 6 people on average, we are proud to announce this new platform. Special thanks to the SOS team and Digital Project Lead Mandy Plugge - for the award and the excellent cooperation. So, without further ado.., powered by Drupal.., a recap of the first phase:

Discovery with value

SOS Children's Villages had already built up a substantial backlog last year: desired functions for the new website. During the kick-off meeting these functions were discussed and prioritized.

After an analysis of these functionalities it turned out Drupal cms was the most suitable cms (content management system).

The kick-off meeting was part of sprint 0 (project discovery phase), this phase had a lead time of one week. Such a week ensures that all information is mapped to start production. In addition to the aforementioned kick-off meeting, the following will be included during this discovery week:

  • Sharing and submitting existing documentation (style guides, personas, wikis, analytics, etc).
  • Consult and analyze technical infrastructure.
  • Consult roles and responsibilities.
  • Inventory and audits of existing content, assets, resources, design patterns, etc.

But also:

  • Project and product limitations: politics, technical, personnel, resources and assets, brand, etc.
  • The competitive landscape of the product / brand.
  • Brand and its characteristics, visual style, values and personalities.

For more info about a valuable project discovery, check this great blog from Lullabot

Valuable discovery

So, during a discovery phase we want to immediately produce value and not get stuck in an analysis paralysis. We delivered concrete results in the form of:

  1. A concept design.
  2. Clickable wireframes, immediately developed in the cms - in this case Drupal.

Lift off: assessment

After the discovery week we had enough information to plan the project globally and start production. The following information was roughly charted:

  1. Goals: why do we do this project? What do we want to achieve?
  2. Sources: where does the traffic come from?
  3. Target groups: what kind of people come to the website?
  4. Desired functionalities

Drupal project kick-off board

A rough summary of the assessment that resulted from the kick-off meeting:

To facilitate the top goals

The new Drupal platform should facilitate the following goals for SOS Children's Villages for content managers:

  • Optimization of donations
  • Conversion optimization
  • A / B testing
  • Customer journey management
  • CRM integration
  • Mobile first
  • Marketing automation management
  • Being scalable: using future techniques relatively easily
  • Optimization of account management: implementation of a My environment for existing donors
  • Optimization of recruitment
  • Lower bounce rates

Top sources

Where does the website traffic mainly come from:

  • Search engines
  • CPC / Ads
  • Newsletters
  • Direct
  • Social media
  • External sites
  • Hard copy

Top target groups

  • Potential donors
  • Businesses
  • Foundations
  • Schools
  • Existing donors
  • Press
  • Participants of challenges and events
  • Volunteers
  • Applicants

Top site functions

1. Flexible content management
In which user-friendly work can be done on, among other things:

  • Donation forms
  • Landing pages
  • Static pages
  • News
  • Homepage

In the first version of the Drupal platform created, there were almost 300 pages with very diverse content and layout facilitated by the Drupal cms.

2. Form builder
SOS Children's Villages wanted to be able to manage flexible donation forms: create unlimited new ones, configure them and place them on all pages - at any position within that page. Given the desired flexibility, the complex data flows and external integrations, it was decided to develop this in a custom Drupal module.

The following functions were included in this form builder within Drupal:

  • Conditional fields
  • Inline real-time validation
  • Postcode API integration
  • IBAN check
  • Adyen integration
  • SOAP CRM integration (XML WSDL)
  • Personalized thank you pages -and thank you e-mail.

3. Content management workflow
Content management roles were desired so that SOS Children's Villages can determine who does what. This also determines the workflow: how does a page go from draft to published. The Drupal platform also facilitates workflows for modification of existing pages, requiring the review of an editor.

4. Testing
Not a function, but constantly a crucial part for a successful, scalable and fast website. The following test components are included in the overall plan:

  • Peer reviews
  • Functional testing
  • Load testing
  • Pen testing: we tested the platform's hack potential
  • Unit / Behat testing

5. Other desired 1st phase top functions

  • Internal search engine
  • E-commerce tracking using Google Analytics / data layer
  • News & blog
  • Vacancies
  • Press releases
  • Events
  • Project map

An explanation of the above 5 parts:

1. Flexible, consistent content management

A great deal of flexibility for the layout of pages was desired, for this it was not possible to define standard content types and templates - that would limit the content team of SOS Children's Villages too much. That is why we used the Paragraphs technique.

Currently ~ 300 pages are all created within this technique, which suits SOS Children's Villages because they are relatively free in layout, but can not be created outside the house style.

It's good for Lucius too because we do not have to help with creating pages and do not have to (re)write content types. Also code-wise, it is easier because all content goes through the same code and configuration.


Through this Paragraphs technique, content managers can add rows and add unlimited columns per row. An example of the added rows on the homepage:

Drupal rows and paragraphs

This homepage consists of 6 rows; the content managers of SOS Children's Villages can add, delete and organize rows themselves. Content managers can also set the following per row in the Drupal backend:

Drupal paragraphs content management per row

  1. Does the row have to be displayed in full width? When this option is checked, this row will occupy the entire width of the screen, such as the header image of the frontpage in row 1.
  2. SOS Children's Villages can set the color of the row themselves. To monitor house style, these are limited to a few options.
  3. Content managers can set the margins per row.

Columns in rows

Each row can have columns (paragraphs) added, below is an example of the row 'Where are we active' - this contains 2 columns:

  1. Text
  2. Image

Drupal paragraphs content management images en texts

Different types of columns

In the above example you can already see two of the 7 types of columns available: Text and Image . Currently, the following types of columns can be added to a row by SOS Children's Villages:

Drupal paragraph  types content management

These columns can be added per row and removed and ordered using a drag function.

Settings per column

We are going to have a deeper content management level: the content managers of SOS Children's Villages have settings for a specific column in the backend of Drupal. These settings vary by column type (text, image, video, etc). An example of the Image column:

Drupal image paragraphs content management

  1. Make images clickable or not.
  2. Set the background and text color.
  3. The placed image can be changed here.
  4. Insert an additional image.
  5. If multiple images are placed (eg a list of partner logos): indicate how many images are placed per row.
  6. A row consists of 12 width parts, each column can have 1 to 12 width parts set. This way you can determine the width distribution of columns in a row.
  7. Add a new Paragraph (column) in this row.

2. Form builder

A big part of this Drupal platform is the form builder. The content managers of SOS Children's Villages can create and configure forms themselves and place them as a column anywhere on all pages. In this way they can create unlimited forms for all target groups, sources and campaigns. As a result, unlimited A / B tests can also be run for conversion optimization.

Data flow

Per form, content managers can determine how the completed data flows to the required CRM fields.

Conditional fields

Certain selection fields are dependent on a previously chosen option, in the example below you see that when choosing one-time payment two payment methods must be available. But when choosing monthly payment only one payment option may appear.

Drupal conditional form field

Inline real-time validation

Content managers can set how to validate each field and which error message appears. If a donor clicks away from a form element, the entry is immediately checked and feedback is displayed:

Drupal form validation inline

Postcode API

It is linked with the API of Postcode.nl, as soon as you enter your postcode and house number, the system automatically searches for the street and place name. If the postcode is not found, people can enter this information manually. This is necessary in the case of new residential areas, which have not yet been added as official zip codes.

Drupal postal code api integration inline

IBAN check

As soon as a donor enters an IBAN, a check is immediately done via iban.com. It is immediately indicated inline whether the IBAN is correct:

Drupal IBAN api integration inline

Adyen integration

The online payments are handled and linked back via Adyen. The following payment methods are integrated:

  • iDEAL
  • Credit card (MasterCard / Visa)
  • American Express
  • Bank transfer
  • One-off authorization

CRM integration

In the end, all data is processed in the central CRM system of SOS Children's Villages. This CRM is used by SOS Children's villages worldwide.

Thank you page

Once the payment is made, donors see a personalized 'thank you' page. The content managers of SOS Children's Villages can use placeholders, which are filled in for the donors with first name, address, donation amount etc.

There may be any number of 'Thank you' pages generated by the content managers. These pages can be linked to a donation form, so that a personalized thank you message appears, aimed at a specific campaign.

Thank you e-mails

Similar to the thank you pages, everything that has been put together by content managers is also emailed to the donor.

Mobile first

Given that the majority of the donors visit the platform via a mobile device, we have optimized for mobile. Exceptions like the iPad 2 and Samsung Internet are included.

For example, form elements are given a full width, so that they are easily tapable:

Drupal responsive form

3. Content management workflows

Within SOS Children's Villages there are content managers with different roles, within these roles, workflows with revision management are set up. For example, drafts for new and existing pages can be created by a content manager, which can only be published by, for example, an editor.

Drupal workflow content management

Workflows have also been configured for published pages, so that the live pages can be adapted and checked - of course without the public seeing this.

4. Testing

If it ain’t tested, it doesn’t work.

Testing: often a development is pushed under because of time pressure, but we value it a lot and provide enough space in budgets and time for this. The following tests are carried out continuously:

Peer reviews

Developers test each other's code. No matter how good you are as a developer, at a given moment you can be so engrossed that sometimes you do not see your own mistakes. A lot of code and layout is automatically screened by the correct plugins. But a manual check is also necessary, code is screened mutually among others:

  • Coding standards and syntax
  • Architecture
  • Scalability
  • Non-Dry-ness (Don't Repeat Yourself)
  • Security
  • Speed
  • Format files and folders

Functional testing

Functionalities for the end users (content managers and website visitors) are tested manually; as many edge cases as possible are invented to make all scenarios as bug-free as possible. After completion, the platform is once again tested by SOS Children's Villages themselves, their test team ranged from 2 to 10 people per sprint. In this way, the majority of the edge cases were discovered.

Load testing

A slow platform is extremely bad: visitors drop out and your SEO goes to rubbish. That's why we always perform load tests: fire up an increasing amount of traffic on the test server and see when it drops. This must be well above the number of visitors that have been discussed, in this distinction between logged in and logged out is of critical importance.

Pen testing: try hacking the server

Security, an important part, our colleague and ethical hacker Nick has performed pen tests on the server where the new platform eventually went live. This resulted in a number of issues that have been resolved, resulting in an optimally safe platform.

Unit / Behat testing

Unfortunately this was not yet feasible within the current deadline, but we will implement unit and Behat tests in the next sprint.

This way you can ensure that already completed functions are automatically tested as soon as new functions are implemented. Through this automatic testing of already completed items, we know for sure that everything remains stable and high quality is delivered. Also called regression testing. ‘Auto testing your business expectations’, as Behat describes on its homepage.

5. Other functions


The previous version of the website did not contain a search function, in this first sprint we added it -including search suggestions:

Drupal search auto complete

SOS Children's Villages can indicate whether a page is important enough to end up in these search suggestions; all search results are displayed on the extensive search results page anyway:

Drupal search results page

Credential management

The Drupal platform of SOS Children's Villages talks with a total of 6 API’s, these all know log in data that you do not want in hard code - because of security reasons. We therefore store these credentials in a different, secure way.


The URLs in this new platform may differ from 'old' URLs. To redirect via a 301 the redirect module is used, this is mainly intended to keep SEO intact and to ensure that links on external sites do not end as a page not found.

E-commerce tracking

Google Analytics was used as E-commerce tracking tool, it was implemented using the Google Tag Manager and the data layer.

It’s alive, alive! Celebrated with cake and champagne

The go live was done in stages, we first did a soft launch followed by the hard launch on 1st February.

In accordance with the agreed deadline

Drupal celebration with cake

Drupal celebration with champagne

Post-go live breathing space and the following sprints

After the go-live, 2 weeks of breathing space was scheduled for any hotfixes that might be needed. There were no real hotfixes needed, except for a few (small) 'highly desirable functions'. These were immediately implemented the week after going live.

In the coming period it will be built up considerably, among other things will be added as an extension:

  • Login section for donors
  • VWO integration
  • Cloning pages
  • Integration with Project management system
  • World map

Nerd alert

Top techniques and tools that were used for this development:

Nerd alert

Top technique used

Installed Drupal modules

In addition to the 4 custom developed Drupal modules, the following contrib modules were used:

Wrap up

Alrighty, that’s it for now. A cool project to work on: great technique, challenging and a fun, professional team. Deadline met, customer happy, what more can I say? :) The progress compared to the previous version is also not small: from a cumbersome, difficult to use, outdated content management system - to a scalable and user-friendly Drupal platform. Questions or remarks? Let me know!

Apr 09 2018
Apr 09

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

The biggest ‘module’ being updated was the Drupal core of course: Drupal 8.5.0 was released about a month ago, read more. Also, everything else what stood out to the module updates of last month, enjoy:

1. Password Policy

Drupal accepts all passwords made by users for their user account, even if it only consists of one letter. This modules refines that, you can determine the password policy of your Drupal system, for example:

  • at least 8 characters;
  • at least 1 special character;
  • can’t be the same as your username or email address;
  • can’t be a password which has been used previously.


2. Content- Security- Policy

Content Security Policy (CSP) is an extra security layer, with Cross Site Scripting (XSS) and injection attacks, for example SQL injection. These attacks are used for all kinds of purposes, from identity theft to defacing websites or the spread of malware.

This module can automatically generate Content- Security- Policy headers for you, after you made the right settings in the Drupal backend.


3. Comment Notify

Send a notification to a Drupal content manager or administrator as soon as a comment is posted by a website visitor. This can be set up for both anonymous as logged in visitors.


4. Rest menu items

Headless Drupal remains fresh, and rightfully so. We also use some installations enthusiastically, like this website for example.

This modules helps with setting up an endpoint to serve out the menu items. You can give them query parameters to determine how much menu level you get back in this web service.

You can use the json data to build a menu in a frontend framework like React, Angular or in an iOS / Android App.


5. Breakpoints

A website which isn’t responsive, isn’t worth much nowadays. This Drupal module facilitates breakpoint management for your responsive web design, allowing the right media queries to be set up.


6. Simple hierarchical select

When a content manager has to make a selection which involves categories and subcategories, this way of selecting might be useful to him.


7. Block Visibility Groups

Within the block system in the Drupal core, you can determine per block where to block needs to go and who is allowed to see that block. But you can’t do it in bulk for a group of blocks.

With this Drupal module you can group blocks and configure per block group who is allowed to see what.


8. Empty Page

Whenever we develop a system within Drupal, we always add a route and facilitate the html dynamically to the screen of the visitor of said page in Drupal via controllers, services and Twig files. It’s possible to work with blocks, ensuring that data keeps being positioned well via blocks.

If you are not a developer, in some use cases you’d want to make a page with the help of blocks alone. Like a landing page, which doesn’t need a node.

Within the Drupal core you can never put your block anywhere in such a scenario, as you don’t have a page to put the block.

This module solves this because you can make an empty page and you can leave your blocks on that empty page. This prevents you from tediously making an empty node, generating unnecessary overhead. Exactly the problem the developer of this module intends to solve.


9. EU Cookie Compliance

Shows a notification in the footer of your Drupal site, where visitors agree to your cookie policy, or click for more information. This module makes it easy for you to comply with this mandatory notification.


10. Shield

We use this module in almost every Drupal installation when it comes to test- and acceptation environments. It completely shields your website from the outside world, unless you log in of course. Anonymous visitors and search engines won’t be able to reach our test environment, but we and our customers can.

Previously we used to do this by manually making a .htpasswd, which is kind of cumbersome and is getting in the way locally as well, as you also need to incorporate it in .htaccess.


11. Access unpublished

Within the Drupal core it isn’t possible to have unpublished content being looked at by anonymous website visitors. Not even when they have a direct link of said item.

It is now possible with this module, useful for content checkers and proofreaders for example: they won’t need a log in for the website, making it easy to work with and secure.

(!) please note that the page can be indexed by Google, thereby making it findable for everybody. Don’t keep a draft open like this for too long and definitely don’t share sensitive information via this route.


12. Anonymous login

Previously, we developed a similar custom code in Lus to use this feature: redirect all non- logged in users to the login page.

This Drupal module offers a similar feature: it also redirects anonymous visitors, but only when they request an admin path. When someone successfully logs in, that someone will be redirected to the original admin path from where he entered.


13. Simplelogin

Generates a different login page, which is more simple, more compact and potentially more beautiful. You can also add a nice background image fit it in your own house- style.


14. BeautyTips

Shows tips when someone hovers over a certain text with his mouse, similar to the Bootstrap tooltip.


15. Schema.org Metatag

A great addition to your website for search engine optimization (SEO). It enriches your html, allowing search engines to better ‘read’ your Drupal system.


16. Login History

Drupal core doesn’t keep a history of logins, but there are scenarios where this is necessary. Among other things, this module generates:

  • rough overview of all logins;
  • logins from individual users;
  • a block with login data for the visitors themselves: when was his last login and a link to his login history.


17. Minify JS

Drupal optimization tool, this module minifies all your JavaScript, making your JavaScript files smaller and less heavy for a network and browser.


18. Minify Source HTML

Similar to ‘Minify JS’, but for the generated html.


19. IMCE Rename (D8)

IMCE is a popular tool for Drupal content managers to manage social media. This plugin allows names of files to be changed, ensuring better structuring and management.


20. Create and continue

A useful tool for when you need to add a lot of content, this module generates an extra button under your content item: ‘Save and add another’. You can continue with adding the next item immediately.


21. Block Refresh

Want to keep information in a Drupal block up to date, even when the page isn’t refreshed by the visitor? No problem, this module will take care of it for you:

  • automatically refresh the content in a block after xx seconds;
  • visitors can refresh manually;
  • refresh after page refresh;
  • can optionally be excluded in Drupal’s page cache or every external cache (like Varnish).


22. Single Date Time Picker

Easy adding of a required date and time.


23. Secure Login

Forces logging in via a secure line, in order to optimally protect your visitors’ privacy.


24. Menu target

Not available in Drupal core: specify per menu item if clicked link for visitors should be opened in current or in a new screen. Install this module et voilá: now you can specify if you want to have it opened in current or in a new screen.

25. Persistent Login

Drupal doesn’t have a standard ‘remember me’ feature in the login screen. This module does offer that feature and some extra security measures have been taken: it doesn’t implement a standard longer ‘PHP session time”.

You can set up the following:

  • how long the users remain logged in, before they need to enter their information again;
  • how many persistent sessions one Drupal user is allowed to have at the same time;
  • determine for which pages the user does have to log in again, for example: when you want to change your user information.


26. CacheExclude

Without active page caching a Drupal website won’t be able to handle a lot of visitors, that’s why it standardly active. But it can happen that you want to exclude certain pages from that cache, because realtime/ dynamic data is shown. When you need a random image or changing content, you might want to check this Drupal module out.

Wrap up

Alright, that's it for now. I hope that this information allows you to further enrich, optimize your Drupal site and make it more user friendly.
Questions? Let me know!

Apr 03 2018
Apr 03

Erik de Kamps
Drupal developer

+31 (0)20 - 261 14 99

Last week we had to update all Drupal websites that we manage because of a high risk security release. We saw too late that some (older) sites didn't have a proper maintenance page. So we released a mini module that provides a quick solution for sites with similar issues:

If everything is alright, your Drupal website doesn't have to be in maintenance mode that often. So maybe it's a waste of budget to put effort in this.

But when you dó need to put it in maintenance mode, you probably don't want an ugly page for your visitors.

So that's why we developed this module: after install it'll provide your Drupal website instantly with a clean maintenance page. It doesn't matter what theme you use, it's clean and it works for Drupal 7 and Drupal 8

Saves a lot of time in manually formatting it in template files :)

Check it out: https://www.drupal.org/project/clean_maintenance

Mar 30 2018
Mar 30

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last week there was a Public Service Announcement done by the Drupal security team: a highly critical security update would be released last Wednesday, around 20.00h Dutch time. So we planned this release and put up a little patch party to facilitate that evening:

  • Put all sites in maintenance mode.
  • Hotfix all sites.
  • Testing.
  • Bring back to live.

It took a little while longer before the release was done, it came around 21.30u Dutch time. We had all our sites patched and back in business around 22.30u.

Tweet away

So during the waiting people started getting bored and posted a lot of tweets, here are a few cool ones:

Drupal security team hesitating publishing security patches#drupalgeddon pic.twitter.com/Y96nPfZETi

— zigazou (@zigazou) March 28, 2018

Today the web will blackout.

All #drupal sites will go in to maintenance mode for a security update, hitting 10% of the top 1M sites

In 9 month later we will see the results...

— bert boerland (@bertboerland) March 28, 2018

#drupalsecurity #drupal pic.twitter.com/1BSg7nqkhm

— James Pegram (@jamespegram) March 28, 2018

Waiting for the Drupal patch release like #Drupal #drupalgeddon #drupalsecurity pic.twitter.com/oyqjobeSAq

— Gabs (@gabstuff) March 28, 2018

When you wait for Drupal Security Release

All credits to @benfrancesco (genius)#drupal #drupalsecurity @drupalsecurity pic.twitter.com/8blRri4cZl

— Stefano Mainardi (@stefanomainardi) March 28, 2018

Me the moment the #drupal security update becomes available pic.twitter.com/SXNBWvWX3c

— Web Assistant (@_webassistant_) March 28, 2018

Yo, esperando a ver qué trae el patch de Drupal. pic.twitter.com/cWSO5DIKOO

— Blockchain professional services (@nocabeotraletra) March 28, 2018

#drupal #drupalgeddon2 pic.twitter.com/wnUgBsff7D

— Web-Beest (@WebBeest) March 28, 2018

Waiting for #drupal security update like this pic.twitter.com/gNx4KXgRPN

— Vlad Bo (@bobowka112) March 28, 2018

Refresh / twiddle thumbs / repeat. #drupal
(Also, take your time @drupalsecurity rockstars. Am patient, as long as the end result works.) pic.twitter.com/YTSsgaKYY2

— Kate B (@keb36) March 28, 2018

Pretty much all #Drupal developers/agencies around the world right now...!#drupalsecurity #drupalgeddon2 #tense #poised #Tminus30minutes #TheAnticipationIsKillingMe pic.twitter.com/AzCObJD268

— Steve Allen (@ttesteve) March 28, 2018

Pronovix is ready and fully prepared for the critical Drupal security release! :) #drupal #drupalsecurity #drupalgeddon pic.twitter.com/0A3c4HNnj0

— pronovix (@pronovix) March 28, 2018

Still waiting #drupalsecurity #drupal #drupalgeddon pic.twitter.com/161mwEcVF0

— Gabs (@gabstuff) March 28, 2018

Hey @drupalassoc! We're having a @drupal update party! pic.twitter.com/G0ti9BaKXj

— netkata (@netkata) March 28, 2018

Wachten op Drupal security update... Duurt lang!! #drupal pic.twitter.com/AZoEecBCjv

— Dominique van Gimst (@dvangimst) March 28, 2018

The entire Drupal community be like... pic.twitter.com/8oYm9zSWGY

— Dale Trexel (@DaleTrexel) March 28, 2018

Bring it on #Drupalgeddon!! #Drupal #Security pic.twitter.com/aleMynEELm

— Taco Potze˙ (@tacopotze) March 28, 2018

And we joined the party :)

#drupal patching party in full effect right now :) pic.twitter.com/LLZUIRTFQh

— Lucius Digital (@lucius_digital) March 28, 2018

Ready for #drupal #security release, all sites in maintenance | #readytorumble ! pic.twitter.com/desNITN9sS

— Lucius Digital (@lucius_digital) March 28, 2018

Mar 19 2018
Mar 19

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Recently we produced realtime messaging platform 'Lus' in our labs, but why and how?

Background story

A few years ago we developed OpenLucius, still a popular open source Drupal platform which could be used as social intranet, project management and/ or file management.

But at a certain point we also appreciated the value of popular realtime communication apps like Slack and Trello. Even though OpenLucius also has a task board and messaging, they aren’t in realtime. Neither does it have group messaging in channels, like they have in Slack.

Optimization of communication

We wanted to use these features to further optimize our projects and communication, both internally as well as externally, with customers and suppliers.

But Slack and Trello missed some features which are crucial for our business processes and its constant optimization. For example, we’d also liked to:

  • keep our data in-house;
  • have a platform that caters to and can be expand on our business processes;
  • have one consistent system instead of multiple app islands, where info lives incoherently.

We were also very eager to master the modern realtime techniques in Node.js with help of Socket.io.

The Node.js realtime/ streaming techniques are also being used by platforms like PayPal, Spotify, Netflix and Uber by the way.

Introducing Lus: realtime communication platform

That’s why we developed Lus in our Lab. Lus has bundled all functions (well, the basics) we saw spread across other systems into one. It's a realtime messaging platform where you can optionally use:

  • projects and tasks;
  • clocking and budget management;
  • documentation (wiki).

Successful experiment turns into mature product

What started out as a lab experiment, turned into a success in the field. Customers inquired about the product. Since then it has grown into a mature platform, which is being run by its first customers.

Currently we’re also developing iOS and Android apps and the necessary API for it as well.

What’s next

We’ll keep on developing the product based on feedback, mainly making current features more user-friendly and optimising code on scalability . At some point we hope to release it as Drupal distribution, just like we did with OpenLucius.

Functional details

Check the Lus website and Lus docs website.

Teaser screenshots

Realtime Messaging

Realtime messaging in Lus


Realtime tasks in Lus


Mentions in Lus

Realtime file sharing

Realtime file sharing in Lus

Your thoughts matter

As said, we like feedback. So what's your take on building this in Drupal / Node.js ? This can be from a technical -or functional point of view.

Please let me know in the comments!

Mar 14 2018
Mar 14

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Never having to remember your Drupal passwords again, how great would that be? It appears the working without passwords even is the most secure option. But how is that possible?

Lately I have been experimenting with Medium: a great blog platform with built in social functionalities. We might have even migrated our blog, because I was reading a lot of positive stories about it. Eventually we decided against migrating.

Anyway, that wasn’t the subject for this blog. What I noticed about Medium: you can’t manage a password anywhere. Logging in and registering via email goes as follows:

I recognise this from all Drupal systems we are managing: for security reasons we never register any of their passwords. So when we log in, we are never doing this through a password, but with a one-time login-link, just like Medium.

You will remain logged in for a few days, and as long as you remain active, you won’t have to ask for the login link every time.

Wake up

I told this to several people and their first reaction usually is: huh? But what if someone has access to your email? This allows that person to login? Wake up: if someone has hacked your email, he can log in to anything. Into all your accounts and into all your systems. Because all internet services work with a ‘forgot password’ function which sends a one-time login-link to your email, allowing you to change your password.

Authentication: serious business

All internet platforms want to make their login process as secure and as simple as possible, from all devices imaginable. But they are hard to remember, sometimes guessable and a lot of people re-use the same (even though they shouldn’t). They are also hard to type in on your smartphone, especially if you are required to use special characters – it’s so annoying to type those!

Wake up 2: without passwords it’s more secure

It goes against your gut feeling, but a system without passwords is more secure than one with passwords. As soon as someone hacks your password, that someone has access to said website until you change your password, usually never. It could be that you never notice that you were hacked and someone gained access to your account.

If you use an email-only-system, the following points should be taken into account:

  • Have the login-link expire quickly: after 15 minutes already.
  • Make sure the login-link can only be used once.
  • Send a notification email if someone tries to log in from an unusual position (browser or physically).

Drupal can facilitate all of those.

Shifting security

If your website works without passwords, it means that you are shifting the security aspect to the email provider and it may look like you are an easy breeder. But security at email providers should be high top utmost priority number one anyway.

Your website login is as secure as the users’ email provider.

Getting new users easier

Another marketing advantage: at email only login, registration is as easy as logging in itself. This lowers the threshold to start; not having to come up with a username and password anymore.

Password frustrations

By working without passwords you will also get rid of the following frustrations:

  • Entering it on a smartphone: ever tried to type in a password on a smartphone? Especially with special characters…simply hell!
  • Brute force attacks: mature systems are protected against brute force attacks with the help of ‘flood control’, which prevents you from logging in after 5 attempts. Necessary to keep everything secure, yet annoying for users, because they have to wait for a while before they can log in once again. It’s just waiting to receive helpdesk calls.
  • Password strength meters: these are being used to make sure that people pick strong passwords. But in reality very little users understand them, and are ignored by many.

Two factor authentication

Another good extra function for logging in is the use of Two Factor Authentication. This is an extra security measure, and the two factors are: “something you know” (a password) and “something you have” (usually a smartphone). But it seems that many users won’t enable this on supporting platforms.
It is advisable to protect the login of your email with two factor authentication anyway because

Hacked email = hacker has access to all your systems by one-time-login-link.

Hacked website? No problem

At least.. not in the password context: if you have an email-only login system, it means that no passwords will be saved on the hacked database, and no user passwords are to be found. ¯_(ツ)_/¯

Because many people use one password for all their accounts, if the database contains passwords, a hacker will gain access to a lot places.

A mature website’s database has encrypted and salted passwords, but smart robots will eventually always be able to uncover passwords anyway.

Wrap up

Right, first I’m going to change my email password and enable two-factor authentication. I can’t find any reason anymore to work with passwords on the internet. Just optimally secure your email all the time and go.

Or am I missing something here?

Mar 09 2018
Mar 09

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Per May 25th 2018, the General Data Protection Regulation comes into effect, making it advisable to have an extra check on the security of your data. Here are some tips on securing files in Drupal:

Paris is always a great idea

When we left for Paris for new years’, we needed a cat sitter. I looked around and found Pawshake: an international platform which soon provided us with someone. I quickly realized it was a Drupal platform, so I made a profile on it and decided to test the waters: is my profile picture being protected…? And it appears it doesn’t seem that way! Anyone can see my picture without logging in. You can check it yourself, it’s not great. How they could fix it:

Public vs Private files

Generically speaking, there are two kinds of files, when you manage a website- or app: public or private. Technically speaking you will have to decide how your content management system will manage those files and how to apply the correct security on them. This depends on the kind of services you are providing with your website- or app.

Public files

These are primarily used by websites with public content, with nobody logging in (except for content managers and admins) and which are mainly used to provide information regarding products and/ or services.

Private files

These are primarily used in case of a web application such as:

  • Social intranet;
  • Online community;
  • Chat application.

For the last one you’d like all files being uploaded by a user not to be visible for just everybody – and you’ll have to design your system accordingly.

Private and public files in Drupal

Drupal contains an extensive file management system which can facilitate public and private files. You can reach the settings via the configuration screen:

As soon as you click on the File system the details will appear:

  1. Directory where the public files are being saved.
  2. The absolute URL which is put in front of all public files
  3. Directory where the private files are being saved, in this case not activated yet.
  4. Standard way how a file can be downloaded, as soon as the private files directory has been set up, you’re also able to opt for private.
  5. Time before temporary/ orphaned files will be removed permanently. This concerns all files with status 0 in the database.

Activate Private files in Drupal.

The above is a standard installation, with the files set on public. But as described, you might want to protect your files, making them accessible to users with the right permission only – instead of the whole, anonymous world. This is how to do it:

Configure the private files directory in settings.php:

In this case you opt for ../files. Makes sure this directory is outside the webroot, otherwise there might be a chance that your private files are publicly available anyway. If you empty your caches after that (Flush all caches) you can pick you pick private files as default download method:

  1. The path as set in settings.php
  2. Adjust the /tmp directory, ensuring temporary files to also be protected.
  3. Set private files as default download method.

Now, Drupal is configured to treat all files as private: if visitors want to download a file, or want to look at an image for example, it will be via a Drupal system call and not by directly invoking the file by the browser. In that call Drupal decides whether the visitor concerned has permission to download the file.

Determining yourself whether someone is allowed to download a private file or not with the help of hook_file_download().

Currently, we are building a chat application based on Drupal and NodeJS: Lus. This has channels (group chats), in which files can be shared. Of course we only want people in the channel concerned to be able to download the files from that group. For example, if you’re not in group A, it ought to be impossible to approach files in that group A.

For more information regarding Lus, see lus.digital & docs.lus.digital.

This concerns a custom web-app, that’s why Drupal doesn’t have suitable permissions to sufficiently secure this. but no worries: hook_file_download() to the rescue, here is a code which we produced in our .module file:

Drupal recognizes the hook_file_download(),making sure it will invoke this function when someone is about to download a file via Drupal’s private file system.

What this code basically does:

  1. Checking who the current user is.
  2. Checking whether that user is in the channel to which the file has been uploaded.
  3. When the user is in the channel: loading file and returning file, making it available for the visitor concerned.
  4. When the user is not in the channel concerned: provides a not found.

Wrap up

Generically speaking, there are public and private files on the internet. Determine which file system you need, before you start producing an online platform, website or app. If you deploy Drupal, I hope that you can structure the files properly and securely with the information as provided above. Any questions? Let me know!

Image Credits

Feb 28 2018
Feb 28

Stijn Berkers - Producer

+31 (0)20 - 261 14 99

Currently we are busy building a realtime chat platform called Lus. In Lus we connected Drupal to NodeJS for a blazing fast system, with realtime communication (chats, tasks & file sharing).

Within Lus, people can cooperate in ‘channels’, comparable to the WhatsApp groups. Team communication takes place in these channels. A channels works best if you organize it around a certain topic, like ‘sales’.

As soon as a new channel is being started, existing team members can be added in the easiest way imaginable: with the help of a ‘auto-complete field’: as soon as you start typing, suggestions will immediately pop up, in this case for names of team members:

This auto-complete field has been custom developed by us, in part because our Drupal installation uses custom database charts which aren’t available in Drupal 8 core. How did we do it:

1. The form element

To get started we need the Drupal auto complete form element, allowing users on the front end to pick the desired team members. We define this as follows:

Because we use #autocomplete_route_name element, Drupal knows that such a form element has to be ignored on the front end.

2. Custom route

As you can see in the form element, a reference is made to the route, from which data has to be obtained. We’ll add these in the .routing.yml file:

This routing.yml file is already in our module’s root.

3. Controller with custom query

In the route we just created we refer to a custom controller AutocompleteController, method handleAutocomplete. This one can be found in the map moduleroot/src/Controller:

This method ensures that the right data is collected from the data base and will be given back correctly formatted as well.

Wrap it up

As you can see, suggestions are being given for code corrections. In an optimization run we’ll get onto it. For now, at least the data is coming though correctly and we can create new channels with existing team members by means of a auto-complete field.

Credits header foto: ricardo Gomez Angel

Feb 12 2018
Feb 12

Stijn Berkers - Producer

+31 (0)20 - 261 14 99

Currently we are busy constructing the production of a realtime messaging platform in Drupal and NodeJS, look at it as a ‘WhatsApp for Business’. This Drupal system works like a web app; logging in is mandatory. How do you make sure that logged out visitors must log in to Drupal 8 before they are allowed to continue?

Drupal has many out-of-the-box functionalities, as well as a powerful API, but because it has so many functions many tracks are standardly available for anonymous visitors. We’d want to make all paths unreachable, until you log in.

That means that visitors always will be redirected to the login screen as long as they aren’t logged in. You wouldn’t want an anonymous user reaching internal news on the homepage.

Redirect URL in Drupal 8

  • Basically, we want all url’s / paths be made unavailable for non-logged in visitors, except explicitly specified pages like:
  • Login (/user)
  • Forgot password (/user/password)
  • Login link (user/reset/login)

in Drupal 7 you could use the module Logintoboggan for that purpose. You could also easily work around it in hook_init() or hook_boot() in a custom Drupal 7 module.


This was quite a puzzle, and we soon found some examples as well as exceptions. Everytime it didn’t work how we wanted it to. This example was the most useful.

Implementation in Drupal 8

Eventually, we got it working with the help of following code in a custom Drupal 8 module:


put this file in your module root, and format yourmodulename.services.yml:


Put the file RedirectAnonymousSubscriber.php in folder /src/EventSubscriber/ and do your custom thing:

Deze code haakt in op de EventSubscriber van Symfony, het framework waar Drupal 8 op gebouwd is.

Wrap up

Alright, that’s it. I hope the information as described will help you to always redirect visitors to the login page. Questions or feedback? Let me know!

We zoeken altijd naar optimale inzet van Drupal contrib modules. Maar in sommige gevallen voldoen ze niet aan benodigde eisen, wensen, stabiliteit en/of veiligheid. In dat geval ontwikkelen we de code op maat; eventueel met behulp van snippets uit andere modules.

Wanneer we dan maatwerk moeten ontwikkelen proberen we het altijd generiek maken, zodat er eventueel een contrib module van geproduceerd kan worden en vrijgegeven op Drupal.org. Dit doen we altijd in overleg met opdrachtgever.

Zo’n voorbeeld is de zojuist vrijgegeven module ‘Conditional Redirect’: een aantal modules kwamen in de buurt, maar voldeden net niet.

Drupal geheel afschermen middels login

Het gaat om volgende functionaliteit: stel dat je een systeem in Drupal produceert wat bedoeld is voor intern gebruik zoals een social intranet of project management app.

Dit systeem moet wel wereldwijd beschikbaar zijn, maar alleen toegankelijk nadat mensen ingelogd zijn. In dit geval wil je graag dat álle bezoekers die niet zijn ingelogd naar de login page worden door gelinkt.

Als extra wens: bepaalde pagina’s moeten wél publiekelijk beschikbaar zijn en dus als uitzondering hierin ingesteld worden.

Bovenstaande is gerealiseerd in de vrijgegeven module: na installatie hiervan zullen alle uitgelogde (anonieme) bezoekers naar de login page geredirect worden. Tevens zijn hierin uitzonderingen te configureren:

  • Content types;
  • Specifieke pagina’s;
  • Specifieke menu links.

Download de module hier

Wrap up

Alright, that’s it. Vragen of opmerkingen over deze module? Let me know, of schiet een issue in op de project page op Drupal.org

Photo by Dmitri Popov on Unsplash

Dec 20 2017
Dec 20

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Nederlandse versie van dit blog

The Popup question redirect module allows Drupal site builders to show website visitors a pop-up in which a question can be asked. If the vistor clicks "Yes" they will be redirected to a given webpage.

Examples of use cases:

  • Request for filling out a survey.
  • To offer a promotion.
  • Highlight a certain (news) page.

Drupal website visitor features:

  • A "Yes" button, visitor will be directed to desired (external) web page.
  • 'Remind me later', show the pop-up again later.
  • "Do not show this again", pop-up will not be shown again.

Drupal backend configuration options

There are configuration options in the Drupal backend:

  • Set popup title and message.
  • Text field to set the redirect link.
  • 'Remind me later' time.
  • Finally, you can enter a list of IP addresses, so the popup will not be shown for visitor from a certain IP / building.

Download here

Credits header foto

May 03 2017
May 03

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Within a Drupal 8 website, there are usually a number of texts that the content manager must be able to manage but that are not real content items.

Dutch version of this blog here.

We resolve this by making a user-friendly configuration form in the backend of Drupal 8, accessible to content managers. This allows us to make sure that all non-content is easy to manage, so that content managers do not have to dig through all kinds of screens in a technical backend to find the correct settings.

An example are the texts (and background image) in this Frontpage header block:

An example of the corresponding Drupal 8 backend configuration form:

This blog series consists of three parts:

  1. Building the Drupal 8 backend configuration form and defining a Twig template file.
  2. Development of a custom Drupal 8 Block, in which imported texts are retrieved from the configuration form; rendered in a custom Twig template file.
  3. Managing the background image via the already defined backend configuration form.

In this part 1:

  1. Create a new module using Drupal Console.
  2. Implement Drupal 8 backend configuration form.
  3. Defining Twig template file - and variables, for facilitating dynamic html in the frontend.

1. New module with help from Drupal Console

Drupal Console is a CLI tool for boilerplate code to generate (also called skeleton code). Console also offers functions to perform and debug actions within Drupal 8.

Drupal Console also offers functions to generate Drupal forms, that is, boilerplate code. To do this, we have to start creating a new module in which the form is then implemented.

Generate a new module using Drupal Console:

  1. Enter command drupal generate:module in a terminal.
  2. Enter a name for the new module. We are only going to use this module for configuration purposes, so I call it 'OpenLucius Configuration'.
  3. The yellow text is the default entered by Console if you press enter without entering anything. This default module machine name is fine, so press enter.
  4. The same goes for the module path. It is a best practice in Drupal to subdivide the /modules folder into /contrib *, */custom and /devel.
  5. Enter a description, it appears in the Drupal 8 backend on the global /config screen.
  6. Yes, I want to generate a .module file. We need this later to implement a hook_theme, where we create a Twig template file known to Drupal. In that, the dynamic html will go live.
  7. We indeed need a themeable template file as mentioned in (6). By default, this will not generate the correct naming, but it is useful as an example code.

2. Generate Drupal 8 backend configuration form

The following fields must be managed by content managers:

  1. Frontpage header title
  2. Frontpage header subtitle
  3. Frontpage header intro text
  4. Frontpage header read more link
  5. Frontpage header background image

Now, for example, Site name and Slogan fields are already available in Drupal 8 core and may be used as Frontpage header title and Frontpage header subtitle.

But for the convenience of content managers, we do not use those Drupal core fields and we create one easy-to-use form that controls all non-content fields. Thus, no fragmentation of features across all kinds of technical administrators, which scares a content manager.

Defining fields and field names, we always do it in English, given that the Drupal 8 backend is always English and it is the language of development (code, comments, etc) as well. We always keep the backend English for consistency in, among other things, debugging and helpdesk issues from customers.

Generate the fields

We start creating the text fields, the image field we deal with in part 3 of this blog series.

I generate the required backend form in the newly created module as described above. We make the form and the text fields using the Drupal Console:

  1. From the web root of your Drupal 8 installation: enter drupal generate:form:config in a terminal.
  2. Specify which module you want to put in the form, so you must generate it in an existing module; Therefore we first created the Drupal 8 module above.
  3. Do you want to load services? Read more about Services and dependency injection in Drupal 8. For this example it is not necessary to key enter.
  4. Start building up the form fields by defining the first field, in this example I start generating the textfield 'Frontpage Header Title'.
  5. Give your field a Label, this text will be above the field. Enter a clear name here, so Drupal content managers know what to enter here.
  6. Configure optional values for elements associated with this field.
  7. You can enter as many fields as you like, until you reach “New field type (press to stop adding fields) [ ]:” thus pressing enter without entering text. Then some final questions will be asked, after which the form will be generated in the indicated module:

  1. Once you have entered all the elements, leave it blank and hit enter.
  2. Enter the desired path (route), this default is fine. More about Drupal 8's routing system here
  3. The default Yes is fine, we would like it to appear in the backend menu so that content managers can easily navigate to it.
  4. Enter the title of this desired menu item and place it in this default parent menu: This will appear in the Drupal Backend menu.
  5. Give it a description, which appears on the config overview page:

Drupal 8 Form API

Drupal 8 has an extensive Form API, which lets you see which elements and options are available. For more information see:

The folder and file structure of the generated module looks like this:

The generated code for the form:

Install module and Drupal 8 backend form

Install the module so that the generated form becomes active. This can be done with Drupal Console's command module:install :

A link is created in the configuration screen:

And the form detail page works:

The form is used directly, saving the values in the database is immediately:

3. Defining Twig template file and template variables, for facilitating dynamic html in frontend.

Drupal Console has just created a template file and defined it as hook_theme(), so that Drupal 8 recognizes this and we can call it in modules through the Render API and / or those in Drupal 8 theme can override.

But as Drupal Console has defined it, it's too generic, I'd like it more specific because more Twig template files will be added soon. Also, I want to add Twig template variables, to make the html dynamic. These variables will facilitate the input of content managers, making it completely dynamic through the backend form.

To initiate this, I make two adjustments:

  1. I change the template file name so it's less generic and we can already deduce what the name is being used for.
  2. I change the Twig template definition in hook_theme(), so Drupal is aware of the 'new' Twig template file. Also, I have defined template variables so that Drupal knows which variables are available. These Twig variables I will further implement and explain in the next part of this blog.

Twig and Drupal 8

Learn more about Twig templating in Drupal 8? Click Here.

Placing HTML in Twig template file

As the last action in this part of this blog series, I place the (already developed) HTML in the Twig template file:

As you can see, I immediately placed the Twig variables, which in the following section we will go to "fill in" with texts entered by the content manager in the backend form.

Wrap up part 1

Alrighty, we have now created a module and generated a Drupal 8 backend form. In addition, we have defined a Twig template file and variables, which means that Drupal 8 knows that our template file exists and which variables are used in it.

But we do not see this HTML anywhere in the front end, and the texts are not yet dynamically loaded from the configuration form.

How do we do that? That's what I describe in Part 2, so stay tuned!

Apr 12 2017
Apr 12

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

It took a while before I could write a new edition, I was just busy with the production of customer social intranet projects :) Here again with a brand new version, what struck me in module updates in the past month:

Dutch version of this blog here

1. D8 Editor Advanced link

A popular module that extends the standard editor in Drupal 8 with additional options for managing links. You can now add the following attributes:

  • title
  • class
  • id
  • target
  • rel


2. Password strength

Default password checks are stupid and annoying for the user: they can check the entered password meets certain rules, such as the number of characters and varying types herein (symbols, numbers, capital letters etc.).

This is a stupid way of checking because the password 'Welcome123' is accepted, while it is easy to guess.

This module enables a secure password policy by "pattern-matching" and "entropy calculation”. Almost every type of password is accepted, as long as it has sufficient entropy.


How it works

Instead of checking strict rules, this module calculates the expected time a brute force attack needs to retrieve the password. This is calculated based on underlying patterns:

  • Words that appear in a standard dictionary, common first and surnames and other default passwords.
  • Words from a dictionary, but written in Leet / 1337. For example, where the "e" is written as a three and “a” like an @.
  • A standard sequence of letters like "abcdef", "qwerty" or "123456"
  • Dates or years.

This module has been around since 2007, I wonder why I only encounter this now :) It is currently available in alpha for Drupal 8 and stable for Drupal 7 available - it is supported by Acquia and Card.

So if you want people to not have to bother to look for a password such as "one special character, 1 upper case and at least 8 characters', then this module offers a solution.


3. Better Field Descriptions

In order to give content managers issues, it is possible to write an explanation of all content fields that they import. But the standard explanation in a field in the backend of Drupal are often irrelevant, to not apply these generic texts in the implemented user story of the installation concerned.

After installing this module you can:

  • Content managers have their own explanation text per field.
  • Set where it stands: above or below the field.
  • The explanatory style that you like.


4. Better login

Want to make the standard Drupal login screen better? Then install this module and you are good to go: through template overrides you can then do the required further tuning of the layout of the login screen.


5. Ridiculously Responsive Social Sharing Buttons

Another social sharing module, but as you see in the title: these are terribly responsive. The icons are SVG based and you need no external services such as AddThis.

Advantage: you're less dependent and have your data in hand, downside: you have less functionality- such as comprehensive statistics.


6. Flush Cache

If you are not using Drush or Drupal console then you can Drupal caches flush via “the 'Flush all caches" button in the Drupal backend. But in a production environment, you will almost never flush all caches, it can cause severe performance problems.

This module solves that problem: install it and you have more control over the caches you want to flush.


7. Multiple Selects

Have your Drupal content management easier with 'multiple selects' administration, this image seems to me to speak for itself:


8. Neutral paths

If you are running a multilingual Drupal website, visitors can see the content in one language: the currently active language. Sometimes you would like to see pages in another language. In addition: content managers / Drupal administrators usually want English and not the backend default language, in our case, often Dutch.

Issue tracking for example, much easier if the backend is in English: Drupal documentation and support in English is much more available than in Dutch.

This module ensures that you can visit other pages in another language than the default. And can navigate the backend in English, while frontend is in another language.


9. Password Reset Landing Page (PRLR)

Drupal core includes a 'password' function: If you have forgotten your password then you can request a one-time login link that is automatically mailed to you.

If you click on the login link, you will see a screen with a login button. Once you click the 'login' button you are logged in and you are redirected to your profile page - that's it.

You are in this situation where your password is lost / forgotten. You are not required to change your password. This is not usually done, so people often endlessly request login links.

This module solves this: the screen where you end up after clicking on the login link not only contains a login button, but also a function to change your password immediately.


10. Auto Purge Users

The user list in Drupal is usually not or hardly ever administered. If people have long been inactive or have not completed their registration, the account can usually be removed to avoid overhead and security issues.

This module does it for you automatically, it checks inactivity below a point and blocks users if they meet:

  • Certain time inactive.
  • Account never activated after registration.
  • Not been logged in for a period of time.

Not a popular module, but in the case of an example Drupal social intranet it can come in handy.


11. Vertical Tabs Config

Want to influence the order of the Drupal tabs? Or do you want some tabs to not show all of your content manager? To keep tabs simple and usable you can install this module: select which tabs to show and in what order.

Modules with similar functions: Simplify and Hide vertical tabs.


12. Custom Search

The default Drupal search is fine, but really standard: you have few options to tune the engine. After installing this module, changes that you can then include are:

  • Change the default label in the search box.
  • Set a default text in the search box.
  • Tune 'Advanced Search'.
  • Change the text on the "submit button”.

And much more, see module page:


13. Persistent Login

Drupal 8 core does not have a 'remember password' function when you log in. You can remain automatically logged for some time, but that is based on a PHP session. This module does not, you can also:

  • How long users can stay logged in.
  • How many places a person can be logged in at once.
  • Select certain pages that the user must log in again at. These are usually pages where more sensitive information is available.
  • Allow the user to delete all his logins themself.


14. Realistic Dummy Content

Source image: gov.uk

Using the Devel module you can automatically generate content so you can see if your modules / themes work well. But it gives an unrealistic picture of the end result, this module generates more realistic images and texts.


15. Password Policy

Although I am a fan of the aforementioned 'Password strength' module, this can also be useful if you want to make a specific password policy on your Drupal website.


16. Mass Password Reset

This module, we often use to implement Drupal social intranet OpenLucius: in preparation of a new intranet you can add all users and content on a test environment, without notifying people of their new accounts through e-mail.

Once the social intranet went live, we sent all users at once an email with a login link via this module; the system was live!


Wrap Up

So far that’s what I noticed last month in Drupal modules, stay tuned for more fat Drupal content!

Source header image

Dec 13 2016
Dec 13

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Speed is important in a Drupal website, very important. For visitors as well as search engines, it’s an essential benchmark to success. But how do you keep your Drupal system fast, even when it has millions of pages and documents? Solr is the answer, here is why and how in Drupal 8.

(Dutch version here)

At the moment, we’re migrating a Drupal 7 website to a Drupal 8 system in which there will be millions of pages and documents in the near future. The aim is to have end-users navigate mainly through the search function. That means it has to be extremely fast.

Drupal 8 core contains a great search function, but because this searches standardly in a MySQL database, the search function becomes too slow when the website contains a lot of pages and documents.

Fast search within Drupal 8 with Solr 6

Just to be clear: when you have a Drupal 8 website with a lot of content, the system will be fast enough when you navigate through clicking menu items or links in content/blocks. We’re now talking about the search function and getting relevant search results fast.

Search engine Apache Solr has been Drupal’s friend in this for years. An implementation of Solr ensures a fast search function on your Drupal system and offers extra functions such as:

  • Fuzzy search: spelling mistakes and differences are possible
  • Facetted search: search filters.
  • Rich text-snippets: a piece of text like Google gives you as well, where the search query is highlighted. If you have implemented schema.org, found data will automatically be presented ‘rich’ and placed in the correct context with relevant label.
  • ‘Did you mean…’ function: suggestions for synonyms, or keywords that are close to your search query.
  • Configure the most relevant results from a query, so the visitor sees the most relevant content at the top. Examples from how you can order: content type, comment count, date, sticky, title, headings (h1->h6), body text and lots more.

Especially the fuzzy search is very welcome; Solr really is a beautiful engine and it’s incredibly fast: millions of documents are no problem. Of course, if your servers capacities are configured correctly.

Implementing Solr in Drupal 7 versus Drupal 8

Solr in Drupal 7 is relatively simple to implement, because it has already been developed for years: lots of stable modules are released to produce all sorts of user stories.

In Drupal 8, the integration has already been developed quite a bit, but it’s not yet plug-and-play like in Drupal 7. The design of the architecture has also been changed: you had two important Solr modules for Drupal 7: Apache Solr Search and Search API Solr, both have their own eco-system of modules.

In Drupal 8 the forces were joined, whereby the development became better and extra modules don’t have to choose anymore which eco-system they will build. Modules as Facet API (now Facets), Facet API Pretty Paths, Search API Autocomplete, etc.) can now focus on one implementation instead of two (source).

Implementing Solr in Drupal 8

At the time of this writing, the Drupal 8 Solr module is in beta1, which includes in this case that it is stable enough to put it in, but it's not plug-and-play yet.

Underneath, you can find an explanation of how we got it to work:

The Solr server

We have set up a new VPS, on which Solr is installed. It doesn’t work on the live server of the website, because the concerned hoster didn’t support it.

Besides that, Solr can be managed and secured better on a dedicated, isolated server. By means of opening and closing the right ports, a connection can be made between the public server of the Drupal 8 website and the Solr server.

All other ports are closed using a firewall. You don’t need graphical interfaces, only an SSH access which is secured with keys. There is one GUI: that's Solr's. We blocked that with help of the firewall. You can also do this with help if Linux' IP tables. But make sure to add a service for this, or else you'll loose your security on reboot.

The capacity for the needed Solr server can be calculated, see here.

Install and configure Drupal Solr module

We installed the following modules:


  • Search Autocomplete - contrib module, this is used so that the search box in the frontend can also be used by the end user to search through Solr. This makes fuzzy search and instant search suggestions relatively easy. This doesn’t work out-of-the-box at the moment, that’s why we have written a custom code for it (see further down this blogpost).

Installation and configuration Drupal 8 connection with Solr

I’m not going to explain the installation of Solr itself in this blogpost, you can find instructions for that here.

1. Installation ‘Solarium’ library in Drupal 8

If you’ve installed the modules mentioned above, you first go to Reports -> Composer manager. There you will see the code that you have to fill in your terminal to install ‘Solarium’ lib.

As soon as you’ve gone through the ‘composer drupal-update’, Solr initially is ready in Drupalrootmap/vendor/solarium:

FYI: you can probably find the ‘Vendor’ file in your GIT ignore file.

2. Add Solr ‘server’ to Drupal 8

  • Go to Settings -> Search and metadata -> Search API.
  • Click Add server and configure the Solr server, an example of the local installation:

Most important settings:

  • Solr version (we use version 6)
  • Port
  • Host

Click ‘Save’ -> Now your Drupal 8 system has a Solr server connection, but isn’t doing anything at the moment.

3. Add ‘Index’

To actually get Drupal content indexed in Solr, you will have to make an ‘index’. Go to Settings -> Search and metadata -> Search API. Click on ‘Add index’:

After you’ve made an index, open it and click the tab ‘Fields’, afterwards click ‘Add Fields’:

Now you can configure the index:

This interface is still a little cumbersome, probably because the Drupal Solr module currently still is in beta1. For example, you can’t see which fields you’ve added to the index, so pay attention to not add the fields multiple times.

It’s a manual task, but it’s fine to do.

You can see the added Fields under the tab ‘Fields’:

4. Configure ‘Processors’

Click the tab ‘Processors’, here you can indicate under what conditions the Solr search has to be executed:

5. Let’s index

Your Drupal content should now be indexed in Solr at a Cron run, you can start this manually. You can see the status:

6. Frontend: queries and search results for end users

This is what it’s all about in the end, search results for the Drupal website visitor:

  • Super-fast
  • Most relevant results on top
  • Spelling mistakes, no problem

Think: Google for your own website ;)

The modules that are available for this don’t work good enough (yet) for our implementation. It didn’t seem to work with Views either, you can configure an ‘index View’, but that didn’t give any results.

Custom code seemed to be the best option at the moment; to get the global ‘Search autocomplete box’ to work as well.

>> Check the code on Github here >>

Explanation of some code snippets

For explanation: see code comments, herewith are some code snippets explained:

hook_page_attachments_alter is to solve the bug from Input field value is not sent with the AJAX request when using URL call back with custom view and exposed filter. The search autocomplete is only able to use contextual filters. With this hook, you can use your own filter (or set a default).

The LuciusSolrController is divided in:

__construct for making, there’s a @todo in here.

$config = \Drupal::config('search_api.server.solr');

This actually must not happen and has to come as a service. (because of dependency injection, which is missing for this part).


Different services are added here (injected in the container).


We build the custom search here, this function has a second $processing_callback which should be used for the autocomplete version, but which still has to be adjusted.


This is for the construction of the autocomplete results.


This would have to invoke the lucius_solr_autocomplete_doc_processing callback.


Function for downloading the solrConnector.


Function that the query fuzzy makes and cleans up using an xss filter. Probably other things have to be done here for contains etc. but for now fuzzy is sufficient. (Possibly contains has to be in the search).


This module is also still in beta, what means that it should be tested extensively, on speed, safety, stability and documentation.

I can imagine you have questions about it, let us know.

Frontend search results screenshots

Since the Drupal 8 data contains private data, we can’t show those results, instead here are a few simular screenshots from a Solr implementation in OpenLucius (a work management system contributed as a Drupal distribution).

Auto complete search box

Search results including in-document search

With help of Apache Tika to index attached document content (doc, xls, pdf, zip, etc):

FYI: Data collections in Solr

You can make data collections in Solr if you want to index more than one website or external data source or if you want to make them more searchable, then it’s good to do that in different data collections. Depending on your version of Solr, it’s also called:

  • Core (Solr v4)
  • Shard/collection (Solr v5)
  • Collection (Solr v6)

To summarize

Does your Drupal website contain a lot of content and documents? Solr helps big time. In Drupal 7, this integration already was very developed and relatively easy: no need for a custom code.

In Drupal 8, this implementation is also available in beta1, custom code is still needed to get the results as you like on the screen of the Drupal website visitor. I will not be surprised if you won’t need custom code anymore in a few months, because the Drupal community constantly works hard on the Solr modules.

Header image credit

Aug 22 2016
Aug 22

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Here’s what struck me last month about Drupal modules. This month I have chosen to focus on Drupal 8 as this is slowly becoming the go-to version - partly because many required modules have been migrated and grown up.

1. Require Login

Make sure all your visitors on your Drupal website are obligated to log in. Handy for a Drupal intranet or social communities. It is possible to exclude certain paths so that they are publicly available.


2. 403 to 404

Mini module that ensures you will get to see a page not found on an access denied page. This way others will not found out that this page is an administration page.

Global redirect contains a similar feature.

Comment from Adam Evertsson:

About 403 to 404, you write that Global Redirect has a similar feature. There isn't a Drupal 8 version, and that functionality has been included in the Redirect module, https://www.drupal.org/project/redirect


3. Block tabs

Add tabs in blocks in order to cluster information. Similar to the Quick Tabs module. But Quick Tabs has no version for Drupal 8. Furthermore Block Tabs is offering integration with the Drupal 8 API, plugin system, block, entity and config API. Add CSS yourself to adjust the tabs according to your house style.


4. ShareThis

Do you like to have social buttons so people can easily share pages on Facebook, Twitter and LinkedIn? Integrate the ShareThis social bookmarking service in your Drupal 8 website using this module to get you socialized in no time.


5. Page Load Progress

Some heavy activities in a Drupal website can take a few seconds. In these cases it is preferable to lock the screen to avoid impatient users clicking other features. You can show a throbber and thus lock the screen using this module.


6. Adminimal Admin Toolbar (Drupal 8)

The Drupal 8 admin toolbar is fine, but could be better. This version is inspired on the popular module Adminimal Administration Menu


7. Node Order

Manually organizing nodes within a given Drupal taxonomy term. By default Drupal is sorting on sticky and date created. Using this module you can determine the order yourself.


8. Mail system

This popular module is migrated to Drupal 8. This allows the administration of all kinds of actions related to sending an email from Drupal 8. For example:

  • Formatting of emails in HTML
  • Managing email per Drupal module
  • Templates for e-mails


9. Optimizely

Everybody should constantly be A/B testing for conversion optimization. Optimizely.com is such an A/B testing tool that integrates in your Drupal 8 website using this module.


10. Menu block

Drupal 8 has standard features to place menus via blocks in your website. But it misses some features that are complemented by this module:

  • Determine how many menu levels you want to show
  • Set initial menu level
  • Expand all Drupal menu items


11. Update External Links

Open external links in text automatically in a new window to avoid people navigating accidentally away from your Drupal 8 website. Similar to the modules External links and External New Tab


12. Pinterest Hover button

Simple module that let’s you show automatically a pin it button as soon as website visitors hover over an image. Now also available for Drupal 8.


13. Easy Social

Similar to the above mentioned ’ShareThis’: make it easy to share your Drupal 8 content on social media platforms such as Twitter, Facebook and LinkedIn. This module is not using an external service unlike ‘ShareThis’.


14. Chosen

Makes selecting items (f.e. Drupal taxonomy terms) easier for content managers in your Drupal system. Now available for Drupal 8.


Wrap up

OK, that’s it for now, stay tuned for more interesting Drupal stuff and next month again a cool Drupal modules update!

Credits header foto
Credits mail foto
Credits social foto

Jun 07 2016
Jun 07

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

In this blog serie I will explain how we have built a new multilingual Drupal 8 site. During the process the required HTML, CSS en Javascript was supplied statically and used to build a custom Drupal 8 theme. So we did not use a Drupal core or contrib theme.

We are talking about this website:

This Drupal 8 website consists of pages that are built up from Drupal blocks. Therefore I will explain in detail how we have built these blocks. Furthermore this Drupal 8 website is multilingual: Dutch and English. As listed below I will explain:

  1. Generic structure of a Drupal 8 theme
  2. Initiation Drupal 8 theme and placing supplied assets: CSS, JS, fonts and images.
  3. Breaking down supplied HTML into Twig template files (.html.twig files).
  4. Determination of the Drupal regions.
  5. Building homepage HTML using blocks, and Drupal and Twig template files.
  6. Building contact page using blocks and Drupal 8 core contact form.
  7. Building other pages using Drupal 8 blocks.

Basic knowledge

I assume you already have some experience with Drupal:

  • Installation and general configuration of the Drupal 8 core, modules and themes.
  • Configuration of content types

Drupal 8 theme | The structure

What is a Drupal 8 theme

A theme is a collection of files that determine the look of your Drupal website: what the visitor sees. Only 1 file is required, the .info.yml, but for a complete theme more files are needed.

Drupal 8 uses by default PHP templating engine Twig, part of the Symfony framework where Drupal 8 is built on.

Where do you insert the theme

When creating a custom theme, this is inserted in the /themes folder. Be sure to put the Drupal core themes in the folder /core/themes. Never ever do you put your own theme there, that would be a core-hack: a crying shame.

To keep your themes folder organized, it is a best practice to divide them in the folders:

  • /contrib: place here all themes downloaded from Drupal.org
  • /custom: place here all themes that you are building yourself.

Each individual theme is inserted in a folder with the name of the concerning theme. That name can only contain lowercase letters, must start with a letter and use underscores (_) instead of spaces.

The (partial) structure for our installation will look like this:

| |-modules
| |-themes
| | |-bartik
| | |-seven
| |-contrib
| |-custom
| | |-openlucius

Which files are part of a Drupal 8 theme

As indicated, a useful theme will contain more files then just the mandatory THEMENAME.info.yml.

About .yml files

Yaml (.yml) files are files intended for data and not for markup. These are not necessarily Drupal 8 specific files: they are also used in other programming languages such as C, Perl and Python. Within Drupal 8 they are mainly used to include definition and configuration; part of the Configuration Management Initiative

A Drupal 8 theme has the following structure:

| |-install
| | |-THEMENAME.settings.yml
| |-schema
| | |-THEMENAME.schema.yml
| |-style.css
| |-background_frontpage_header.png
| |-maintenance-page.html.twig
| |-node.html.twig


This is the only mandatory file of the theme, that defines the theme and that is recognized by Drupal 8. Extra ‘meta data’ is also placed here, such as:

  • description: short description of the theme.
  • libraries: which libraries are where.
  • block regions: defined regions, see below for more info.
  • overrides: which Drupal 8 core services do you want to override and where are these overrides.


Defines the Javascript and CSS libraries used by the Drupal 8 theme.


Contains PHP code where preparatory logics can be programmed: (pre)processing of the HTML output.


Breakpoints are points on which a responsive webdesign should change to be displayed properly across devices. These breakpoints can be defined here.


The template files implement the HTML code for your Drupal 8 website. Drupal 8 template files have format THEMENAME.html.twig and must be placed in this subfolder (unlike Drupal 7).

The Drupal 8 core provides a number of template files. If you maintain certain naming conventions for template files in your own theme, then Drupal will automatically use your templates instead of the core templates. Allowing you to override the HTML markup.

Place for example the file node.html.twig in this folder and Drupal will use your version instead of the core version: /core/modules/node/templates/node.html.twig


It is a best practice to place .css files in the subfolder /css. Drupal 8 core themes structure CSS files in accordance with the SMACCS style guide. CSS files should be defined in the .libraries.yml file and can be override or disabled in the .info.yml file.


This folder contains the Javascript files of the Drupal 8 theme. To load them, they should also be defined in the .libraries.yml file.


It is a best practice to place theme image in this subfolder. Don’t confuse it with content images.


When you insert this image, then it will appear on the Appearance backend page in Drupal 8. The location of screenshot.png could be placed somewhere else; that alternative location should then be defined in the .info.yml file.


The logo of your website, that is usually shown in the header to your visitors. This logo can also be uploaded in the Drupal 8 backend under Appearance > Settings


Within Drupal 8 it is also possible to work with base-themes and sub-themes. Subthemes are just like other themes with the difference that they inherit resources from the base-theme. It is even possible to create sub-sub-themes and sub-sub-sub-themes (and so on).

In this tutorial I will not discuss sub-theming in Drupal 8 any further.

Drupal 8 theme structure | Regions

As the word implies: a region is a certain region in your Drupal 8 website, which is used to place content. More detailed: this content is added in blocks, that are placed in regions. A block can be seen as a building block; regions give your Drupal 8 website the layout to place your blocks (meaning the content).

Regions are defined in the theme in the .info.yml file

Drupal 8 core regions

Drupal 8 knows the following standard regions:

  • page.header: Items for the header region.
  • page.primary_menu: Items for the primary menu region.
  • page.secondary_menu: Items for the secondary menu region.
  • page.highlighted: Items for the highlighted content region.
  • page.help: Dynamic help text, used mainly for admin pages.
  • page.content: The ‘main content’ of the current page.
  • page.sidebar_first: Items for the ‘first sidebar’.
  • page.sidebar_second: Items for the ‘second sidebar’.
  • page.footer: Items for the ‘footer region’.
  • page.breadcrumb: Items for the ‘breadcrumb region’.

If your custom theme does not define regions, then you will have these at your disposal.

Hidden regions

When you go deeper into Drupal 8 theming, then you will also get to see these regions:

  • page_top
  • page_bottom

These are hidden regions and can be seen in html.html.twig, a template file that is usually not overridden in a custom theme. These regions are used to place HTML entirely at the beginning or the end of the page, for example:

More info about regions

Can be found here.

Drupal 8 theme structure | Template files

Template files contain the HTML that is eventually sent to the browser of your website visitor. These are all files with extension .html.twig. If you look at the template files of the Drupal 8 core theme ‘Bartik‘, you will see the following:

These files all follow a by Drupal 8 determined naming convention so that Drupal knows which template file to use for what. This can range from an entire page, to theming a block, to theming one small select element. In fact, all html generated (or additionally required) by Drupal core can be changed to custom HTML. Creating a theme with supplied, so 100% custom, HTML is therefore possible.

The template files are divided into:

  • HTML for the header
  • HTML for the page
  • HTML for regions
  • HTML for blocks
  • HTML for nodes
  • HTML for taxonomy terms
  • HTML for fields
  • HTML for comments
  • HTML for maintenance page
  • HTML for search results

As an example, these are the naming conventions for the node template files:

  1. node--nodeid--viewmode.html.twig
  2. node--nodeid.html.twig
  3. node--type--viewmode.html.twig
  4. node--type.html.twig
  5. node--viewmode.html.twig
  6. node.html.twig

Per page Drupal will run this list from top to down, the file that is first defined in the theme, will be applied by Drupal to the appropriate item.

See here an overview of all template naming conventions.

In case this should all be a little too abstract, don’t worry: in the actual implementation that is discussed further down in this blog, everything will become clear.

Implementation custom Drupal 8 theme | Initiation

Installation Drupal 8

We are starting with a new Drupal installation. Download and install Drupal 8 from this page, or install via the Drupal console with site:new.

Initiation Drupal 8 theme

In the initiation phase the following theme structure was made: the required folders and files were placed in drupal8 root/themes/custom/

| |-base
| | |- css files
| |-components
| | |- css files
| |- mobile-overrides.css
| |- overrides.css
| |- font files
| |-backgrounds
| | |- images
| |-flags
| | |- images
| |-glyphicons
| | |- images
| |-gradients
| | |- images
| |-base
| | |- javascript-files
| |-components
| | |- javascript-files
| |-block.html.twig
| |-block--system-branding.html.twig
| |-block--system-menu-block.html.twig
| |-node.html.twig
| |-page.html.twig
| |-page-title.html.twig
| |-region--header.html.twig
| |-status-messages.html.twig

Inserting supplied assets of the theme

All supplied assets of the theme are divided into the following folders:

  • /css
  • /javascript
  • /images
  • /fonts


All CSS and JS files need to be recognized by Drupal, this is done in openlucius.libraries.yml, with us this is looking as follows:


Additional logics that is required before rendering the HTML, will be placed here.

Not implemented: openlucius.breakpoints.yml

We did not use this file, as necessary breakpoints have already been supplied to the implemented static HTML/CSS.

Enable the Drupal theme

In the Drupal 8 backend go to ‘Appearence’ and click ‘install and set as default’ at the new custom theme.

Theme initiation done

The Drupal 8 theme is now initiated, but at the moment only an ‘empty’ page can be seen. In the following blogs I will fill the page by inserting the HTML through blocks.

Jun 01 2016
Jun 01

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Blockchain right now is like the web in 1994. It will revolutionize our world and way of working together.

Want to know more? Please visit our event:

  • Date: Wednesday 6 July 2016
  • Location: WeWork Metropool - Weesperstraat 61, Amsterdam
  • Free entrance



18:00u Doors open

18:15u Why bother about blockchain? - Henk van Cann

What is it, how it is used best and why anyone should get into blockchain technology. Henk will give his insights on how the blockchain works and what it can do for you. He will examine and explain the blockchains that dominate much of the crossover space from crypto-currency, e-identity to blockchain technology:

Bitcoin, Ethereum, NXT and Hyperledger.

He will also show how to judge what is true and false in the increasingly hyped news and opinions about the benefits of blockchain.
In addition, Van Cann will give examples of how this technology is going to change your work and life. It is an interactive session.

Bio Henk van Cann

In recent years Henk van Cann (@henkvancann) has been gathering knowledge and contacts within the blockchain technology field, focussing on applications for e-identity issues (your digital ‘me’).

Van Cann will share his experiences from a number of recent conferences he attended on the subject of blockchain and e-Identity: Consensys May 2016 conference, Dutch Blockchain June 2016 Conference, Conference e-Identity and doing business digitally, June 2016.

19:15u Break

19:30u What you can learn from Blockchains in Work management systems like OpenLucius - Joris Snoek

Aimed at small & medium sized organisations OpenLucius connects to Bitcoin, Ethereum, NXT and Hyperledger. Joris (@joris_lucius) wil address the three main problems blockchain can solve that could not be solved before for users of OpenLucius. These principles are general tough, every visitor could apply them on his/hers own situation in (working) life.
Briefly Snoek demonstrates the functions that aim to solve these problems within OpenLucius. A discussion about where to take OpenLucius from here could follow and Joris is open to that.

Bio Joris Snoek

Joris Snoek is an experienced online entrepreneur since 2004 and director with a passion for online collaboration in social intranets founder and CEO of OpenLucius: "I love to work on improving teamwork and finding new ways to collaborate more effective together via social intranets. Always thinking of better ways to organize and motivate staff to get the maximum results and help them to reach their personal and business goals.

20:30u End


May 27 2016
May 27

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Last Thursday I had the honour to speak about Headless Drupal on a sold out Drupaljam. See the slides of my presentation at the bottom of this blog.

First I would like to thank the stichting Drupal Nederland for the invitation and their hard work which resulted in a very successful Drupaljam this year.

Many interesting talks were planned in at the same time. In total 20 sessions, including the keynotes. I was able to be present at the keynote of Boris (‘The next web’) van Zanten, cool anecdotes about his companies:

Source image

Also Iskander Smit had interesting things to say about the latest IoT developments:

I am now also completely up to date with PHP-FIG, thanks to the interesting talk from Bart Feenstra 'how the PHP world got off their islands':

Source image

My Headless Drupal session

The preparation of my headless Drupal talk did not take place without a few setbacks. After a rehearsal presentation to my colleagues I found out too late that my session was not running smoothly at all. So I practised and adjusted until the wee hours of the night.

Usually I am not nervous for presentations, but the rehearsals did not go well. So at the beginning of the session my heart was pounding in my throat; especially when it became clear that there was a lot of interest for decoupled Drupal. After 5 minutes the nerves were gone and my Headless Drupal session went according to plan:

A little headless myself

Unfortunately I slept too little and became a little headless myself. The preparation was taking its toll; I went home around 3 p.m. to catch up some sleep.

Unfortunately I could not experience the rest of the day, since I postponed the preparation and rehearsal of my talk for too long. I was absolutely not reluctant, but postponed it constantly.
And somehow work for clients always seem to have the priority :). How could I have prevented this:

My Headless Drupal presentation

Below the presentation of my Drupal session: 'Headless Drupal - What, Why, How, Challenges & examples' (View on Slideshare):

Did you visit Drupaljam?

Let me know your thoughts. And when you are clicking anyway, check here to see if you were spotted.

Wrap up

Next year for sure a successful Drupaljam, see you then!

May 13 2016
May 13

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Drush, the must-have toolkit for every Drupal developer. Installing Drush is not a problem when working via Composer. However, as with most of the applications that are dependent on other applications it can go wrong. Especially after upgrading your system or upgrading your MAMP / AMPPS / XAMPP / ... stack.

Drush depends on a number of smaller applications: PHP, MYSQL and of course Drush itself. As soon as it goes wrong, most of the developers (at least I hope) are searching through Google for a solution to the problem.

Common messages include:

  • "No Drupal site found, only 'Drush' cache was cleared."
  • "Drush was not able to start (bootstrap) the Drupal database."

These messages can even occur when working from the root of the Drupal environment.

  1. Why is this happening?
  2. And which solution is the right one?

1. Why is this happening?

The user can receive both messages when data in settings.php is not yet properly filled in.
This is also the most common message that you may receive with Drush when it goes wrong out of the box. The reason is that the wrong PHP or MySQL is called. (Usually MySQL).

You can find some solutions when entering the error messages in Google:

  • Changing the word localhost in the settings.php to
  • Creating a symbolic link from the path to your mysql.sock to /var/mysql/mysql.sock
  • Some are even giving the advice to use Drush 6.0.

Almost all the tips that are given are dependent on the situation and don’t work for everyone. The most important thing for Drush is that the right MySQL and PHP are configured:

Configure the correct MySQL and PHP version

On OSX the PHP is by default called from the following path: /usr/bin/php
This can be checked quite quickly by typing which php on a command line:

Usually this is not the PHP from the stack that you use for your Drupal install.

You can quickly check this by comparing the version number with the PHP version that you are using for Drupal. The chance that the PHP version of your OS is equal to your stack is quite small. Type php -v in the terminal and PHP will give you the version number.

2. Which solution is right?

You can use a bash_profile to make sure that every instance of the terminal is using the same versions of PHP and MySQL. This is a hidden file in the /~ path or the home directory. Here we specify which PHP / MySQL and Drush we will give to the bash profile.

Looking up the paths to use.

The paths used are dependent on the stack you are using. As an example I am using AMPPS. XAMPP and MAMP are using similar paths.


First of all it is useful to discover the Drush path. If you have used the instructions from docs.drush.org, then this will be "/usr/local/bin/drush". To be sure you can type which drush in the terminal.

If this does not result in a path, then I advise you to check the instructions from Drush.org


After we have found Drush it is time for PHP. Most apache stacks contain more than one PHP version. Once you change your PHP version, some stacks automatically change a symbolic link to the folder with the active version.

Because this is not happening with every stack, I am using a variable for the folder name of PHP.

Here you will put the name of the folder containing the PHP version which you are using for the Drupal install. To check if this is the case, you can type ls -la in the terminal within the application folder of your stack. (As shown in the screenshot).

The directory of PHP within AMPPS is /Applications/AMPPS/"PHPVERSION"/bin in my case "php-5.6" which changes the full path to: "/Applications/AMPPS/php-5.6/bin".


Finally we need the MySQL. Also this is dependent on the stack being used.
For AMPPS this is "/Applications/AMPPS/mysql/bin". (See previous screenshot)

Creating the bash profile

We will add the three paths found in the previous step to the bash profile of OSX.

The bash profile is a file that can add applications to the path variable of OSX.

We will use a text editor to modify the .bash_profile in the home directory.

The home directory is easily accessible by typing cd ~ in the terminal. Depending on the settings of the terminal it can also be sufficient to open a new screen.

By default, the home directory is open when you open a new instance of the terminal.

From the home directory we will edit/create the .bash_profile with a random text editor.
I am using Nano, other people will use Vim or TextEdit. For Nano you only need to enter 'nano', followed by the file name (in the terminal): nano .bash_profile.

In this file, we will add our paths to the $PATH variable. As example for simply changing PHP versions I have added the name of this folder as a separate variable.

To do this, enter the following:

export PHP_ID="php-5.6"

Where “php-5.6” is the name of the folder. Then you can use PHP_ID in the remainder of the profile.

Next we will add all paths to the Path variable:

export PATH="/Applications/AMPPS/$PHP_ID/bin:/Applications/AMPPS/mysql/bin:/usr/local/bin/drush:$PATH"

If everything went well, you have now added/created two lines to the profile.

To write to the profile, you will use CTRL + O followed by CTRL + X to close nano.

You will now get a warning if you want to write, press enter to confirm.
When you receive a permission denied then it is possible that you need sudo rights to write to/create this file.

Enter sudo su - followed by the admin password and execute the steps again.
Once the lines have been added and saved, all the open terminals need to be closed (or refresh source .bash_profile in.)

If everything went well, you can now use Drush again, congratulations :)

Credits header foto

Apr 22 2016
Apr 22

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Let’s start straight away with the things that struck me about Drupal module updates of last month:

1. Image effects

The Drupal 8 and Drupal 7 core both have features to facilitate graphics, including scaling and cropping.

To perform other actions, Drupal 7 had additional modules: ImageCache Actions and Textimage:

  • Placing overlays, for example for round corners
  • Adding a watermark, for example your logo
  • Placing text over image, for example your company name
  • Making images lighter/darker

In Drupal 8 these additional image features are now available in this module.


2. Currently logged in users

Provides a list of logged in visitors with additional information, such as:

  • Since when logged in
  • Hostname
  • IP address

You can also force users to log out when you are a site admin.


3. Drop down login

Create space on your page and place the login block under a dropdown button.


4. Views Send

Do you want to send a bulk email to a selection of users in your Drupal website? For example to inform them about an update? Through this module you can use Views to make a selection and then use fields from that selection to send personal bulk emails.


5. Google Analytics Reports

Provides a graphic report of page visits to your Drupal website using data from Google analytics. Has been around since 2011, but just had a stable 3.0 release.


6. Quick tabs

Simple, but effective and popular to create tabs in content on your Drupal website.


7. Bootstrap Site Alert

Are you running a Drupal theme on the Bootstrap HTML framework? Great! Then you can now easily display a message at the top of your website - through this module. For example to inform users about upcoming maintenance or a performed update.


8. Code filter

An alternative for the Geshi module: gives the correct highlighting to code in your Drupal content.


9. AJAX Comments

By default Drupal has a good system for comments/responses, but when someone is giving a response (for example to a news item) then the page will always load again. The response is not instantly placed underneath the item, like for example Facebook is doing.

This module ensures a response will be placed without refreshing the page.


10. User IP log

Convenient administration module that stores IP’s from logged in Drupal users. This let’s you analyze if there is suspicious activity.


11. Views Accordion

Simple but popular module, similar to the above mentioned ‘Quick tabs’: this makes an accordion of Views results.


Mar 31 2016
Mar 31

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Probably you have heard about this before: ‘Two-factor authentication’. When you are a frequent user of Facebook, Twitter or LinkedIn you have quite likely seen it before; for sure you have been asked to provide your telephone number.

At first I was reluctant because then ‘they’ know all about you. But in the course of the time social media accounts have become very important, you don’t want a stranger to be able to hack into your account and steal your identity on Facebook, Twitter or LinkedIn.

Hence, I have now entered my phone number on these three social media. If I want to change my password, I will need to confirm this now through a verification code that is sent to my telephone number. A person with malicious intent usually does not know your number, so chances of hacking your account – by guessing and then changing your password – will be minimized.

Two-factor authentication of for example Facebook

This kind of extra security is called ‘two-step authentication’ / ‘two-factor authentication’. To take the example of Facebook: when logging in, the standard verification exists out of a username and password, something you ‘know’. The second step is authentication with something you ‘have’, such as a Smartphone, a fingerprint scanner, or a bank card reader.

This should not only be used to change passwords, but can also be used as an additional security when logging in to your social intranet:

  1. Enter your username and password
  2. The social intranet sends a sms with a verification code to your phone
  3. Enter the verification code in the social intranet
  4. And you are logged in

Drupal social intranet?

Are you using a social intranet built on Drupal? Then there is a module available for this: Two-factor Authentication- TFA. This module facilitates the basis for two-factor authentication in Drupal:

  • Choose the solution, such as time-based one-time passwords.
  • Sms verification codes.
  • Pre-generated codes.
  • Integration with external services, such as Authy of Duo.

Other features of the module:

  • Pluggable: supports multiple ways of two-factor verification and can work simultaneously with multiple external services
  • Adjustable: supports fallback methods and context dependent exceptions
  • Supports ‘flood control’ for brute force attacks
  • Well tested module
  • Sensitive data for this authentication is stored encrypted using the PHP extension mcrypt.

For example: install two-factor authentication in Drupal social intranet OpenLucius

To start, install the following modules in OpenLucius:

  1. Two-factor Authentication (TFA): the basic module containing only an API
  2. TFA Basic plugins: basic TFA plugins containing the following components:
  • SMS: serving a verification sms via external service Twilio.
  • TOTP: a “Time-based one-time password plugin”, uses PHP_Gansta\GoogleAuthenticator PHP library.
  • Trusted device: a plugin ensuring that a logged in browser is characterized as ‘trusted’, so the next time it is not required to login via two-steps, but only one-step: entering your username and password.

1. Configure the two-factor authentication

In this example I am using TOTP, because it is for free. As mentioned previously you can also build in sms verification, but then you will have to purchase an external paid service.
Once you have installed the module go to /admin/config/people/tfa:

  1. Enable two-factor authentication
  2. I am selecting TOTP as the standard. A solution that does not require integration of external paid services.
  3. Set ‘recovery codes’ as fallback.
  4. Activate ‘Trusted Browsers’, after logging in once via a certain browser with two-factor authentication you can then log in through this browser via one-step: username and password.
  5. Users with these roles are required to activate two-factor authentication. I have activated all the roles.

2. Activate two-factor authentication for a user

Install Google Authenticator on your Smartphone

To use this TOTP you can use the free app from Google: Google Authenticator. Download and install it on your Smartphone.

3. Configure a new user:

  • Add a user.
  • Navigate to that user and click the tab ‘security’, then click ‘set up application’. The following screen appears:

  • Go to your Google Authenticator app and select ‘scan barcode’:

  • Scan the barcode with your Smartphone camera to receive a verification code, enter it.
  • At the next screen ‘recovery codes’ select for now ‘skip’.
  • You have now set your two-factor authentication:

4. Logging in with two-factor authentication

Once I log in with the recently set up account, an additional verification code will be requested that I can read from my Smartphone:

Enter it and that’s it! Now you have established two-factor verification:

  1. Enter something you ‘know’: username and password
  2. Enter something you ‘have’: a code from your Smartphone.

Resulting in an additional optimization in the security of your social intranet.

Related modules

Mar 22 2016
Mar 22

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

The Drupal Insert module is a convenient module to easily place images in content, without hassling around with a WYSIWYG editor. It is rightly a popular Drupal module (nearly 80,000 active installs). We are also using it in our blogs; in combination with Markdown you can easily and quickly format content.

How Insert works in a nutshell:

  1. Upload an image in an Image field, select the desired image style and click ‘Insert’.
  2. The required tag is automatically inserted in the place of the cursor in the text.

Now you don’t need to fiddle around anymore with WYSIWYG editors that most of the time don’t do what you want anyway. Also useful is that the Insert module can scale images automatically in accordance with a defined image style in Drupal.

Quality images not optimal

The only problem is that the images are not looking good. The quality of the scaled images can be set in Drupal (Administration > Configuration > Media > Image toolkit), but I noticed they are never really good enough. Also because you have to deal with many different kinds and sizes of screens of visitors: you would like everybody to see a nice image (mobile, tablet, desktop, retina etc).

Solution for better quality images

This can be solved as follows: don't use an Image preset, but let Insert place the original image. Then make sure a css class is automatically given, which ensures the responsiveness of the image – this class is depending on the css you use. In our case this is ‘img-responsive’, since we are using the bootstrap html framework.

The Insert module setting of the relevant Image field will look like this:

(In our case it is under the link /admin/structure/types/manage/blog/fields/field_blog_images)

Directly place the original image, but make sure you upload an optimal quality/file size. A too large file is not beneficial to your Drupal SEO. First, I always resize the image in Photoshop to a maximum of 1280 px wide, as to be prepared for large and high resolution screens in future.

This will lead to an image that scales with all screens and that is nicely displayed.


Look at the difference in quality of images between this blog and the Dutch translation hereof. The difference is clearly visible in the image under ‘3. Group activity stream’.

Wrap up

That’s all folks, questions or feedback? Let me know.

Credits header photo: Andrew Coelho

Mar 19 2016
Mar 19

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Below you will find the module updates that catched my attention last month:

1. Security Kit

In this Drupal module a set of actions is taken against common security issues:

  • Cross site scripting
  • Cross site request forgery
  • Clickjacking


2. Similar by terms

Imagine, you want to show the visitors of your Drupal website a block containing relevant related content. You can do this yourself using Views - like we have done below. But this module provides this ready-made. The related content is displayed based on ‘the same terms’ and their quantity.


3. Content locking (anti competitor editing)

You don’t want different content managers in your Drupal website overwriting each other's changes when they are simultaneously modifying the same item. Within Drupal that is by default not possible, but in an inconvenient way: you only receive a notification when someone else has edited the content item as soon as you click 'save'. And then you have already put all your energy into your changes.

This module solves that and immediately notifies you when clicking on 'edit'.


4. Fast permissions administration

Drupal’s permission table is out of the box already quite big. When you are installing a number of modules, and programming some custom permissions, then it quickly becomes cluttered. This module is solving this problem: it clusters per module and provides a convenient filter function.


5. SideComments now

Responding to a specific piece of text in a blog, popular on Medium. And rightly so, it is convenient: immediately respond in the proper context.
The reaction is then not put under the text, but to the side of a section.


6. Responsive and off-canvas menu

Offer your mobile website visitors a useful navigation. One that is not in the way when you don’t need it (‘off canvas’).


7. Bulk Delete

Removal of many nodes at once, like more than 10,000, Drupal core does not provide this. This module is solving that problem. But take care, this module removes everything permanently; ensure backups and pay enough attention to your actions.


8. Search Index Wipe

The standard 'Re-index site (admin/config/search/settings) button from the Drupal Search does not empty the entire directory at once, but gradually replaces existing items with new ones.
If you run a Drupal website with lots of content and want to completely rebuild the search index, this will be difficult.
This module is solving that problem: it adds a ‘Wipe Index' button, which deletes all indexed content entirely and therefore existing content will be fully indexed again.
Mainly useful if you are executing a deploy, for example from a new version of the website.


9. Mail safety

If you are engaged in developing for example a Drupal social intranet, you don’t want users to (accidentally) receive test emails. This module ensures that all outgoing emails are 'captured' and collected on a dashboard.
Similar to Mail logger and Reroute email


10. OpenLucius News

Our module received an update. It is made compatible with the latest version of Drupal social intranet OpenLucius. Some new features have been added and bugs are fixed.


11. PatchInfo

In some cases you will need to apply patches for existing modules:

  • to hotfix a bug
  • to modify a feature according to your requirements

When patching, you will need to document this properly in your Drupal system. Otherwise you will overwrite your patch at the next update. You probably guessed it already: this module is helping you with that.


12. Chosen

Makes selecting items (for example Drupal taxonomy terms) a lot easier for content managers in your Drupal system.


13. Pinterest hover button

Pinterest is quickly gaining ground and you might like to capitalize on this. This simple module allows your visitors to see a 'Pin it' button as soon as they ‘hover’ over a picture. Via this button they can then add your image to their pinboards.


14. Range

Offers a combined field in which content managers can enter multiple numbers: a set of numbers. For example: ‘year -> to’. Specific input can be enforced, for example:

  • Minimum and maximum values
  • Precision and scale

Then you can show that set of numbers in various ways to site visitors, for example:

  • With a set division sign
  • Set prefixes and suffixes
  • Decimals and thousands: automatic commas and full stops


15. Retina images

Provides content managers with an additional field for each Image Upload for Retina appropriate images, high resolution images that look beautiful on a Retina display.
These retinal images are typically much larger in file size and therefore a shame to serve out, since a great deal of the screens are non-retina. A larger file means more download time and thus a relatively slower site.
Here you will find additional information.


16. Accelerated mobile pages (AMP)

AMP is an open source project from Google that aims for an optimal reading experience on mobile websites. It provides a front-end (HTML/CSS/JS) framework which facilitates this. This module converts Drupal pages to ‘AMP HTML’. Currently it only supports nodes, but later that will be more. There is already a Drupal 8 beta2 release, but currently they are working on a Drupal 7 release.

[embedded content]

Lullabot produced this module and wrote blogs about it.


Wrap up

Ok, that’s it. Next month again a Drupal modules update.

Mar 16 2016
Mar 16

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Every now and then you come across a module you wished you saw before. And I wonder why we did not discover this one earlier: WYSIWYG Filter. It even exists since Drupal 6.

WYSIWYG Filter is solving the following problem:

After installing the Wysiwyg module – and when you are using for example TinyMCE as editor – desired buttons can be configured under /admin/config/content/wysiwyg/profile/

This will offer you a text editor and will avoid content managers having to write HTML code:

(Screenshot from Drupal intranet OpenLucius)

To make sure this HTML is shown in the frontend (for visitors) you will need to allow these elements. This can be set under ‘text formats’ (/admin/config/content/formats). In a default Drupal installation it is needed to enable the following filter (to protect your Drupal against unsafe and unwanted html/js): ‘Limit allowed HTML tags’. Then you will need to specify the allowed elements:

The problem now is that everything will be stripped, except what is standing here. So also the required HTML attributes and properties. Like for example inline styles to line out text and apply colour, but also required id’s and classes. After installation of the module this problem will be solved, as it is offering the right configuration tools and therefore allowing elements, attributes and properties required by you for Drupal site visitors:

A detailed screenshot can be found here and is also showing that whitelists can be added for required allowed:

  • classes
  • element id’s
  • URL’s with inline styles
  • domains

The module can also, for example, automatically place rel="nofollow" based on your settings. This way the content flow will be build in a comprehensive manner for search engines which is great for your Drupal SEO.

Integrated default safety

HTML attributes related to the DOM events (on*) are not permitted for safety reasons (e.g. to prevent XSS). Also, the following elements are not allowed for safety reasons: applet, area, base, basefont, body, button, embed, form, frame, frameset, head, html, iframe, input, isindex, label, link, map, meta, noframes, noscript, object, optgroup, option, param, script, select, style, textarea, title.

Wrap up

De module is included in the Drupal 8 core, but since Drupal 7 will stay around a little while longer it seemed a good idea to share some knowledge about this Drupal module. Questions or feedback? Let me know!

Header photo credit: Karl Fredrickson

Feb 25 2016
Feb 25

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

A Drupal intranet is a closed, internal system. The privacy sensitive content is only visible after logging in. But in a standard Drupal installation the login page of your intranet will be indexed by Google. You would rather not see this happening, because even though people cannot log in you are still giving a large part of your security away. Namely: the location of your Drupal intranet.

And Google is smart, very smart, and is only getting smarter; there is a big chance that your intranet will be found and thus seen when somebody is searching for the keywords ‘your company’ and ‘intranet’. This will enable people to find the login link of your intranet via Google.

Make your Drupal intranet invisible for Google:

1. Install module Robots.txt

Install the module Robots.txt in your Drupal intranet.

2. Remove the standard robots.txt from your Drupal installation:

!) Please note, this is a Drupal core hack and should be avoided. But in this case there is no other option. Document this carefully using a patch for future updates.

3. Configure your new robots.txt via the module:

Go to /admin/config/search/robotstxt and enter the following:

To clarify, delete everything under the commentaries and enter:

User-agent: *
Disallow: /
Noindex: /

4. Add meta tag

A good additional measure is to include the following meta tag on the login page:
meta name="robots" content="noindex"

Can your Drupal intranet already be found in Google?

First apply the above module to avoid to be indexed again after the following action via the Google Search console (Webmaster tools):

When your Drupal intranet is not registered yet, you will need to do this first via a short verification process. This process is starting with the registration in the search console.

Once you have completed this process and have logged into the Search console:

  1. Go to ‘Google index’ -> ‘Remove URL’.
  2. Click ‘Temporary hide’.
  3. Enter the URL of your Drupal intranet.

This is temporary. If you want to remove it permanently you will need to do this via robot.txt and meta tags as described above. See this Google guide for more information.

Wrap up

That’s it. Questions? Let me know!

Find more info on robots.txt here.

Feb 16 2016
Feb 16

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Let’s get straight to the point:

1. Infinite scroll

On many websites we are currently seeing ‘infinite scroll’ instead of page numbers. For sure you know how it works: at the bottom of a list with items (f.e. an activity stream) 20 new items are automatically loaded.

This module implements a ‘jQuery auto-pager plugin’ that provides the above functionality. It is possible to configure:

  • on which page it is active;
  • a ‘load more’ button or automatically loading new items.

Infinite scroll
Drupal 7

2. OpenLucius Inline Images

This module provides Drupal distribution OpenLucius to add images to text.
The image is well protected as well: only users in the relevant (work)group can view images and directly request them via url – users that are not a member of the group cannot.

The Drupal Grants system is respected, something that all other ‘image managers’ are lacking; that’s why we decided to ‘scratch our own itch.

OpenLucius inline images
Drupal 7

3. Simple social icons

Social icons are omnipresent on webpages. It is a direct integral connection to your online presence. This module provides an easy way to place the icons and display personal colors. Furthermore, this module implements 2 blocks:

  1. ‘Share’ (parts) of a page.
  2. ‘Follow’ for example your Twitter account or Facebook page.

Social icons
Drupal 8 alpha

4. Secure Login

Safely sending data over the internet will be standard in the near future. Search engines like Google will probably better evaluate protected websites.

This module facilitates sending and receiving encrypted data via https. For example, data from forms and passwords. It also forces safely sending cookies to prevent session hijacking.

Secure Login
Drupal 7 & Drupal 8


If you want to be informed about changes in an article or the posted comments, then this module can help. It makes sure that visitors of your Drupal website can ‘watch’ (follow) nodes and comments, also without posting a comment themselves. Some features:

  • Email notifications can be set per node.
  • Usable for both anonymous and registered visitors.
  • Configurable email templates.
  • Visitors can receive an overview of everything they are ‘watching’ (following).

Drupal 7

6. Colorbox (Drupal 8 release)

Colorbox is a jQuery plugin, mainly used to display images in a pop-up slideshow. This module implements Colorbox in Drupal and has been popular since Drupal 6; the Drupal 8 version has been released yesterday.

Drupal 7 & Drupal 8

7. Markdown (Drupal 8 Release)

Markdown, for me an indispensible tool when writing content. You don’t want to fiddle around with a WYSIWYG editor but you do want to format text quickly and easy? Markdown. Now also available in Drupal 8. Nice!

Drupal 7 & Drupal 8

8. Isotope (with Masonry)

‘Filter & sort magical layouts’ is the tagline of Isotope, a javascript library which is beautifully aligning blocks on your webpages, on every device and screen.

This module can be integrated with Drupal Views, so you can align simple selections of content by Isotope – without having to integrate the javascript in your Drupal system. But Views is not necessary, you can also use it in your own theme features.

Drupal 7

Hi! Wij zijn Lucius: een getalenteerde club van Drupal open source professionals.

Bel ons op 020 - 261 14 99, mail ons op [email protected], of stuur een bericht via ons contactformulier.

9. Toolbar Menu

Some admin pages are visited often and you want to reach at once. This module helps configure which items are displayed in the main menu.

Toolbar menu
Drupal 8

10. Focal Point

Drupal can automatically crop images so they are always beautifully aligned for your visitors. But it can happen that Drupal cuts important pieces of an image.

This module provides a solution for this: you select a ‘focal point’ in the image so Drupal knows the key point in the image. When the image is automatically cropped this point will be considered key and will not be cut out.

Focal point
Drupal 7 & Drupal 8 dev

11. Node-level Blocks

By default it is possible to place a Drupal block on certain pages based on content type or specific paths and nodes. But you can always select just one region (position) on the page (f.e. left sidebar). This module allows you to determine per node in which region the block should be placed.

Also see this blog by Deeson

Node level blocks
Drupal 7

12. Simple hierarchical select

If you have a lot of vocabularies and terms that are hierarchically (nested) structured then it can sometimes be a challenge to find the right one when adding content. This module solves this problem by displaying the hierarchy in various drop down boxes so you can find the right term more quickly.

Simple hierarchical select
Drupal 7 & Drupal 8 alpha

13. Computed Field

Provides a field (Drupal Field) where you can define certain logics (via PHP) such as calculations on users/node data or values from other imported fields. You can find some code snippets here as an example.

Note that this code will be placed in the database, and not in GIT. Bugtracking is therefore also more difficult and ‘Pareviewing’ of the code is not taken into account. This module is not recommended when you are working in a team of developers on a Drupal System.

Computed Field
Drupal 7 & Drupal 8

14. Custom Publishing Options

Sometimes you are in need of additional ‘publishing options’ with a node, like ‘archive’ or ‘featured’. Through this module they can be configured and used in Views.

Custom Publishing Options
Drupal 7

15. Override Node Options

In some cases you want content managers to only enter a title and description, but not ‘author’, ‘revisions’ or for example ‘sticky’. In default Drupal you have the choice between everything and nothing. But with this module you can set more detailed permissions per field, so that certain roles have limited rights to modify node fields.

Override Node Options
Drupal 7 & Drupal 8

16. Disqus

Commenting platform that can be integrated on every website and with lots of added value compared to the default Drupal response system, read here more why. This module is easy to install and integrates Disqus in your Drupal system.

Drupal 7 & Drupal 8

17. Publication Date

Drupal nodes have by default a ‘created’ and ‘changed’ date, but no ‘published’ date. Sometimes this can come in handy.

Publication Date
Drupal 7

18. Restrict password change

Within Drupal core users can be given rights to add other users, but then they can also automatically change the passwords of everybody. If you don’t want that, then install this module to add a new permission 'change other users password'.

Restrict password change
Drupal 7 & Drupal 8

19. User Expire

Do you want to give a user temporarily access to your Drupal system, for example a client in your social intranet or a temporary content manager? This module helps creating temporary access and ensures a user is automatically blocked after a certain time. This way you cannot forget it and data will not accidentally leak.

User Expire
Drupal 7

20. Custom Search

Do you like to give your Drupal visitors more options when searching than just one search box? This module provides a solution for this by searching in desired content types or a specific module. You can also configure the type of field instead of just a free text field.

Custom search
Drupal 7 & Drupal 8

21. Cache Flush

Drupal has standard limited configuration options to empty the cache. This module provides a solution for this. It claims to be the ‘ultimate tool’ to empty caches within Drupal. It is possible to make a number of presets to set all the requirements related to caches for different servers. Usable with all roles and since version 3 it is also supporting Memcache and Varnish.

Cache Flush
Drupal 7 & drupal 8

22. Relative Path to Absolute URLs

Provides a filter that generates absolute url’s from relative url’s; so relevant images are also becoming visible in for example newsletters, Drupal planet and other external systems.

Relative Path to Absolute URLs
Drupal 7 & drupal 8

23. Flush Facebook Cache

I have encountered this more often: after writing a blog and posting it on Facebook, I wanted to change a text or image. But once Facebook has indexed your page, it is placed in the cache. The next time you are posting the url of your page on Facebook, it shows an outdated image. This module provides a solution for that.

Flush Facebook Cache
Drupal 7

24. Bootstrap Library (Drupal 8 release)

Release for Drupal 8 of the popular HTML framework Bootstrap – our favourite.
Bootstrap Library

Bootstrap Library

25. Views Autocomplete Filters

In Views you can set up filters through which visitors of your Drupal system can filter (search) a.o. with free text fields within a View (f.e. a list with content). This makes the search easier by adding an ‘auto complete’. So as soon as the visitor starts to type, this module will complement the entry with suggestions. See also this tutorial:

[embedded content]

Views Autocomplete Filters

Wrap up

Ok, that’s it for this month. Questions or feedback? Let me know. Next month again a cool modules update, so stay tuned!

Feb 10 2016
Feb 10
18 Drupal SEO modules - and tools for better findability in Google Search engine optimization (SEO) has always been important, but in recent years its importance seems to have increased significantly. We were more often dealing with Drupal SEO implementations than in previous years. Many of the implementations contained overlapping components. Below we will discuss the most important ones:
Jan 26 2016
Jan 26

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

Lately I have been hearing a lot about Laravel. This is a PHP framework to build web applications and that is quickly gaining popularity. I wanted to test it to keep up to date with this current technology. So I thought: I will build a concept in Laravel to see how it works and to compare it with Drupal 8.

My goals:

  • A static page in which the content is loaded from a local database.
  • Build a list of Blog items which is fed from a Drupal 8 RESTful API (which I had previously built for Node.js).

Overall content of this blog:

  1. Introduction to Laravel
  2. Laravel’s foundation
  3. Installing Laravel
  4. Routing in Laravel
  5. Laravel’s Migration: management of the database structure
  6. Eloquent ORM: query the database
  7. HTML templating in Laravel: Blade and Views
  8. Loading data from a RESTful Drupal 8 API

1. Introduction to Laravel

Required tools and knowledge

In order to participate you will need to have the following basic knowledge and tools:

  • PHP: intermediate knowledge
  • HTML/CSS basic knowledge
  • Good code editor (IDE), I am using PHPStorm
  • A browser, f.e. Firefox

What is Laravel

  • A PHP framework for web applications
  • Developed by Taylor Otwell
  • First release: February 2012
  • Open Source (MIT licence)

Why Laravel

According to the developers it is a 'clean, modern web application framework’, which is built on other great tools. In addition, it is said that Laravel is ‘fun to code’.

Laravel is a MVC Framework

  • MVC = Model View Controller, a modern structure of web applications.
  • Model: application data and functionalities
  • View: the visible output, the HTML
  • Controller: interaction between user, model and view. Facilitated in Laravel by PHP.

Standard tools in Laravel

  • Routing of incoming requests
  • HTML templating (Blade)
  • Database definition and version control (Laravel’s Migrations and Eloquent ORM)
  • Authentication: login users and manage permissions.
  • Emailing with attachments

Laravel core is not a cms like Drupal 8

Laravel out of the box is not a cms. There is a cms component available (October cms), but in this regard Laravel cannot be compared with Drupal 8, which does offer in the core full blown cms functionalities. If you want to compare Laravel with Drupal, you will need to do this on the level of Drupal API and not Drupal cms.

2. Laravel’s foundation

Laravel’s foundation is built on strong components:

  1. Symfony for core Laravel functionalities: including simulation, access to files and debugging. Drupal 8 is also using Symfony components.
  2. Composer: a dependency manager where hundreds of packages are already available. (similar to NPM for Node.js). Composer can also be used in Drupal 8, but not to the extent of Laravel: Drupal 8 is using modules with YAML files for this.
  3. Eloquent ORM (Object Relational Mapper): object oriented database management. Similar to the Database abstraction layer in Drupal 8
  4. Migrations: database version control for Laravel. This is similar to the schema API in Drupal 8 and Migrations from Ruby on Rail Migrations.
  5. Blade: html templating system, Drupal 8 uses Twig.

Laravel is a framework built on several other strong frameworks. Below an explanation of each component:

2.1 Laravel’s foundation: Symfony

Symfony is one of the main components in Laravel. The following Symfony components are, among others, used in Laravel:

Future releases of Laravel
Laravel has announced to stay in sync with future releases of Symfony.

Symfony users
When you are a user of Symfony you can also use Laravel components.

2.2 Laravel’s foundation: Composer

Laravel uses Composer, a PHP dependency manager. The main features are:

  • Works on a ‘per project’ basis, not global.
  • Works on Mac, Windows and Unix.
  • The dependencies are defined in a JSON file: composer.json. Composer can also be used in Drupal 8. This approach is also similar to the package.json in Node.js where NPM is ‘acting’ as Composer, see also.
  • See Packagist.org for 3rd party packages that can be used in Laravel by installing them through Composer.

2.3 Laravel’s foundation: Eloquent ORM

Eloquent ORM is Laravel’s database component, similar to the Database abstraction layer in Drupal 8. ORM is an acronym for Object Relational Mapper. It has been developed for Laravel, but can also be used outside Laraval. It is using an Active record pattern for database CRUD actions. It can facilitate one-on-one, one-on-many and many-on-many relations.

2.4 Laravel’s foundation: Migrations

Tables can be created, structured and (version) controlled through Laravel’s Migrations. All this is done via code, not configuration.

2.5 Laravel’s foundation: Blade

Blade is Laravel’s html templating machine. A Blade file is saved with the extension ‘.blade.php’. Variables in the template file can be placed as follows: {{variable}} (XSS filtered) or {!! variable !!} (unfiltered, [!] only use this when you know exactly what you are doing). You can also use PHP functionalities and codes in blade files. Blade also supports subtheming and conditional controls. 

3. Installing Laravel

I am working on a Mac with OS X El Capitan. The current Laravel version is 5.1, and that is the version I am going to use. Go to Laravel docs and follow the instructions:

  • Make sure you have installed Composer.
  • Make sure the directory ~/.composer/vendor/bin is in your PATH, so that the laravel command is everywhere available. Learn here how.
  • Now you can install via the command laravel new a fresh Laravel installation. I am now going to my webroot and enter laravel new blog concept: a fresh Laravel installation will be created in the folder /blogconcept:

The created install:

  • You will get an ‘application key’. This will be used, among other things, to encrypt data, such as session data.
  • Go to the Laravel installation and run this command: php artisan serve to activate the Laravel server. Artisan is Laravel’s command line environment.

Go to your browser and navigate to http://localhost:8000. You should be seeing this:

4. Routing in Laravel

Routes are used to facilitate incoming page requests. This is similar to Drupal 7’s hook_menu() and Drupal 8’s routing system. The routes can be found in /app/Http/routes.php:

Static routes
In routes.php you will see the default homepage defined, which you saw above in the browser. Here you can add your own routes. Below an example of a page with static information:

In a browser:

Dynamic routes
Routes can also be built dynamically through working with variables:

Note the double quotes that are required to dynamically print out the variable. If you are using single quotes, Laravel will print literally {$person}.

In the browser:

5. Laravel’s Migrations: management of the database structure

First you will need a database, the standard used here is MySQL; I will make a database called ‘blog concept’. All the database settings are in config/database.php:

In this file you can set:

  • Fetch style
  • Type database: mysql is the standard, but Laravel also supports sqlite, pgsql and sql server.
  • The database connections, I am entering the following:

Tables can be managed manually through for example phpmyadmin, but that is not advisable. In Laravel the structure of tables/database can be programmed in code, resulting in flexibility and version control. ‘Database structure’ is also called ‘schema’.

By managing this in Laravel’s Migration developers can easily keep their databases in sync within a version control system, such as GIT. So you can also easily revert a database change.

Example: I am creating the initial migration file through command php artisan make:migration create_content_table. In the created file I am adding code that defines database tables:

This migration class exists of two methods: up and down. Up is used to create new tables, down is used to make the Up actions undone.

Execute command php artisan migrate, that will apply the migration code, and voila: the database tables are created:

More information: http://laravel.com/docs/5.1/migrations

6. Query the database with Eloquent ORM

For now I have manually filled the newly created tables with test content. Below a simple example to query this data:

  • Create a Model: php artisan make:model Content
  • Laravel creates the model in the /app folder:

  • The model is called ‘Content’ and not ‘Contents’, Laravel is smart enough to make that connection by itself.
  • Add the following code in routes.php:

$content = App\Content::find(1) => This is all it takes to query record with id=1 from the database table 'Contents', also here Laravel is smart enough to make the link with ‘Contents’. Then, all the fields from that record are stored in object $content, which can be assigned as variables to a blade template.

More information: http://laravel.com/docs/5.1/eloquent#defining-models

7. HTML templating in Laravel: Views & Blade

As previously indicated the HTML templating engine Blade is used in Laravel. The HTML files are called views, something else than Drupal Views: these are lists. An example of the use hereof can be seen immediately in the standard installation. In routes.php on line 15 the Laravel view ‘welcome’ is invoked: return view(‘welcome’);.

The views are included in the folder /resources/views, there you can also find the standard view ‘welcome.blade.php’:

An own dynamic view

Blade facilitates dynamically filling HTML pages. An example: I am creating a new view file called ‘about.blade.php’ and copy the HTML from welcome.blade.php:

I am adding the following code in routes.php:

You can see that the ‘about’ view is evoked through View::make() with an additional array included in which variables with content are defined that were previously loaded from the database.

Then I can use those variables in the Blade template:

In the browser:

FYI: more about Blade templates.

8. Data from a RESTful Drupal 8 API

As an example I am using the Drupal 8 API that I built earlier. The json output is looking like this:

First I played a bit around with Composer packages Buzz & Guzzle, both http clients. Those packages are facilitating much more than just retrieving data from a REStful API: POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading from JSON data, etc...

That is too much overhead, for now I can work with a standard php functionality: file_get_contents en json_decode:

  1. Create a new route: /blogs
  2. Query the json data from the external Drupal 8 RESTful API.
  3. Run through the json arrays data and create a new array where: key = url, value = blog title
  4. Render the Blade html view ‘blogs’.

Then I am copying an existing blade view and rename it to ‘blogs.blade.php’:

In this blade html view I am running through the associative array and am creating in this way a list with links:

Creating the detail page of a blog

Finally I would like to accomplish that when I click a link, the detail page of that blog appears:

  1. Create a new route with a variable
  2. Request the data from the Drupal 8 RESTful API.
  3. Look for a match in the url variable and a url in the json array from the API.
  4. When a match is found, create the variable: the title and body from the matched item.
  5. Render the html through a blade view.

In a browser:

As you can see, a lot still needs to be done concerning the styling. But as a purely functional concept, I am leaving it now the way it is.

Wrap up

Ok, that’s it for now. This is only an introduction in which I produced a concept. Many advanced components of Laravel have not yet been discussed, such as incorporating the logic code /routes.php that I placed to Models and Controllers. I would like to discuss this further in a next blog. Questions or feedback, let me know!

-- Cheers, Joris

Jan 21 2016
Jan 21

(Available as freelancer)

Joris Snoek

Business Consultant
/ Drupal Developer

The holidays are over for a while now, so it's about time for a new blog. In this article I'll discuss 12 modules that can help you get started with a great Drupal site:

1. Max image size

A default Drupal installation can check if an uploaded image is too large and display a warning. This module does something similar but is also checking previously uploaded images that are too large and likely taking up too much space.
It scans all the images (also already uploaded ones) and reduces the size of the original

More info and download - Drupal 7

2. User Import

Useful module to import users using a CSV file.

More info and download - Drupal 7

3. Select (or other)

Drupal’s form API knows by default a select element that allows you to offer choices to those who enter content. This element is limited to the provision of predefined terms (categories). After installing this module, this element can be expanded with an additional field: let the end user choose ‘other' and offer a free selection field.

More info and download - Drupal 7 & Drupal 8 Alpha

4. Captcha-free Form Protection

Everybody wants to be protected against spammers, this is often done through the Captcha technology; probably you have heard of this before. This module protects you against spammers without Captcha, since this is often a barrier for visitors.

The module applies other techniques (‘behind the scenes’) such as checks if cookies / javascript are disabled, it can also check whether a certain time has exceeded. On the basis of these data it can determine whether the person who sent a form is most likely a spammer or not. The Honeypot module contains similar end features.

More info and download - Drupal 7 and Drupal 8

5. Twitter block

Simple but common used module: shows a Twitter stream from a particular account.

More info and download - Drupal 7 and Drupal 8

6. Leaflet

Leaflet is a javascript library that is quickly becoming popular and that let’s you create maps. It is an alternative to Google maps, allowing you to easily create customized maps and integrate external map services (for example Mapbox, Stamen or Thunderforest). Easy to configure, mobile-friendly to navigate and light in code.

For a detailed introduction see Drupalize.me.

More info and download - Drupal 7 & Drupal 8 dev

7. Better watchdog UI

The Drupal core has a logging module which gives great insights in errors, notices, content and user actions, etc. Install this module if you want to filter better in this log.
FYI: Till Drupal 5 Drupal’s logging module was called ‘watchdog’, this term is still used for logging elements.

More info and download - Drupal 7

8. Check for acknowledgement

In some cases you want to know whether users of your system have read a particular piece of content. This is now possible after installing this module: it places a check mark at the bottom of a content page. Users placing the check mark are logged which is visible to you as a site administrator. This allows you to see who really confirmed they read the article.

More info and download - Drupal 7

9. IP address manager

Log the IP addresses of users logging into your Drupal site. This can be used for many things:

  • Detecting suspicious logins;
  • Identifying misconduct;
  • Detecting duplicate accounts.

More info and download - Drupal 7

10. Taxonomy container

Make the choice easier for content managers by clustering terms better.

More info and download - Drupal 7 & Drupal 8 beta

11. Date Facets

A widget for when you are using the Facet API: generates an additional block in which date-based filtering options are offered.

More info and download - Drupal 7

12. Read only mode

When putting your system in the maintenance mode in a default Drupal installation, the entire system will be temporarily put offline; the visitors will receive a maintenance message. Usually you would prefer that nobody is logged in on your site, as content can be changed during the update process. Those changes could be lost.

If you can ensure that nobody can enter/change content during maintenance, then you are also adequately covered - provided that your update is not generating errors. This module is doing just that: it places your site in the maintenance mode, so visitors can still view the site but cannot enter/change content.

More info and download - Drupal 7 & Drupal 8 beta

Wrap up

And finally, I discovered this cool site: modulecharts.org . Next month again a module update, so stay tuned! Questions or feedback? Let me know in the comments below.


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