Upgrade Your Drupal Skills

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

See Advanced Courses NAH, I know Enough
Dec 28 2018
Dec 28

Themes improperly check renderable arrays when determining visibility

Kaleem Clarkson Photo by Hello I'm Nik on Unsplash

One of the many great advantages of being a part of an open source project is that there are so many smart people out there are willing to contribute their time for the betterment of the project. This ability to crowdsource bugs and feature requests that rarely stumps the community is what makes Drupal such a powerful application.

While rare, sometimes the community finds a bug that is very difficult to solve. Let me introduce you to [#953034] Themes improperly check renderable arrays when determining visibility.

[meta] Themes improperly check renderable arrays when determining visibility

Problem/Motivation Determination of visibility for a given region's content is done by checking: This results in…


I was first introduced to this bug while trying to add a view block in the left sidebar. When the view was empty I expected the block and the sidebar to not be displayed. As you can see below, while the block was empty the sidebar was still being rendered.

The sidebar is Still being displayed.

I then googled and stumbled upon another issued, Empty view causes region to be displayed and it was exactly what I was looking for, but I noticed it was marked as a duplicate issue and linked to [#953034] Themes improperly check renderable arrays when determining visibility. This bug was reported to Drupal 7 core on October 26, 2010. The issue has over 310 comments and 230 followers.

You can really tell the severity and complexity of an issue when you see some of the brightest Drupal contributors have been making suggestions and striking out. They include but are not limited to:
bleen, chx, Cottser, Crell, DamienMcKenna, EclipseGc, Fabianx, Jeff Burnz, jenlampton, joachim, joelpittet, JohnAlbin, lauriii, markcarver, mdrummond, moshe weitzman, mpotter, samuel.mortenson, tim.plunkett, webchick, Wim Leers, xjm.

While I am not a backend developer, I felt like I could still help by highlighting a major issue that maybe someone either inside or outside the community could help find a solution.

Please remember to read the complete issue before commenting as so many people have suggested solutions to fix but have ran into a roadblock.

[meta] Themes improperly check renderable arrays when determining visibility

Problem/Motivation Determination of visibility for a given region's content is done by checking: This results in…


Oct 21 2018
Oct 21

Wouldn’t it be nice if you could add any block you want to your paragraphs?

Kaleem Clarkson

In years past, layout for Drupal has been in the hands of front-end developers, but over time various modules were developed that provided site-builders the ability to adjust the layout. An improvement yes, but there still wasn’t a clear cut option that empowered content editors to alter the layout during the editorial process.

Look out! Here comes the Paragraphs Module. This module has been taking the Drupal community over by storm because it allows content editors to add pre-designed components which gives each page the option to have different layouts. One of the limitations of the Paragraphs module, is that each paragraph can only be used once, and only for the current node you are editing. This means that you can’t re-use a common paragraph such as a call to action block, email signup or contact us form, so you end up finding yourself duplicating a lot of work if you want the same block on numerous pages. While the Drupal community has been working to help solve this problem by allowing the re-use of paragraphs, there are still going to be plenty of situations where you want to insert custom blocks, views, or system blocks such as the site logo or login block.

How do you allow your site editors to add re-used blocks into their content during the editorial process?

Let me introduce you to the Block Field Module. Maintained by the one and only Jacob Rockowitz (you know the webform guy ), you can be assured that the code follows best practices and that there will be support. The block field module allows you to reference any block regardless of where it is coming from and the best part, you don’t have to create some hidden region in your theme in order for the blocks to be rendered.

There are plenty of awesome articles out there that explains how to use paragraphs so I won’t get into that. To follow along with my steps be sure to have downloaded and enabled both the Paragraphs and the Block Field modules.

  1. Download and Enable the Paragraphs and Block Field modules.
  2. Create a paragraph type called Block Reference (or whatever name you want)
  3. Add a new field, by selecting the Block (plugin) field type from the dropdown and save it.
  4. Go to manage display and make the label hidden.
    I always forget this step and then I scratch my head when I see the Block Ref field label above my views title.
  5. Now go to back to your content type that has the paragraph reference field and ensure the Block Reference paragraph type is correctly enabled.
    The content type with the paragraph reference field was not covered in this tutorial.
  6. When adding or editing your content with a paragraph reference field. Add the Block Reference paragraph type. Select the name of the block that you would like to reference from the dropdown hit save on the content and watch the magic happen.

In conclusion, it does feel a little scary giving content editors this much freedom so it will be imperative that all views and custom blocks have descriptive names so that editors can clearly identify what blocks to reference. Overall I feel like this is a good solution for referencing existing blocks that can save a lot of time and really unleashes the power of the paragraphs module. The Drupal community continues to amaze me!

Oct 10 2018
Oct 10

image of team working to put pieces of a puzzle together The reality is that running a business is such a diverse and complex endeavor that managing complex and rapidly evolving software solutions needed to execute the mission can be an overwhelming component. It already takes enough energy and expertise to be proficient in managing people, knowing your vertical, regulating cash flow, envisioning new products, evaluating old products, and on and on and on. The problem, however, is that if you don’t leverage complex and rapidly evolving software solutions to handle processes, you end up drowning in inefficiency and inconsistency. So therein lies a significant and difficult problem because you likely didn’t get into business to become an informal senior software architect. And that’s where leveraging something like a robust CMS comes into play. 

Let’s look at some of the ways leveraging a modern CMS, like Drupal, for example, can significantly streamline your business and free you to, well, run your business.

CMS is more than a CMS 

So in simplest terms, a CMS is a Content Management System. Historically, that basically meant providing standard functionality for perhaps managing blog content for a public website. The truth is, however, today it’s far more than that. There’s a whole range of CMS options that vary from that ultimately simple blog scenario to enterprise level development frameworks upon which you can build nearly any kind of web-based software solution. So in its infancy, it may have been largely all about getting a simple “brochure” site up with some basic management, but today it’s being used to provide some of the most sophisticated enterprise web solutions that are critical to modern business strategy. And in many cases, it’s leveraged internally to empower the management of the business in a highly effective and efficient manner. We’ll cover some more tangible examples in a minute, but first we need to get an important question out of the way. 

Which CMS? 

A CMS is a broad-ranging category of systems, and there is still a ton of flexibility in choosing a CMS. In fact, we’ve written articles on this topic and built a little tool to help you figure that out. The different management systems cover a wide range of use cases, so it can be difficult to determine which is right for a given situation at times. There are a number of extremely simple CMS setups that can work great on a low budget, with very flexible requirements, and without needs for complex solutions like custom integrations. On the other end are systems like Drupal (our CMS framework of choice) that allows you do virtually anything you want as well as continue to leverage a whole lot of components included in the core system or built by those extending the system in powerful ways. It’s this latter category of enterprise-level customizable CMS that we will focus on here because that’s where the exciting power lies.

 Which CMS is best for your website?  Take our CMS Quiz and find out!

Real world scenarios

Let’s look at some specific examples of just what these systems can do. And this isn’t hypothetical. These are exactly the types of solutions we’ve built for our clients with an extensible CMS platform like Drupal as our starting point.

Employee collaboration

Email. Chat. Documents. Meetings. There is a lot of internal chatter and management that goes on within a corporation, and the magnitude of the management of that cannot be overstated. Who hasn’t found themselves almost daily wanting to just disconnect from the internet for 20 minutes to take a breather from all the chaos swirling around? Well, the right CMS can mitigate a lot of that. You can use a whole host of building blocks to build an employee portal where coworkers can chat, send notifications, collaborate on policy documents, receive corporate notifications, see a team calendar, reserve a conference room, assign tasks, etc - all with deep tracking and revisioning and all within one ecosystem that is accessible from the desktop, the laptop, and mobile devices. With this strategy, you find yourself having a whole different experience. No more depending on how different people like to store and organize their local copy of largely outdated documents. No more relying on email history to track a decision that was made or find a digital asset. No more walking around the hall looking for an empty conference room. No more being stuck solving an accounting problem because that person is on vacation and has a local spreadsheet on their laptop. Best of all - everyone uses the same tools and those tools are managed from a single infrastructure. Sounds great, doesn’t it?

Client management

Let’s be honest - managing clients is often more difficult than managing your own workforce because your clients aren’t in your building, on your schedule, or under your control. There are countless phone calls, emails, shared documents, meeting decisions, deadlines, and other elements that can make it easy to lose sight of the forest for the trees. And it can be overwhelming to manage and well, frankly, quite embarrassing when something slips through the cracks or someone who needs to know isn’t in the know.

A CMS based solution can provide a platform to minimize and consolidate client management needs into a system that depends far less on individual availability and manual process and allows for a much more robust client relationship. Using a CMS as a platform, you can build systems that allow sending an invoice in a few clicks, with automated reminders and tracking of unpaid invoices. That same system can allow clients to track progress on major requests, and send or request updates. It can also run reports on product subscriptions that are set to expire, or highlight clients that are typically late paying their bills, or prioritize requests that haven’t been responded to in the past x days. It can also allow clients to pay their invoices online, engage live chat support, access help documentation, or receive alerts about upcoming products - again, all tracked in a single ecosystem and in full view of everyone in your business who needs visibility of some or all of the client engagement. It can literally transform how things are done and has huge ROI potential because it literally may save you from losing clients and make the ones that stay happier.

Content or product management

So what about managing the products or services your company actually provides? A CMS can do that too. It might mean allowing those who manage the warehouse to manage inventory, which is immediately reflected on the public-facing ecommerce site. Or it might mean serving, tracking and reporting online ads. Or it may mean providing a robust content management workflow for new stories and white papers that you offer your customers. And it all can leverage the same building blocks for tracking, notifications, document management, user roles, and permissions, etc., that a modern CMS can provide. Better yet, multiple CMS systems can even be built to talk to each other so that perhaps your Client Management system can get info about products your client has purchased from your Product Management or your Employee Collaboration system can be told to set follow-up reminders for your employees based on the activity of their clients. Or maybe all of these systems are really just one system that gives appropriate access to all who need it. The possibilities are endless.

So where do we go next?

So we’re only scratching the surface here, but if you have a heavy dependence on manual processes, or a lot of duplication of effort, or a difficulty tracking all the moving requirements, conversations or documentation - then a robust software solution built upon a CMS could be a key opportunity to making your processes more efficient and effective and allow you to focus on building your business, not running your business. The web today is not the web it even was 5 years ago so taking the time to see what’s possible can really change your whole perspective on how your business can function. Exciting times!

image with text offering access to our free CMS Selection quiz.

Aug 15 2018
Aug 15

Business person looking at Drupal logo, deciding on a CMS

You may have heard of Drupal in passing, but you have not ever been given a straight answer on what it is and why you should care. The truth is that even if you have worked with Drupal, you might not actually know what to say when asked what it is. Looking around there doesn’t seem to be a lot of great answers to this question out there either. It would be difficult to tell if you need Drupal as a solution for your website if you aren’t even sure what it really is to begin with. 

The Basics

To say we talk about Drupal a lot is an understatement. It’s non-stop Drupal all day long here at Ashday, but what is Drupal? Simply put Drupal, is an open source content management system. It's primarily built in the PHP programing language, and designed to create websites for use on a variety of different web servers.

Okay, but what is a content management system? A typical definition of a content management system or CMS is an application that is often used for creating websites that focuses on publishing workflows, user management, and content delivery. These dynamic and database driven websites usually allow for multiple editors and templating for streamlined content development. This is different than a plain old web page that is written in HTML and styled in CSS. A content management system allows you to compose and edit just the content without having to adjust the HTML. It makes it easier for non-technical users to publish text and images on the web to use that content in more than one place. With a CMS you can display your blog post on the homepage and in your blog, without needing to write the same content twice.

Which CMS is best for your website?  Take our CMS Quiz and find out!

What does it mean to be open source? Open source means that all of the core code that makes the software tick is free and open to view. Open source programs are typically free to download and use. They aren’t exclusively developed by one person or corporation and they rely on an open community of peers to maintain and improve the core code. This means that the software can be rapidly developed with a large pool of contributors. Another benefit of open source is the adaptability of custom code, since everything is open we can extend the core code to do more and behave based on the business needs of the project.

Other Popular Content Management Systems

There are many open source software CMS tools available on the internet. Drupal is often mentioned in the company of other popular CMS such as WordPress. It even gets lumped together with SaaS (Software as a Service) based site builders like Squarespace and Wix. While it's true that Drupal serves a similar role as a means to building websites, it is far different from these other systems. WordPress for example, is primarily a blogging platform but people have stretched it far beyond its intended use. Because of this, complex sites built with WordPress often consist of a lot of custom code of varying quality. Drupal’s real contemporaries are more along the lines of a framework like Laravel. These frameworks are much more customizable and robust, but often lack the pre-built setup of users, content types, and management features. This results in a much longer time to market for projects built on a bare framework.

What are the use cases for Drupal?

Drupal is best suited for building websites that are medium to large in size with a focus on future scalability. That isn’t to say that Drupal can’t be used for smaller sites, it does fine for this sort of thing all of the time, but it is built to handle much more and can incur more overhead than is necessary. It is a bit subjective to use terms like medium and large for a website, but when we think of large we typically mean websites used for enterprise applications.

Drupal is great at storing, managing and delivering huge amounts of content. If you have a lot to publish, then Drupal can’t be beat. The admin interface allows for creation of custom management tools that make the whole publishing workflow tailored to how your business runs. Drupal is built around being able to have many levels of users with defined roles. Permissions can be fine-tuned to create a system with a publishing workflow that won’t slow down content creators and will save time for editors and curators.

In the world of web apps, Drupal is king. Drupal 8 is a very extensible framework capable of integrating with the vast ecosystem of services offered across the internet. If you need to build a product for others to connect to, Drupal is a great choice with its core RESTful API. The object-oriented framework within Drupal makes creating large-scale applications inexpensive with a reasonable timetable.

Why do organizations choose Drupal?

Large organizations both corporate and non-profit trust Drupal to run their sites and applications. Drupal has earned this trust through its open source community that provides contributed modules and timely core updates. The security team, which is world class, keeps Drupal a bit safer by finding and writing patches vulnerabilities before they can become a problem. Part of the Drupal community is the Drupal association that pushes cutting-edge initiatives to keep Drupal modern, innovative and thoughtful.

The large open source community behind Drupal provides thousands of modules to extend the core functionality of Drupal, all for free. Contributed modules are reviewed by the community and given a stamp of approval if they are stable and safe to use. This is very different than many other open source communities where contributed code can be malicious or come at a cost. When you use Drupal and its contributed modules, you are benefiting from the hundreds of thousands of development hours from a giant group of developers across the globe.

How do I start a Drupal project?

Drupal can be used to run just about anything you would want on the web. Because of this flexibility, Drupal doesn’t do a whole lot on initial install without more configuration and setup. This is not a simple task for the amateur site builder, Drupal is not known as the easiest of the frameworks to learn. If you are building a medium to large site or a web application, you may want to hire professional web developers with the right technical skills. This can be accomplished by an internal team of Drupal developers or outsourced to a Drupal development agency. Check out this article we wrote to help you determine if you should build with an in-house team or outsource. 

Popular examples of Drupal websites

You have most likely seen or used a site built on Drupal and didn’t even realize it. There are a lot of very influential sites out on the web that leverage Drupal to deliver content. Here is a small list of those:







Drupal is very popular in higher education with many universities and colleges running their sites on Drupal 7 & 8. Drupal also has a large share in local government sites and in the publishing industry. Drupal is everywhere you look but its flexible structure allows it to power a variety of types of sites while being invisible and allowing the content it serves to be visible.

 image with text offering access to our free CMS Selection quiz.

Jun 25 2018
Jun 25
Drupal Europe

Drupal Europe is both a technology conference and a family reunion for the Drupal community. Bringing together 1600+ attendees, it is the largest community driven Drupal event taking place on the European continent this year. For anyone connected with Drupal this is a unique opportunity to share your experience, learn, discuss, connect and contribute back to the community.

Being a community driven conference, we wanted to focus on real life case studies and not the usual technology driven structure. So we’ve introduced industry tracks which focus on specific industry sectors.

Photo with CCO licence via Pexels.com from StartupStockPhotos

The Higher Education track is for anyone using Drupal or thinking of migrating to Drupal at a college or university who is looking to connect with other Higher-Ed Drupal users.

If you have experience of delivering Drupal solutions in the higher education sector or are looking for inspiration on how you continue to develop your CMS further, this is the right track for you.

Drupal is a popular choice in higher education, and many of us are using it in creative and inventive ways. With Drupal 8, the opportunities for exploration and experimentation expand even further — from headless Drupal to top-tier configuration management. Let’s showcase our successes and best-practices with Drupal 8!

We know many universities are still on Drupal 7 and are keen to migrate to Drupal 8, so come to share what works for you and see wins from your peers.

Photo with CCO licence via Pexels.com from StatusStockphoto

Have you launched a Drupal 8 project recently that you are proud of? Started a campus Drupal users group and have tips for others looking to create their own? Developed a great user support model for your content editors? Conquered decoupled Drupal with your frontend stack? Share your awesome projects and lessons learned with your peers.

  • Education sector
Photo with CCO licence via Pexels.com from Pixbay
  • Drupal in a Day (how Global Training Days got to be a localized event)
  • From CMS to LMS
  • Web accessibility in higher education
  • GDPR and childrens information
  • Javascript for higher education
  • Migration from Drupal 7 to 8
  • How Drupal 8 API-first helps to
    integrate with existing IT-Infrastructure
  • Build your own Drupal Community

Session submission is open and we ask you to submit interesting session proposals to create an awesome conference. Session proposals are not limited to Drupal and all topics in relationship with Higher Education are welcome.

Please also help us to spread the word about this awesome conference. Our hashtag is #drupaleurope.

If you want to participate in the organisation or want to recommend speakers or topics please get in touch at [email protected].

Drupal is one of the leading open source technologies empowering digital solutions around the world.

Drupal Europe 2018 brings over 2,000 creators, innovators, and users of digital technologies from all over Europe and the rest of the world together for three days of intense and inspiring interaction.

Drupal Europe will be held in Darmstadtium in Darmstadt, Germany — with a direct connection to Frankfurt International Airport. Drupal Europe will take place 10–14 September 2018 with Drupal contribution opportunities every day. Keynotes, sessions, workshops and BoFs will be from Tuesday to Thursday.

Apr 06 2018
Apr 06
image of the Drupal and Wordpress logosWe’ve covered this in previous blog posts, but I think it’s time we came back to this and gave the contenders another look. (It's only been three years since we last covered this, so everyone has probably been waiting with baited breath for this one.) Internet culture loves to pit things against each other to see which reigns supreme, so let’s do that for these two juggernaut content management systems.

Wordpress? More like Worldpress

It is no exaggeration to say that a lot of the internet (about 28% at the time of this writing) is made up of Wordpress sites. With that sort of share, it is no surprise that most everyone has heard of this blogging-tool-turned-web-platform. Among other CMS type sites, there is no contest as far as usage goes. Somewhere around half of all sites built with a CMS use Wordpress. You’ll find it as a suggestion on most shared hosting platforms and there are tutorials across the internet to help someone get started using it. This thing is everywhere.

Wordpress is currently on version 4.9.x right now and has the great reputation of making sure that most of its users are able to upgrade automatically without much threat of backwards compatibility issues. This is great from a stability standpoint. When you create a website you probably don’t want to worry that the next update to the platform will cause you to rebuild it more often than you are ready. That’s not to say it has a perfect track record when it comes to security. Not every site has a situation that allows for the automatic updates and even then there are thousands of plugins available that could have security holes.

Which CMS is best for your website?  Take our CMS Quiz and find out!

Wordpress is everywhere and it has been for a few years now. It is not suitable for every web need though and that comes through the most when you need something that can’t be done by installing a few plugins and throwing on a premium theme purchased from somewhere. There are many places you can get a custom Wordpress site built, but the CMS itself isn’t well suited for sites with a lot of editors, permissions, and features that large enterprise sites might run into.

By making Wordpress into an easily accessible platform, it has precluded itself from being able to handle the scale that comes with more complex sites. Without diving into code, you can’t define a new role or give users a different set of limited permissions outside of what already is defined in the system. The same goes with the types of content you can create and the fields you will have available. Plugins can extend some of this, but the reliability track record isn’t the greatest from my experience.

Drupal is for big projects

When it comes to market share, Drupal is a sliver of the pie compared to the internet at large. What it lacks in sheer numbers it makes up in the number of large and significant sites that use it. Some of these sites include government sites, entertainment sites, and university sites. Drupal has a reputation of being complex and heavy to run. While that is true, it isn’t necessarily a bad thing all of the time.

Drupal 8 is a bit of a rebirth for the platform. Promises of better forwards compatibility with future versions means that it will be easier to stay up to date than ever before. This was a pain point with previous versions of the platform and the community has made it a point to improve. Drupal 8 makes life a bit easier with many more features ready to go when you install the site. You can craft a pretty good, simple, site with a vanilla installation of this version.

The real magic comes out when a skilled team of developers get their hands on Drupal. This platform has always been made by developers for developers and it shows through in 8. The new object-oriented approach to the code makes it simpler for those who aren’t as familiar with Drupal to get in there and make some changes. It is extended easily with the large number of modules that add specific features to a site. These modules are put through pretty rigorous review before they are deemed stable and it makes for more secure sites overall.

Drupal’s other big draw is the workflow experience for editors and site builders. With all of the different ways you can setup a Drupal site, it is possible to have moderated workflow between editors and whoever has the final say on published content. New editing tools include a better wysiwyg, responsive images, and dynamic data views.

Drupal 8 is easier than it ever has been, but that doesn’t say a whole lot when you think about where it came from. What separates it from the rest of the crowd is the ability for it to scale to whatever size is asked of it, but that only can happen in trained hands still and that is probably why it hasn’t taken over the market share just yet. Not every small project needs a whole development team to get it done. If you only have a few pages with some text, Drupal is going to be too much for the task. (Though it will work just fine, it’s just overkill.)

The winner is the web

There is place on the internet for both of these platforms, and while it may seem like this is a cop-out answer to come to after approaching this topic again, there is more to it. Wordpress has established itself as a useful tool for what it does best. It allows users to create a website and a decent one at that. It has replaced the old platforms of yore that helped build the early internet, but it isn’t the platform of choice for the largest sites that get the most traffic. Quantity of sites using Wordpress does not mean these sites get the most traffic individually. Drupal is built for scale and is ready to handle high traffic. Is it the obvious choice for every website? No, but should an enterprise size project be shoved into a platform meant to handle every other website or should it be able to have its needs met specifically by something meant for that task?


image with text offering access to our free CMS Selection quiz.

Mar 23 2018
Mar 23

Why Squarespace Will Replace Wordpress, Wordpress Will Replace Joomla, and Drupal Will Replace Drupal

When the open source WordPress blogging platform first came out, it opened up the world of internet publishing to the masses. Sure, there were website builders out there like GeoCities and Angelfire, but they lacked much and were very ugly. When WordPress came along it gave voice to those willing to overcome the barriers of setting up web hosting and installing the software. These days there are much better website builders for the common person. Squarespace being a standout of the group even has an easy to use e-commerce option. Because of this, the roles of many popular Content Management Systems (CMS)s are shifting.

Squarespace is the new WordPress

While WordPress usage is higher than ever, it seems that a large portion of the DIY and personal site market is shifting to services like Squarespace. It makes sense, since Squarespace and its ilk (Wix, Weebly, etc) are often easier and cheaper in the long run. With hosting and support rolled into one cost, it simplifies everything. People building personal sites and even small business sites have been migrating over to these kinds of site builders more and more every year. The trend is sure to keep rising as these services start to offer e-commerce and other business tools.

Which CMS is best for your website?  Take our CMS Quiz and find out!

WordPress doing more than ever

WordPress really hasn’t changed all that quickly over the years, but what has changed is the ways in which people are using it. It’s still deep-down a blogging platform, but people have extended it to be much more of a full CMS. The sheer number of developers familiar with WordPress development is what has pushed it to be the top open source CMS on the web today. WordPress is now the CMS of choice for most small to medium sized enterprise sites, and it is increasingly capable of more on more complexity, potentially pushing middling tools like Joomla more and more into the fringes of the the market and perhaps eventual irrelevance. WordPress is probably going to continue to be the top CMS for at least the next few years as more web design and marketing agencies make it a cornerstone of their services. WordPress at it’s core doesn’t seem to be doing much to accommodate this new kind of usage that is beyond the blog. We are already starting to see the bubble burst as these sites are requiring more functionality than WordPress can handle and many end up being more custom code than WordPress. It will be interesting to see if WordPress adapts or loses share in the enterprise world over the next few years.

Drupal framework more of a framework

Drupal has always been viewed as more of a framework than a CMS. With the release of Drupal 8, Drupal has doubled down on the framework concept incorporating the Symfony PHP ecosystem into it’s core. Drupal 8 has become the perfect option for large Drupal 7 sites that have begun to outgrow what Drupal 7 can do. Drupal 8 has positioned itself to be a viable option for many web based apps and can easily beat out non-CMS frameworks such as Laravel in terms of development speed and scalability. Drupal 8 is filling the functionality gap that WordPress just can’t do. I predict that enterprise migrations from WordPress to Drupal 8 are going to be on the rise over the next couple of years as businesses require more of what the internet has to offer. 

Which platform you go with will depend on your website needs. Small brochure type sites will easily find a home on one of the instant site builders and those with strong WordPress understanding might continue to use Wordpress. We at Ashday strongly believe that Drupal will be able to serve a wide-range of needs for a long time to come. The stability and scalability has only improved with the latest iteration and in the hands of the right team it can be made to do just about anything.

image with text offering access to our free CMS Selection quiz.

Oct 17 2017
Oct 17


My instinct is to say never….but if you are still wondering “Should I use Drupal?”, read on and we will take a look deeper to see if we can find some cases where Drupal may be a bad fit.

Brochure and small websites

Drupal can be overkill if your site needs consist of a page or two and maybe a webform. I would agree that the overhead of Drupal may be a bit much here, but you should also consider your future needs. Your simple site may need to grow into something that requires users, e-commerce, or more complex data handling. If that is the case then you would save money in the future by investing in a solid web framework early on.

Legacy Systems

If years of your data is tied up in a legacy system, it may be too risky to try to switch a site over to Drupal. That is understandable but you should also calculate the costs of maintaining the old system, the added time it takes to add new features, and the vulnerabilities that come up in older depreciated software. It takes a lot of planning and can be a bit tedious but a migration to Drupal 8 may actually cost less in the long run.

Small Budget

Drupal development costs due seem to be a bit higher than development on other popular content management systems. But I would say that the difference in cost is negligible, especially when you have a lot of custom needs. Drupal will actually save you money once it comes time to build custom features.

See our article on Drupal vs. WordPress for more details when comparing the true costs of a WordPress site.

If you truly have a tiny budget and many development needs, it is probably time to face reality and scale back to what you can truly afford, regardless of which CMS you choose. If you have a small budget and you can’t accomplish everything you need with a WiX website, then it may be time to re-think your web presence entirely.

No Drupal Experience

If your internal development team or development partner has no previous experience in Drupal, then it really might not be the best choice for your project. It is definitely worth the effort to learn, but be prepared to make big increases to your project timeline. However, this can easily be solved with supplementing your existing team with an experienced Drupal shop like Ashday.

It turns out that there are a few instances where Drupal may not be the best fit, but most of them can be overcome with some planning and evaluation of future needs and requirements.

If you want to build in Drupal but don’t have the right team for the job, you are in luck! Ashday can help with that. 

Offer for a free consultation with an Ashday expert

Jul 13 2017
Jul 13
July 13th, 2017

When creating the Global Academy for continuing Medical Education (GAME) site for Frontline, we had to tackle several complex problems in regards to content migrations. The previous site had a lot of legacy content we had to bring over into the new system. By tackling each unique problem, we were able to migrate most of the content into the new Drupal 7 site.

Setting Up the New Site

The system Frontline used before the redesign was called Typo3, along with a suite of individual, internally-hosted ASP sites for conferences. Frontline had several kinds of content that displayed differently throughout the site. The complexity with handling the migration was that a lot of the content was in WYSIWYG fields that contained large amounts of custom HTML.

We decided to go with Drupal 7 for this project so we could more easily use code that was created from the MDEdge.com site.

“How are we going to extract the specific pieces of data and get them inserted into the correct fields in Drupal?”

The GAME website redesign greatly improved the flow of the content and how it was displayed on the frontend, and part of that improvement was displaying specific pieces of content in different sections of the page. The burning question that plagued us when tackling this problem was “How are we going to extract the specific pieces of data and get them inserted into the correct fields in Drupal?”

Before we could get deep into the code, we had to do some planning and setup to make sure we were clear in how to best handle the different types of content. This also included hammering out the content model. Once we got to a spot where we could start migrating content, we decided to use the Migrate module. We grabbed the current site files, images and database and put them into a central location outside of the current site that we could easily access. This would allow us to re-run these migrations even after the site launched (if we needed to)!

Migrating Articles

This content on the new site is connected to MDEdge.com via a Rest API. One complication is that the content on GAME was added manually to Typo3, and wasn’t tagged for use with specific fields. The content type on the new Drupal site had a few fields for the data we were displaying, and a field that stores the article ID from MDedge.com. To get that ID for this migration, we mapped the title for news articles in Typo3 to the tile of the article on MDEdge.com. It wasn’t a perfect solution, but it allowed us to do an initial migration of the data.

Conferences Migration

For GAME’s conferences, since there were not too many on the site, we decided to import the main conference data via a Google spreadsheet. The Google doc was a fairly simple spreadsheet that contained a column we used to identify each row in the migration, plus a column for each field that is in that conference’s content type. This worked out well because most of the content in the redesign was new for this content type. This approach allowed the client to start adding content before the content types or migrations were fully built.

Our spreadsheet handled the top level conference data, but it did not handle the pages attached to each conference. Page content was either stored in the Typo3 data or we needed to extract the HTML from the ASP sites.

Typo3 Categories to Drupal Taxonomies

To make sure we mapped the content in the migrations properly, we created another Google doc mapping file that connected the Typo3 categories to Drupal taxonomies. We set it up to support multiple taxonomy terms that could be mapped to one Typo3 category.
[NB: Here is some code that we used to help with the conversion: https://pastebin.com/aeUV81UX.]

Our mapping system worked out fantastically well. The only problem we encountered was that since we were allowing three taxonomy terms to be mapped to one Typo3 category, the client noticed some use cases where too many taxonomies were assigned to content that had more than one Typo3 category in certain use cases. But this was a content-related issue and required them to re-look at this document and tweak it as necessary.

Slaying the Beast:
Extracting, Importing, and Redirecting

One of the larger problems we tackled was how to get the HTML from the Typo3 system and the ASP conference sites into the new Drupal 7 setup.

The ASP conference sites were handled by grabbing the HTML for each of those pages and extracting the page title, body, and photos. The migration of the conference sites was challenging because we were dealing with different HTML for different sites and trying to get get all those differences matched up in Drupal.

Grabbing the data from the Typo3 sites presented another challenge because we had to figure out where the different data was stored in the database. This was a uniquely interesting process because we had to determine which tables were connected to which other tables in order to figure out the content relationships in the database.

The migration of the conference sites was challenging because we were dealing with different HTML for different sites and trying to get get all those differences matched up in Drupal.

A few things we learned in this process:

  • We found all of the content on the current site was in these tables (which are connected to each other): pages, tt_content, tt_news, tt_news_cat_mm and link_cache.
  • After talking with the client, we were able to grab content based on certain Typo3 categories or the pages hierarchy relationship. This helped fill in some of the gaps where a direct relationship could not be made by looking at the database.
  • It was clear that getting 100% of the legacy content wasn’t going to be realistic, mainly because of the loose content relationships in Typo3. After talking to the client we agreed to not migrate content older than a certain date.
  • It was also clear that—given how much HTML was in the content—some manual cleanup was going to be required.

Once we were able to get to the main HTML for the content, we had to figure out how to extract the specific pieces we needed from that HTML.

Once we had access to the data we needed, it was a matter of getting it into Drupal. The migrate module made a lot of this fairly easy with how much functionality it provided out of the box. We ended up using the prepareRow() method a lot to grab specific pieces of content and assigning them to Drupal fields.

Handling Redirects

We wanted to handle as many of the redirects as we could automatically, so the client wouldn’t have to add thousands of redirects and to ensure existing links would continue to work after the new site launched. To do this we mapped the unique row in the Typo3 database to the unique ID we were storing in the custom migration.

As long as you are handling the unique IDs properly in your use of the Migration API, this is a great way to handle mapping what was migrated to the data in Drupal. You use the unique identifier stored for each migration row and grab the corresponding node ID to get the correct URL that should be loaded. Below are some sample queries we used to get access to the migrated nodes in the system. We used UNION queries because the content that was imported from the legacy system could be in any of these tables.

SELECT destid1 FROM migrate_map_cmeactivitynode WHERE sourceid1 IN(:sourceid) UNION SELECT destid1 FROM migrate_map_cmeactivitycontentnode WHERE sourceid1 IN(:sourceid) UNION SELECT destid1 FROM migrate_map_conferencepagetypo3node WHERE sourceid1 IN(:sourceid) … SELECTdestid1FROMmigrate_map_cmeactivitynodeWHEREsourceid1IN(:sourceid)UNIONSELECTdestid1FROMmigrate_map_cmeactivitycontentnodeWHEREsourceid1IN(:sourceid)UNIONSELECTdestid1FROMmigrate_map_conferencepagetypo3nodeWHEREsourceid1IN(:sourceid)

Wrap Up

Migrating complex websites is rarely simple. One thing we learned on this project is that it is best to jump deep into migrations early in the project lifecycle, so the big roadblocks can be identified as early as possible. It also is best to give the client as much time as possible to work through any content cleanup issues that may be required.

We used a lot of Google spreadsheets to get needed information from the client. This made things much simpler on all fronts and allowed the client to start gathering needed content much sooner in the development process.

In a perfect world, all content would be easily migrated over without any problems, but this usually doesn’t happen. It can be difficult to know when you have taken a migration “far enough” and you are better off jumping onto other things. This is where communication with the full team early is vital to not having migration issues take over a project.

Web Chef Chris Roane
Chris Roane

When not breaking down and solving complex problems as quickly as possible, Chris volunteers for a local theater called Arthouse Cinema & Pub.

Jul 07 2016
Jul 07

Eight months ago Drupal 8.0.0 was released. Exciting news for drupalists. Since then comparing D8’s features to its predecessor is a topic in daily business. «Can drupal 8 do what we can do now with 7 today?”. After playing around with D8 i get the feeling some crucial features are missing. Dries invited people to tell ”why we not use or migrate to drupal 8” – and got a clear answer: A majority of drupalist (60%) are waiting for certain modules. So the follow up question would be what are these modules.

On the fly my top 10 wishlist would be:

  • pathauto
  • token
  • webform
  • metadata
  • views_bulk_operations
  • flag
  • rules
  • xmlsitemap
  • redirect
  • search_api

Today it seems quite difficult to get a good overview of D8 ecosystem. Also because some module development moved to github to have a better collaboration tool. I was irritated to see no D8 version of the webform module in the download section on drupal.org  – That’s a module with 1/2 million downloads for D7. Comments on this issue gives some answers. Without committed maintainers from the beginning the porting takes much longer. A highly complex module like webform probably needs almost complete rewrite to fit into the new core of D8. Porting module from D7 to D6 was much easier. For forms we could use in some cases the core Form API, core contact forms or the eform module. But our clients would most likely miss out on the experience of D7s webform module.

Under the hood Drupal 8 core changed significantly. Symfony2 for example is now playing its music to give us new possibilities. I guess in some cases there are new solutions we have yet to discover. From a suitebuilder point of view, D8 is delightfully similar to what we know from D7. However, it will take some getting used to not trying to add the old modules we know to this new architecture.

In the end the importance of a variety of mature modules that play together nicely is crucial when it comes to efficiency, maintainability and stability of a project…

“I am confident that Drupal 8 will be adopted at “full-force” by the end of 2016.”
Dries Buytaert

Drupal is a registered trademark of Dries Buytaert.

Jul 06 2016
Jul 06

Development started on Drupal 8 features back in March of 2011. Since then, the developer and application framework world has looked forward to the outcomes of every development, feature completion, clean-up, API completion, beta, and release candidate (RC) phase with baited breath. In November of 2015, Drupal 8.0.0 was released. Sighs of relief turned to curious murmers—what’s this all about?

Drupal 8 takes an already terrific content management framework to ever greater heights for users, administrators, and developers. There’s a seriously sharp focus on user-friendliness, but content presentation, new ways to create data structures, build APIs, multilingual capabilities, and the delivery of mobile accessibility out of the box? Drupal 8 brings those to the table too.

Looking for help with Drupal 8?

There are 16 Drupal 8 features worth knowing.

While Symfony 2 powers the Drupal 8 backend, a lighter and faster core offers tons more capabilities for modules and themes. Plus, the Drupal 8 migration and the onward curve is significantly reduced. These changes and more are key reasons to consider that switch to Drupal 8. But I’m getting ahead of myself, here are the 16 top Drupal 8 features:

1. New Theme Engine

Drupal 8 includes a brand new theming engine called Twig, which is PHP-based, flexible, fast, and secure. It’s much easier to create beautiful and more functional Drupal websites using Twig, as its templates are written in a syntax that’s less complex than a PHP template or others while being more secure.

2. Mobile First From The Get-Go

Drupal 8 is mobile first in its approach. All the built-in themes that come with Drupal 8 are responsive, along with an admin theme that adapts to different screen sizes, and a ‘Back To Site’ button to go back to the front page. Tables fit into any screen size without a hitch, and the new admin toolbar works well on mobile devices.

3. More HTML5 Power to You

HTML5 is now more or less the de facto standard when it comes to writing web markup. The same is now available natively in Drupal 8, giving you access to input fields like date, e-mail, phone, etc., and even more functionality and compatibility with mobile and handheld devices.

4. Multilingual Ready

Drupal 8 boasts extensive multilingual features right out of the box. The admin interface has built-in translations. You can also create pages with language-based Views filtering and block visibility. Translation updates from the community are automatically facilitated.

5. Manage Your Configuration

Drupal 8 has configuration management built into it at the file-system level so that carrying over configuration elements (like content type, views, or fields, etc.) from local development to the server is a breeze. You can use a version-control system to keep track of configuration changes. Configuration data is stored in files, separate from the site database(s).

6. Easy Authoring

New Drupal 8 features bring unprecedented power into the hands of the Content Editor, with WYSIWYG editor CKEditor now bundled with the core. However, the most touted improvement remains the in-place editing capability that Drupal 8 will afford users, a result of the Spark Initiative.

Site and content creators or editors can edit text on any page without having to switch to the full edit form. Drafts are now much easier to create, and web security is now better implemented as a result.

7. Quick Edits

There’s something great about seeing something that needs changing and having the ease of access to change it—directly and quickly. Now Quick Edit is a backport of the Drupal 8 in-place editing for Fields. So if you’re logged into Drupal content is in front of you, edit the text directly for quick fixes and additions from the front-end.

8. Views Now Part of Core

Views sit high up in the Drupal module hierarchy, as it is an integral part of most website projects, and a lot is pretty much impossible without it. Site designers have used use this hitherto-contributed module to output galleries, maps, graphs, lists, posts, tables, menus, blocks, reports, and what-have-you.

With this Drupal 8 feature, Views is part of and firmly integrated with the core. The front page and several administration pages are now Views, and users will now be able to quickly create pages, blocks, admin sections, etc., and modify existing ones just as effortlessly.

9. Better Support for Accessibility

Drupal 8 has excellent support for industry standard accessibility technologies, like WAI-ARIA. ARIA Live Announcements API and TabManager are significant improvements in Drupal 8, which provide control for rich Internet applications. Bells and whistles like better font sizes, tweaked color contrasts, jQuery UI’s autocomplete, and modal dialogs go a long way towards making Drupal 8 a breeze to use.

Download our Ebook: Learn to select your best Drupal Partner

10. Web Services Built-in

Drupal 8 now makes it possible to use itself as a data source, and output content as JSON or XML. You can even post data back to Drupal 8 from the front end. Hypertext Application Language (HAL) is implemented in Drupal 8 and makes exploitation of web service capabilities less painful.

11. Fields Galore

Drupal 8 ships with bucket-loads of field types in the core, thus taking its content structure capabilities up a notch. New field types like entity reference, link, date, e-mail, telephone, etc., aid content creation, and now you can attach fields to more content types, as well as create custom contact forms by attaching fields to them.

12. Guided Tour

Now the descriptive text is right under the help link. Users can click and then take the tour; pop-ups appear, explaining how this all works, one of the most helpful Drupal 8 features to newcomers. This user-friendly boost is well-received as it’s making the CMS easier for everyone to understand.

13. Loading Speed

Drupal 8 caches all entities and only loads JavaScript when necessary. When a page is viewed, its content doesn’t need to be reloaded again. Previously viewed content is quickly loaded from the cache. Once configured and enabled, caching is completely automatic.

14. Industry Standards

Drupal 8 aligns with the latest PHP 7 standards like PSR-4, namespaces, and traits, and uses top notch, outstanding external libraries like Composer, PHPUnit, Guzzle, Zend Feed Component, Assetic to name a few. Meanwhile, underlying Drupal 8 features modern, object-oriented code that’s the order of the day, by Symfony 2.

15. JavaScript Automated Testing

Automated testing is not possible for front-end, so JaveScript (JS) automated testing is now possible with Drupal 8.1. Now QA’ers can test the JavaScript front-end automatically, saving time and making continuous integration that much easier.

16. Big Pipe in Core

With Big Pipe part of Drupal core, developers can optimize the site load performance for the end-user significantly. While this feature has nothing to with actual performance and is only perceived, it’s a great feature to have since the end user is able to see a difference in site load times.

Enough Drupal 8 features to think about?

These 16 Drupal 8 features are some of the most important reasons that this upgrade is so worth celebrating; it’s the collective work of over 3,000 contributors. But more importantly to you, this might be that big, bright answer you’ve been searching for.

Got Drupal 8 your mind?

More Drupal 8 resources:

This article was originally published in July, 2014. It has since been updated.

May 12 2016
May 12


A content management system, or CMS, is a web application designed to make it easy for non-technical users to add, edit and manage a website. We use WordPress and Drupal the most for CMS development, but it is all dependent on our clients’ needs. Not only do content management systems help website users with content editing, they also take care of a lot of behind the scenes work.

Whenever it comes to developing a website from scratch, and for a client who wants to be able to manage the site after the launch it is important as a developer to find a tool that the client will be able to use. When we think about web development it’s always better for the client and for the company to find a good content management system or CMS, because it solves problems that you will never have to worry about from the UI of the backend to the front-end wanted features it solves a lot of issues upfront that you will not have to worry about later.  As a website evolves, it will never stay in the final version you delivered to your client, when we develop we need to always think to the site’s future.

WordPress is one of the most popular tools because it is very adaptable. The amount of plugins (solutions to your problems) are endless. Not only does it have great features but it has a friendly UI backend. All of the advantages mentioned lower the development time, which helps the client to lower their costs. In short, WordPress saves time and money! The most recent example is our very own website Mobomo.

Another resource for a CMS is Drupal. Drupal may be a little more difficult to develop with because it can handle bigger sites with much more data and a ton of users but this system is better for newspapers or government sites such as NASA. 

Each CMS will have their own advantages but our first priority is making it adaptable to the client’s needs.

Drupal 8 Entity Validation and Typed Data Demonstration

Mar 31 2016
Mar 31

Drupal 8 Entity Validation and Typed Data Explained

Mar 29 2016
Mar 29

Theming Views in Drupal 8 – Custom Style Plugins

Mar 23 2016
Mar 23

Tutorial on Using Drupal 8 Plugin Derivatives Effectively

Jan 19 2016
Jan 19
Jan 04 2016
Jan 04


What if we had a Drupal theme that does exactly what we want? No more divs, in divs, in divs. No more weird css. Out of the box responsiveness, both adaptive as fluid. Debuggers, good javascript additions, Gulp. Maybe even a little styleguide generator.

That’s what we thought when we started working on our own custom Drupal starter theme in July 2013. We called it “FortyTwo”.

A brief history

Before we we started working with FortyTwo, we did theming, like many others, based on the Zen or Omega base themes. It worked, it got us where we wanted, but it had its downsides. Besides Zen we also looked at Omega and other major base themes. They all had their pros but also a lot of cons.

During a talk I had with one of the frontenders at Finalist about this we started to think: Why not create our own theme. Let’s combine all of the pros from all those themes to one, and maybe add some other nifty features.

The start

The first ever site we developed with FortyTwo, and the site that actually developed a big part of FortyTwo was the Finalist website. Back then it was a good starting point for us to develop website frontends the way we wanted to. Combined with good backend developers we could start working on good frontends.

Finalist.nl websiteThe Finalist website as built with FortyTwo

Because we developed FortyTwo as a base theme for Drupal we could use it to create all kinds of different websites, no matter the shape or size.


Let me enumerate some of the best features FortyTwo has right now:

  • SASS; FortyTwo has completely been made using the SASS css preprocessor.
  • Drush integration; Easily create your sub theme using our custom drush command.
  • Out of the box responsiveness; Without no effort themes developed using FortyTwo are responsive. Both adaptive or fluid. Extending the responsiveness is easy by just copying some files. Want to change the breakpoints? They are defined in the sass settings file.
  • Gulp; We have added gulp support for some extra features.
    • SASS watch and compiling with auto prefixes for IE8 and IE9.
    • JSLint integration, while watching the theme folder the console will output errors or warnings from JSLint if there are any.
    • Uglify of JavaScript files.
    • Clearing of Drupal cache on changes in PHP, include or info files in the theme.
    • And last, but not least automatic reloading of the browser on file changes.
  • Icomoon integration; For easy development we have created a starter set of icomoon icons and added them to the theme. You can easily extend those icons and use theme using our custom icomoon SASS mixin.
  • Layout styles; It is possible to choose different styles of layout, whether you want your content column on the left, right or the middle, it is just a setting;
  • Debuggers; We have added some handy debuggers in FortyTwo:
    • It is possible to show the grid on the background of the page. The grid uses the settings set in the sass settings file.
    • It is possible to show a responsive identifier. This makes it easier to create responsive websites. A bar at the bottom of the website shows you on what breakpoint you currently are viewing.

Debuggers in actionThe above image shows the mentioned debuggers in action.

There is more, but you have to see for yourselves what FortyTwo can offer you!

Drupal 8

Since August 2015 we have also started developing the Drupal 8 version of the theme. Since Drupal 8 is becoming the new standard we wanted to be ready for it when it came out. On the date Drupal 8 was officially released FortyTwo was already finished and is now in active development.

I will write a separate blog about the porting of FortyTwo from Drupal 7 to Drupal 8 on a later date.

How about the future?

We are still in active development. Since the release of FortyTwo-8.x-1.0 Only bugfixes and really nice features are added to the Drupal 7 version of FortyTwo. Other new features are only added for Drupal 8.

On the roadmap are:

  • KSS; Knyle Style Sheets integration. Using KSS you can automatically create style guides from CSS and SASS.
  • FortyTwo admin theme; Admin themes are always difficult to pick. Because we work with a lot of clients, different kinds of content and content managers we believe that we can create a admin theme (of course based on FortyTwo) that suits the needs of everybody.
  • FortyTwo example theme; Since the start of development we always wanted to create a example theme that everybody can use, out-of-the-box.

Get involved!

Yes, we would love to see you around on the project page and the issue queue ! We heavily depend on your input, testing and feedback, but also on your commitment as a community developer, by helping us implementing new features and fixes.

Dec 21 2015
Dec 21

For the last 6 months I’ve been helping Dick and Andrei with a number of Drupal modules to enhance the management of content.


This module enhances the Drupal core Entity API by making all content entities revisionable. Revisions are enabled by default and not optional. This means that edits to users, comments, taxonomy terms etc are created as new revisions.

Another ground breaking advance is that deleting any of these entities now just archives it. Delete is a flag in the entity object, and just like any other update, it creates a new revision.

The concept of workspaces has also been added, this allows for a new instance of the site, from a content perspective, can be created. An example use case for workspaces would be to have a dev, stage and production workspace, and move content between them as it gets promoted through the workflow.


Now that deleting content entities just means a new revision marked as deleted we need a way to recover or purge them. The trash module is a UI on top of Multiversion allowing users to do just this.

Relaxed Web Services

Drupal 8 has always been about getting off the island, Relaxed Web Services furthers this by getting content off the island. It uses Drupal core’s REST API to expose CouchDB compatible endpoints. This means that replicating content is just a case of using CouchDBs replicator. Then creating a decoupled Drupal site is as simple as using PouchDB.

This works really well with Multiversion’s Workspaces, where each workspace is exposed as a separate CouchDB database.

CouchDB Replicator

So that we don’t need to depend on CouchDB for replication, the replicator has been rewritten in PHP. This will allow us replicator content from within Drupal or even via Drush.


There is a long history for Deploy in Drupal, but now in Drupal 8 it’s little more than a UI for the PHP based CouchDB replicator. It allows replication of content between workspaces, between Drupal sites, and between CouchDB databases.


Something we’re currently working on is Mango, inspired by MongoDB and based on Cloudant’s implementation for CouchDB. Mango will allow querying for content entities over the Relaxed Web Services API. This is going to be very interesting to those creating decoupled sites because PouchDB supports the same querying API.

Please enable JavaScript to view the comments powered by Disqus.

blog comments powered by
Nov 18 2015
Nov 18

This Thursday is the long awaited release date for Drupal 8, the newest version of the leading Open Source CMS. It’s packed with big improvements, and the new version represents a big leap forward for the future of the CMS. There is a better mobile experience, a new services layer for delivering “content-as-a-service,” easier deployment management, and, of course, Drupal 8 has made a big architectural shift under-the-hood to a more object-oriented model that professional developers will love.

But the biggest question everyone is asking about Drupal 8 right now *isn’t* “how great is Drupal 8 going to be?” but rather “should I use Drupal 7 or Drupal 8 for my project right now?”

Here’s our big advice. First, don’t panic. Organization’s should not feel any urgency to move from Drupal 7 to Drupal 8 in the immediate term. Why?

What makes Drupal amazing is it’s ecosystem of thousands of open source modules that easily extend the “core” functionality of the platform. Looking to integrate your website deeply with Salesforce CRM? There is a module for that. Want sophisticated online community functionality? There is a module for that too. The release of any major version of Drupal requires the maintainers of those modules to update their code, and that will take some time.

During its first 6 to 9 months of existence, Drupal 8’s ecosystem of contributed modules will have a smaller collection of available modules than Drupal 7, and those modules, because they are brand new, *will* have issues that require time and effort to patch, debug, and make function. Right now, the amount of time and energy required to do that work is almost impossible to determine accurately – other than it is certain to be there.  By early Q3 of 2016, we expect to have a far more solid understanding of that timeframe – and Drupal 8 and it’s contributed modules will have had the benefit of a few updates and some real-world use.

If you launch anything but the simplest of sites at any time in 2016 prior to Q3 –

  • It will be less expensive to create on Drupal 7 than on Drupal 8.
  • It will likely not need to be updated to Drupal 8 until 2019/2020 – which is in line with most site redesign cycles.

This is the pattern we’ve seen with previous major releases of Drupal – Drupal 5 to Drupal 6, Drupal 6 to Drupal 7: Sites (of any meaningful complexity) built within the first 9 months of a major Drupal release will require more effort to create, and have higher risks of unforeseen issues that need effort to overcome than simply building on the previous release.

One caveat is that for “simpler” sites, Drupal 8 will be more suitable immediately upon it’s release. Why – because many of the “key modules” that were previously contributed modules, are now a part of Drupal 8 core.

So, what does that all mean for my project? Here’s our frank take on when to stick with Drupal 7 and when to make the move to Drupal 8 for your project:

If you need to deploy your site in the first half of 2016, use Drupal 7 unless:

  • You have no (or very limited) integration requirements with CRM, authentication, or other systems. Modules to watch: Salesforce, LDAP, other mature integration modules. 
  • You have no customized publishing workflows. Modules to watch: Workbench and other moderation modules 
  • You do not need sophisticated ‘community’ functionality. Modules to watch: Organic Groups
  • You do not need drag and drop/sophisticated layout manipulation for non-techies on your project. Modules to watch: Panels, IPE, Panelizer
  • You have significant multi-lingual needs. Drupal 8 might be a better choice because of the improvements to internationalization and their inclusion in Drupal Core.
  • You want to accelerate the development of Drupal 8 contributed modules in any of the areas above.
  • Your site meets the conditions above, and your goal is for your development team to gain experience and insight into the platform

For more information on taking the stress out of upgrading your website to Drupal 8, check out our December 3rd webinar “Drupal 8 for Decision Makers.” Do you have a project that’s happening in this timeframe and still have questions? Drop us a line!

Don’t forget to read our other featured blogs for this week’s launch of Drupal 8, “What’s Your Drupal Upgrade Path?” and “Upgrading to Drupal 8: A Planning Guide.

And that’s our Drupal 8 cheat sheet!

Previous Post

Upgrading to Drupal 8: A Planning Guide

Nov 17 2015
Nov 17

Co-written by: Jess Snyder,  Senior Manager, Web Systems at WETA
A year ago, Andrew wrote that the Drupal 8 decision was coming, and advised folks to plan.  Around that time, he talked to folks about their plans, many replied, “my plan so far has been to put my fingers in my ears and say, “la, la, la, la…” Well, it’s time to remove your fingers from your ears and kick your strategic planning into high gear. Drupal 8 is officially released this week!

While there’s no reason to panic (unless you are Drupal 6, then it is time to get into gear), you do need to plan. Although Drupal 7 will be officially supported for quite some time, developer enthusiasm and attention is already shifting to Drupal 8. While security updates will continue, new features and innovation are definitely going to be focused on Drupal 8, and in time, fewer and fewer developers will be adept at maintaining or improving a Drupal 7 site.

In short, unless you are an early adopter, our recommendation is to begin planning your upgrade now, so you are prepared to move Drupal 8 as soon as late 2016. That means that you should get your house in order and prepare your budget requests now.

What does a Drupal 8 plan look like?

A solid plan includes a consideration of the following:

  • Context
  • Content
  • Platform
  • Resources
  • Budget

Let’s consider each one in turn.

Step 1: Consider Your Context

Before you even think about software, consider where your organization or project exists in your world.

Is your organization considering a re-branding? Are you planning a new communications campaign? Are you about to seek a new round of funding? All of these questions affect how and when and how you should move to Drupal 8.

Too often, organizations consider a technical change outside of the broader context of their overall communications plans. Ask yourself: “What do I want my website to achieve?” – in real terms, not simply in terms of what will impress your boss or board.  You should have goals that are more mission-focused that simply “make the site easier to use” or “work better on mobile.”

If you are considering updating your project or organization’s visual expression, you should make sure that this is established before you start the project. Drupal 8 has a new Twig-based templating engine, so you will need to re-theme the entire site even if you wish to retain your site’s existing design. This means that fonts, page headings, page footers, color assignments, form stylings, mobile-friendly styles – everything about your site’s overall “look and feel” – will need to be re-created as part of a Drupal 8 migration. Don’t make the mistake of coding in your old style only to have to re-theme it again later.

Considering your organizational priorities will also make it easier to make the case that the upgrade is necessary. If you are a Drupalist or technical staffer, you already know in your heart that a Drupal 8 upgrade is the right move for your organization. But chances are, you will need to convince non-technical decision-makers who won’t be swayed by all of Drupal 8’s cool new features. Being able to align the technical upgrade with your organization’s overall strategy can help you avoid potential delays or derailments.  

If you do your homework, you will be in a good place to argue for an upgrade.  Here’s a checklist to jump-start your digital project.

Step 2: Catalog Your Content

An upgrade to Drupal 8 also represents an opportunity to re-think your content. When you move to a new house, it’s best practice to go through your belongings and separate them into piles: “keep,” “donate,” “trash,” and “repair.”

Take a similar approach when planning your upgrade project. As my colleague blogged, you need to ask yourself four questions: How much content do I have? How good is it? What’s missing? Who can fix it?

A content audit will provide you a clear view of which content types are in use, which ones are valuable, and which ones could be deprecated. Next, evaluate your content’s quality by checking the data. To determine what’s missing, talk to your stakeholders – department heads, content owners, and perhaps even your audience. Finally, assign missing or poorly-written content to the appropriate experts or copywriters.

Pruning your content  will save time and money during the upgrade. For instance, perhaps your communications department has decided that it no longer needs press releases listed on the site. By eliminating that type of content, that’s one less content type to migrate and one less view to be re-created.

Likewise, ask yourself,  “are my content types still getting the job done?” For example, a process or workflow that was required when you originally launched your site may no longer be current practice. Ask your content editors whether there are pain points when they edit and update your existing site. Is there a way to improve their authoring experience during the upgrade?

This is also an opportunity to break apart a large site into smaller, more manageable chunks. For instance, on Jess’s site, weta.org, she is considering whether she might rebuild the WETA Press Room separately from the main Drupal instance. This will isolate that subsite’s special functionality and give her practice building a Drupal 8 site before tackling the larger project, while at the same time making that larger project less complex.

This is also the time to consider whether there are pieces of functionality that had been incredibly important, but may no longer make sense. For example, there are incredibly complex rules that govern how playlists are displayed on weta.org. Before rebuilding that functionality in Drupal 8, Jess plans to confirm with her legal department  that those rules are still in effect.  If your site has similar bits of legacy functionality that are no longer relevant, put those in the recycle bin. There’s no sense in bringing low-value functionality into your new D8 site.

Step 3: Evaluate Your Platform

On modern smartphones, you can tap an “upgrade” button, set it down, and return to a fresh interface and new features in less than an hour.

Your Drupal 8 upgrade will be nothing like this.

Make no mistake, a move to Drupal 8 is more of a re-build than a simple upgrade.  While your content, users, and other elements can be systematically moved over cleanly, you still will need to re-create your themes, install and configure modules, reconfigure views, and much more. The complexity of an upgrade is determined by the complexity – and quality – of your existing Drupal instance.

In addition, if your site is using any custom programming, those pieces will need to be ported manually to be compatible with Drupal 8’s new API.

Therefore you need to evaluate the state of your specific technical configuration. This will help with your budgeting. Here are some questions to ask:

  • Is your CSS is compiled?
  • Which modules you are using? Which ones are now in core? Which ones can be retired?
  • Do changes in best practices necessitate different modules or different approaches?
  • Are you using any custom programming?
  • Is your theme responsive, or will the design need to be adapted to work well within a responsive theme?
  • Are your analytics installed and configured correctly and usefully?
  • Are there any technical integrations between Drupal and other systems that will need to be re-established?

Consider whether your current Drupal solution is weighed down by complex functionality that serves just a portion of your site? For example, might you have a large number of community-focused modules simply because it needs to support community functions for a small slice of your audience? For example, Jess’ site supports moderated user authentication due to the requirements of just two small, low-traffic features. As part of the Drupal 8 upgrade, it may make sense to break these features into their own mini-site.

And here’s a more frightening question: Are your security patches current? If not, there is a high likelihood that your site has been compromised. Not only should you take steps to plug those holes  immediately, you will want to use the upgrade process to redouble your efforts keep things locked down.

If you can’t answer these questions on your own, consider getting a Technical Audit by a qualified consultant. Here’s someone who can help audit your site!

Step 4: Consider Your Resources

As we’ve said, it’s important to frame this to your peers as a rebuild, not an upgrade. This is the first step to making sure you have the resources you need.

Depending on your situation, a move to D8 will require the following capabilities (among others):

  • Audience Research
  • Content Strategy
  • Design
  • Copywriting
  • Front-end Development
  • Back-end Development
  • Information Architecture
  • Design
  • Analytics

Take an honest look at your staff. Consider how many of these capabilities are available to you in house. In addition, think hard about the weight of the task. A team that is capable of supporting and improving an existing solution may not be able to continue that support while taking on the sometimes substantial task of a major upgrade.

If your resources are not sufficient, you will need to find a partner in the form of skilled independent contractors or a trusted agency.

Step 5: Plan Your Budget

Budgets are prepared annually at most organizations, and this is not a small project that can be slipped into another line item. You should be thinking now as to whether your D8 upgrade will hit your 2016 budget or 2017 budget.

Budgeting for a technical project such as this is a challenging, multi-faceted exercise in the best of circumstances. Upgrade projects are even trickier because, at this writing, virtually no one  has prior D8 upgrade projects to reference as a baseline. Still, budgets must be planned, so plan we must.

Here are a few things to consider in your budgeting:

  • How many outside consultants will you need to engage and at what levels? (See step 4.)
  • How much strategic work must precede the migration?
  • How much creative work must precede the migration? (Do you have brand and visual identity guidelines?)
  • Which custom applications must be migrated?
  • How many content types must be migrated? The types of content are often more critical than the volume of content. (That is, knowing your site has content types for, say, press releases, blogs, and videos is more useful indicator than the actual quantity of each type.)
  • Which integrations are needed?
  • Have you budgeted for ongoing security patching?
  • How will the upgrade affect your hosting costs?

And with all these questions, the answers are easier if you are able to break larger projects into smaller ones.

Listening and Learning

Unfortunately, the fingers-in-ears strategy is not a viable solution. The tips in this article provide you a framework for your planning so you can get your organization in a good position to upgrade to Drupal 8 when it makes sense for you. In the meantime, there is a lot we can learn from each other. Keep your eyes and ears open!

If you have further questions about the Drupal 8 release and where your existing site fits into this, please get in touch and we’d be happy to talk it through with you. And for information on how to upgrade from Drupal 6, check out What’s Your Drupal Upgrade Path?

Previous Post

What’s Your Drupal Upgrade Path?

Building Custom cTools Plugins in Drupal 7

Oct 02 2015
Oct 02

Drupal 8 Third Party Settings and Pseudo-Fields

Sep 14 2015
Sep 14
Sep 11 2015
Sep 11

Reusable Forms in Drupal 8

  • Drupal 8 Custom Plugin Types

Drupal 8 comes with a great addition to the backend developer toolkit in the form of the plugin system. Completely new, specific to Drupal and evolved from serving only a few specific purposes, plugins have become the go-to system for reusable functionality in Drupal 8.

Drupal 8 logo

In this article series of two parts, we will use this system to build a feature that allows the use of custom forms together with node entities. After we’re done, we’ll be able to do the following:

  • configure node bundles to use one of multiple form types to be displayed together with the node display
  • easily define new form types by extending from a sensible base class

Because the topic is very well covered elsewhere, I will not go into the details of how plugins work. But do feel free to brush up on the theory before diving into the crux of it here. And if you want to take a look at the end result, the code we write in both articles can be found in this repository.

We will get started by creating our custom plugin type. To this end, we will have 2 interfaces and 6 classes. It sounds like much, but I assure you they are rather boilerplate and quick to set up. Then, in the next installment of this series, we will see how to use it for our reusable forms attached to nodes.

Plugin manager

Responsible for discovering and loading plugins, the most important part in any plugin type is the manager. However, it’s very simple to create one because Drupal already provides us with a sensible default base to extend. So in our module’s /src folder we can have this class inside a ReusableFormManager.php file (the de facto name of our plugin type becoming ReusableForm):

namespace Drupal\reusable_forms;

use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;

class ReusableFormsManager extends DefaultPluginManager {

public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
    parent::__construct('Plugin/ReusableForm', $namespaces, $module_handler, 'Drupal\reusable_forms\ReusableFormPluginInterface', 'Drupal\reusable_forms\Annotation\ReusableForm');
    $this->setCacheBackend($cache_backend, 'reusable_forms');

As I mentioned, our manager extends the DefaultPluginManager class and just overrides the constructor to call the parent one with some important information about our plugin type:

  • Plugin/ReusableForm – the subdirectory where plugins of this type will be found within any module
  • Drupal\reusable_forms\ReusableFormPluginInterface – the interface each of our plugins will need to implement
  • Drupal\reusable_forms\Annotation\ReusableForm – the annotation class that will define our plugin properties (such as ID, name, etc.)

Additionally, we create an alter hook which can be implemented by various modules to alter the plugin definitions and we set a key for our plugins in the cache backend. For more information about plugin managers, what they do and how they are set up, you should consult the documentation page available on Drupal.org.

Plugin interface

Next, let’s create that interface the manager expects all our plugins to implement. Inside a file called ReusableFormPluginInterface.php located in the src/ folder of our module, we can have this:


namespace Drupal\reusable_forms;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Component\Plugin\PluginInspectionInterface;

interface ReusableFormPluginInterface extends PluginInspectionInterface, ContainerFactoryPluginInterface {

   * Return the name of the reusable form plugin.
   * @return string
  public function getName();

   * Builds the associated form.
   * @param $entity EntityInterface.
   *   The entity this plugin is associated with.
   * @return array().
   *   Render array of form that implements \Drupal\reusable_forms\Form\ReusableFormInterface
  public function buildForm($entity);

This is a very simple interface that enforces only two methods: getName() and buildForm(). The first will return the name of the plugin while the latter is expected to be passed an entity object and to return a render array of a form definition that implements \Drupal\reusable_forms\Form\ReusableFormInterface (the interface we will set up for our actual forms). You’ll also notice that we are extending two other interfaces. Those provide us with some extra helpful methods and allow us to inject dependencies from the container.

Plugin annotation

As defined in the manager, let’s also set up our annotation class inside src/Annotation/ReusableForm.php:


namespace Drupal\reusable_forms\Annotation;

use Drupal\Component\Annotation\Plugin;

 * Defines a reusable form plugin annotation object.
 * @Annotation
class ReusableForm extends Plugin {

   * The plugin ID.
   * @var string
  public $id;

   * The name of the form plugin.
   * @var \Drupal\Core\Annotation\Translation
   * @ingroup plugin_translatable
  public $name;

   * The form class associated with this plugin
   * It must implement \Drupal\reusable_forms\Form\ReusableFormInterface.
   * @var string
  public $form;

Here we simply extend the default Plugin annotation class and define three properties (id, name and form). These will be the three keys found in the annotation of our individual plugins (we’ll see an example in part two of this series).

Plugin base

So far we have the core of what we need for our plugin type: a plugin manager that can discover new plugins using the annotation we defined and instantiate them with its default factory, i.e. the Container Factory.

Let us now lay the ground work for the plugins themselves by creating a base class all the plugins can/should/will extend. Inside the src/ folder of our module we can create a new file called ReusableFormPluginBase.php with the following abstract class inside:


namespace Drupal\reusable_forms;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Form\FormBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;

abstract class ReusableFormPluginBase extends PluginBase implements ReusableFormPluginInterface {

   * The form builder.
   * @var \Drupal\Core\Form\FormBuilder.
  protected $formBuilder;

   * Constructs a ReusableFormPluginBase object.
   * @param array $configuration
   * @param string $plugin_id
   * @param mixed $plugin_definition
   * @param FormBuilder $form_builder
  public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilder $form_builder) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->formBuilder = $form_builder;

   * {@inheritdoc}
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(

   * {@inheritdoc}
  public function getName() {
    return $this->pluginDefinition['name'];

   * {@inheritdoc}
  public function buildForm($entity) {
    return $this->formBuilder->getForm($this->pluginDefinition['form'], $entity);

There are a few things to note here. First, we are extending from the plugin base class provided by Drupal so that we get some useful functionality (the methods of PluginInspectionInterface are already implemented with sensible defaults). Second, we are implementing the interface we defined earlier. All of our plugins need to implement it so might as well take care of it here. Third, we are using dependency injection to load from the container the form_builder service we will need to build our forms. This is possible because our interface extends from the ContainerFactoryPluginInterface.

For more information about the service container and dependency injection in Drupal 8, check out one of my previous articles on Sitepoint.com.

As our interface dictates, we already take care of implementing the two methods right here in our base class. The getName() method will simply return the name of the plugin as defined in the plugin annotation. The buildForm() method, on the other hand, will use the form builder to build a form. For this it will use the class provided in the plugin annotation’s form key (which needs to be the fully qualified name of a class that implements our Form interface which we haven’t defined yet). In doing so, we also pass the $entity argument to the form (whatever that may be as long as it implements EntityInterface). This is so that the form that is being rendered on the node page becomes aware of the node it is being rendered with.

Form Interface

Our plugin type is pretty much finished. We can now provide some sensible defaults to the forms that will be used by these plugins. Inside src/Form/ReusableFormInterface.php we can have this simple interface:


namespace Drupal\reusable_forms\Form;

use Drupal\Core\Form\FormInterface;

interface ReusableFormInterface extends FormInterface {}

We are doing nothing here except for extending from the default Drupal FormInterface. We have it so that we can add whatever methods we need our forms to implement (currently none) and are able to identify forms that implement this interface as compatible with our plugins.

More from this author

Form base

Now that we have a form interface to implement, let’s also create a form base class that the rest of the forms can extend. Inside src/Form/ReusableFormBase.php we can have the following abstract class:


namespace Drupal\reusable_forms\Form;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

 * Defines the ReusableFormBase abstract class
abstract class ReusableFormBase extends FormBase implements ReusableFormInterface {

   * @var EntityInterface.
  protected $entity;

   * {@inheritdoc}.
  public function buildForm(array $form, FormStateInterface $form_state) {

    $build_info = $form_state->getBuildInfo();
    if ($build_info['args'] && $build_info['args'][0] instanceof EntityInterface) {
      $this->entity = $build_info['args'][0];

    $form['first_name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('First name'),

    $form['last_name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Last name'),

    $form['email'] = array(
      '#type' => 'email',
      '#title' => $this->t('Email'),

    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
      '#button_type' => 'primary',

    return $form;

As you can see, we are implementing the interface but we are also extending from the default Drupal FormBase class. And in this example we only have the buildForm method that returns a simple form with three fields and a submit button. You can do whatever you want here in terms of what you consider a good base form. Additionally though, at the beginning of this method, we are checking if an EntityInterface object has been passed as an argument when this form is built and setting it as a protected property. The classes extending this will be able to make use of this entity as long as they call the parent::buildForm() method first.


In the first part of this article series we focused on setting up our custom plugin type and getting it ready for use. In doing so we quickly went through this process and saw how our plugins are expected to work with the actual form classes. In the next part we will work on making it possible to display them together with the nodes. This means adding extra configuration to the node type entities and displaying the forms using pseudo fields managed as part of the regular content view modes. Stay tuned!

Aug 17 2015
Aug 17

In the first article on Drupal 8 module development we looked a bit at the routing aspect of this process. We’ve seen that creating pages with paths is now a matter of declaring routes that match up with controllers. The latter, as we’ve seen, can return a render array that gets interpreted into markup and displayed in the main content area of that page. However, did you know that under the hood, Drupal actually transforms that array into a Response object according to the dictates of Symfony’s HTTPKernelInterface?


In this article, I would like us to go deeper into the internals of Drupal 8 (and Symfony2) and look at what actually happens (and can happen) from the moment a request is made by a user to the one in which they see something returned in response. The example I mentioned above is just one direction this process can go in, and today we are also going to see other possibilities. The goal is to understand the flexibility of the system which in turn can help us build awesome applications.

Before going into it, I strongly recommend you check out this diagram which does an amazing job at synthesizing what is often referred to as the render pipeline. Though in my opinion it represents more than the name implies because the render system is only part of what’s depicted, albeit a big one.

Front controller (index.php)

It’s no secret that Symfony2 is now an important part of Drupal. The latter uses many of Symfony’s components, most importantly for this article the HTTPKernel and HTTPFoundation ones. Together they are responsible for encapsulating a user request, passing it to the application and then returning whatever comes back to the user in a consistent and OO way.

The HTTPKernelInterface (something you probably heard about also from other contexts) is what glues all of this together by taking in a Request object and always returning a Response one. A very simple but powerful concept.

This process is initiated inside the index.php file which starts by generating said Request object and passing it to the HTTPKernel::handle() method. The latter is then responsible for returning a Response object. At a high level, this is what happens both in a Drupal application as well as in a Symfony one (or any other that leverages the HTTPKernel component).

HTTPKernel and events

HTTPKernel is the heart of any Symfony based application. Its handle() method, as we saw, has a great deal of responsibility in preparing a response and it does so in a workflow driven by events. This makes for a very flexible application where the heavy lifting is always delegated to listeners of these events.

If you look at the diagram from earlier, you can see this workflow depicted in the second column, and it essentially represents the glue between Symfony and the Drupal side of things.

It starts with the first event called kernel.request. Subscribers to this event handle various tasks. But two very important ones in Drupal 8 are the format negotiation and routing. The first determines the type of response that needs to be returned (html, json, image, pdf, etc) while the second determines what the code responsible for handling this is (the _controller key of a route definition inside the routing.yml file). But like in most steps in this event workflow, if a listener returns a response object, the process skips most of the further steps (stops propagation) and goes straight to kernel.response.

The second event is kernel.controller which is called after the application knows which controller is responsible for handling the request. At this point, listeners can still perform some overriding operations on it. Closely following this step, the Kernel is responsible for resolving the arguments that get passed to the controller. One such operation in Drupal is loading objects based on IDs found in the request (for example nodes) and directly providing the controller with them. Then finally the controller gets called with the respective parameters.

The controller is responsible for returning a response of some kind. If it returns a Response object, the process skips to the kernel.response event. Listeners to the latter can perform last minute modifications on the object such as modifying headers or the content itself. And after getting it from the handle() method, the front controller uses the send() method on the Response object to send it back to the user and terminates the process.

symfony event workflow

Going deeper with render arrays

If the controller does not return a Response object, the Kernel fires one last event: kernel.view. Its subscribers are responsible for turning the result of the controller into an actual Response object. So this means that you have the option of returning from your controller any kind of object as long as you couple it with a VIEW event subscriber that turns that into a proper Response.

However, as we’ve seen in the example, most of the time controllers will return a render array. Usually this represents the page’s main content (similar to page callbacks in Drupal 7).

To handle this, Drupal 8 has a MainContentViewSubscriber responsible for transforming this array into proper Response objects. It does so by using a particular MainContentRenderer chosen during the format negotiation phase we’ve talked about before. And although there are a few such renderers already available, the default one used is the HtmlRenderer.


Since this is the most commonly used type of main content renderer, let’s go in a bit deeper and see how this builds the page.

One of the cool things about this step in the process is the concept of page variants.
This means that HTMLRenderer dispatches an event responsible for finding out which type of page is to be used to wrap the main content render array: RenderEvents::SELECT_PAGE_DISPLAY_VARIANT. By default, the SimplePageVariant is used unless the Block module is enabled. In that case the BlockPageVariant kicks in and allows the placement of the blocks in the regions around the main content. If you want, you can subscribe to this event in your own module and provide your own variant.

All of this happens within the prepare() method of the HTMLRenderer which supplies the renderResponse() method with a #type => 'page' render array that wraps the main content one. The latter two get in turn wrapped into a #type => 'html' render array which gets finally rendered using the Renderer class (the equivalent of drupal_render() in Drupal 7). The resulting HTML string gets added to the Response object and gets returned to the front controller.

Although this is a very high level overview of the process, this is basically what happens. Now we have a Response object which means the Kernel can dispatch its kernel.response event. And right after this, the front controller can send the Response back to the user and terminate the process.


In this article we’ve taken a journey into Drupal 8 (and Symfony2) internals by following the pipeline from a user request to the response the server returns. We’ve seen how Drupal 8 leverages the HTTPKernel and HTTPFoundation Symfony2 components and how it basically lives on top of them. Additionally, we’ve seen how the glue between them is made up of the events the Kernel dispatches to which Drupal subscribes for all of its functionality. Finally, we’ve seen how HTML pages are built and returned to the user with the help of the render pipeline.

I believe that understanding what is going on under the hood in a Drupal 8 application will allow you to create awesome applications by knowing exactly which entry points you have into this flow. And I believe that if you take away only one thing from this article, it should be the word flexibility. Because the flexibility for building exactly what we need in Drupal 8 far surpasses anything in Drupal 7. It has truly become modern.

Aug 10 2015
Aug 10

If you are a Drupal developer who has dabbled in theming older versions of Drupal (5, 6, 7) you understand why frustration is the trusty companion of any Drupal themer. Luckily, though, Drupal 8 promises so many improvements that even the Angry Themer is happy for a change. It is only natural we jump in and start looking at what these improvement are.

Drupal 8 logo

In this article, we will look at some of the more important changes to theming in Drupal 8. Although we will keep things simple and start from the basics, I do assume you have at least a bit of experience with theming in Drupal 7. And since theming is a big subject and this is just an introduction, you’ll find all sorts of links to more information that can help you out.

Starting up

As with custom modules, a new theme always starts with a folder and the obligatory .info.yml file inside (as opposed to the old .info file). These go in the root themes folder of the Drupal codebase (as opposed to the old sites/all/themes directory) and they should both have the same name (e.g. my_theme.info.yml within the my_theme folder).

Inside the .info.yml file we provide a few required keys:

name: Theme name
description: Theme description
type: theme
core: 8.x

All the rest are optional and come as needed. With this in place, you can already navigate to admin/appearance and enable the new theme or set it as default. You’ll notice that from the good ‘ol Bartik you now have a really naked theme in place. But the big difference from Drupal 7 is that you can easily start theming every aspect of your website.

A major improvement is that we now have an intermediary core theme called Classy which bridges the gap between the data output by the Drupal backend (usually the system module) and the actual themes. So what all the other available core themes do (and what you can as well) is use Classy as their base theme and override its templates:

base theme: classy

Alternatively, you can also not do this but copy all of its template files into your theme and you’ll end up at the same place. But you probably won’t need all those files (some might not need changing) so in my opinion it’s just better to use Classy as a base theme and just override what you need.

Although I won’t go into details, region definition is also quite an important aspect of a theme’s info.yml file:

  header: 'Header'
  content: 'Content'
  footer: 'Footer'

With this in place, inside your page.html.twig template file you can print these regions out like so:

{{ page.header }}

This is the Twig templating syntax you should start getting familiar with if you haven’t already.


By now I think everybody knows that Twig is the templating language used in Drupal 8. I won’t go into it too much because there are many resources out there with plenty of information about how Twig syntax can make themers forget all about PHPTemplate in no time.

But one important thing to keep in mind is that there are no more theme functions in Drupal 8. This means that all themable output is run through an html.twig file. We can still use hook_theme() to define reusable theme implementations, but they will now all use Twig files. And the cool thing is that these Twig templates are extensible. This means they can define only the necessary bits related to them and inherit the rest from their parent. Check out the Twig extends documentation for more information on what I mean.


I mentioned before how in Drupal 8 we are in full control over the markup of our site due to everything being neatly organised in template files within the Classy theme. So one of the next steps in building your theme would be overriding the html.html.twig and/or page.html.twig files to provide markup for your pages. Doing so, you get to play with semantic HTML5 markup because that is what Drupal 8 outputs by default.

All of these template files have documentation at the top with information about what variables you have available. Additionally, you can make use of various Twig filters and functions to manipulate this data straight from the template files. It is in fact recommended, for instance, to build translatable strings or urls straight in there rather than the preprocessor in order to maybe avoid unnecessary function calls (if these don’t actually end up being printed).

And speaking of preprocess functions, they do still exist. However, there is no longer a template.php file to put them in but rather a .theme PHP file (my_theme.theme) inside the root theme folder.

An interesting note about preprocessors is that in Drupal 8 we have to try to always prepare render arrays for the template file variables rather than final markup as we often do in Drupal 7. Of course, this is only if the data needs to be rendered and is not already just a simple string or something primitive like that. The point is to no longer call drupal_render() within our preprocessor functions but let the Twig magic handle that for us.


There are many improvements made also to debugging of theme information. By turning on Twig debugging (debug: true) inside the sites/defaults/services.yml file, you get a bunch of helpful HTML comments printed in the page source.

Theme debugging in Drupal 8

These allow you to see which template file is responsible for a particular piece of markup, where it is located and what theme suggestions you can use to override it. No more spending hours trying to figure out what to override. This is a great win!

Additionally, Twig comes with the dump() function which allows you to print out a particular variable to the page from Twig. However, if that is not enough for you, the Devel module comes with the kint() function that provides a better (traversable) variable inspection tool. This is the new Krumo.

Assets and libraries

The last thing we are going to cover here is the topic of assets (CSS and JavaScript files). A notable change is that Drupal 8 ships with jQuery 2.x alongside other modern frontend libraries like Modernizr, Backbone.js and Underscore.js. And if you ever had to work with jQuery in Drupal 7 you’ll understand why this is no small gain. Plus this means that IE8 and lower are no longer supported!

Additionally, Drupal 8 has adopted a SMACSS based CSS file organization and we have some [good architecture and best practices] (https://www.drupal.org/node/1887918#best-practices) in place as well. No more excuses for messy CSS in our theme!

One thing that trips people up in the beginning is that, for performance reasons, assets are no longer added indiscriminately to every page. So if that Ajax functionality you’re trying out doesn’t work, make sure Drupal has loaded the necessary scripts for it. You can do so by declaring them as dependencies to your own.

What’s great is that we now have a unified way of doing all of this across the entire development spectrum. We use libraries that contain both javascript and css files, which can have dependencies on other assets and which get #attached to render arrays. If you want them loaded on all pages, you can also add them to your theme’s info.yml file or implement hook_page_attachments() and add them like that. However, it is recommended to always attach libraries to render arrays to make sure your assets don’t get loaded unless they are really needed and that they are cached properly with the data they serve.


In this article we’ve looked at some of the more prominent changes to theming in Drupal 8. We’ve done so by taking a look at the starting point from which we create new themes and moved through some of the main topics related to this process. By no means, however, has this been a complete rundown of all the changes. I recommend keeping up to date with the documentation on Drupal.org (which is also constantly updating) and jump in the code yourself. It should be fun!

Jul 15 2015
Jul 15

Regardless of industry, staff size, and budget, many of today’s organizations have one thing in common: they’re demanding the best content management systems (CMS) to build their websites on. With requirement lists that can range from 10 to 100 features, an already short list of “best CMS options” shrinks even further once “user-friendly”, “rapidly-deployable”, and “cost-effective” are added to the list.

There is one CMS, though, that not only meets the core criteria of ease-of-use, reasonable pricing, and flexibility, but a long list of other valuable features, too: Drupal.

With Drupal, both developers and non-developer admins can deploy a long list of robust functionalities right out-of-the-box. This powerful, open source CMS allows for easy content creation and editing, as well as seamless integration with numerous 3rd party platforms (including social media and e-commerce). Drupal is highly scalable, cloud-friendly, and highly intuitive. Did we mention it’s effectively-priced, too?

In our “Why Drupal?” 3-part series, we’ll highlight some features (many which you know you need, and others which you may not have even considered) that make Drupal a clear front-runner in the CMS market.

For a personalized synopsis of how your organization’s site can be built on or migrated to Drupal with amazing results, grab a free ticket to Drupal GovCon 2015 where you can speak with one of our site migration experts for free, or contact us through our website.


SEO + Social Networking:

Unlike other content software, Drupal does not get in the way of SEO or social networking. By using a properly built theme–as well as add-on modules–a highly optimized site can be created. There are even modules that will provide an SEO checklist and monitor the site’s SEO performance. The Metatags module ensures continued support for the latest metatags used by various social networking sites when content is shared from Drupal.

SEO Search Engine Optimization, Ranking algorithm


Drupal Commerce is an excellent e-commerce platform that uses Drupal’s native information architecture features. One can easily add desired fields to products and orders without having to write any code. There are numerous add-on modules for reports, order workflows, shipping calculators, payment processors, and other commerce-based tools.



Drupal’s native search functionality is strong. There is also a Search API module that allows site managers to build custom search widgets with layered search capabilities. Additionally, there are modules that enable integration of third-party search engines, such as Google Search Appliance and Apache Solr.

Third-Party Integration:

Drupal not only allows for the integration of search engines, but a long list of other tools, too. The Feeds module allows Drupal to consume structured data (for example, .xml and .json) from various sources. The consumed content can be manipulated and presented just like content that is created natively in Drupal. Content can also be exposed through a RESTful API using the Services module. The format and structure of the exposed content is also highly configurable, and requires no programming.

Taxonomy + Tagging:

Taxonomy and tagging are core Drupal features. The ability to create categories (dubbed “vocabularies” by Drupal) and then create unlimited terms within that vocabulary is connected to the platform’s robust information architecture. To make taxonomy even easier, Drupal even provides a drag-n-drop interface to organize the terms into a hierarchy, if needed. Content managers are able to use vocabularies for various functions, eliminating the need to replicate efforts. For example, a vocabulary could be used for both content tagging and making complex drop-down lists and user groups, or even building a menu structure.



There are a few contributor modules that provide workflow functionality in Drupal. They all provide common functionality along with unique features for various use cases. The most popular options are Maestro and Workbench.


Drupal has a dedicated security team that is very quick to react to vulnerabilities that are found in Drupal core as well as contributed modules. If a security issue is found within a contrib module, the security team will notify the module maintainer and give them a deadline to fix it. If the module does not get fixed by the deadline, the security team will issue an advisory recommending that the module be disabled, and will also classify the module as unsupported.

Cloud, Scalability, and Performance:

Drupal’s architecture makes it incredibly “cloud friendly”. It is easy to create a Drupal site that can be setup to auto-scale (i.e., add more servers during peak traffic times and shut them down when not needed). Some modules integrate with cloud storage such as S3. Further, Drupal is built for caching. By default, Drupal caches content in the database for quick delivery; support for other caching mechanisms (such as Memcache) can be added to make the caching lightning fast.


Multi-Site Deployments:

Drupal is architected to allow for multiple sites to share a single codebase. This feature is built-in and, unlike WordPress, it does not require any cumbersome add-ons. This can be a tremendous benefit for customers who want to have multiple sites that share similar functionality. There are few–if any–limitations to a multi-site configuration. Each site can have its own modules and themes that are completely separate from the customer’s other sites.

Want to know other amazing functionalities that Drupal has to offer? Stay tuned for the final installment of our 3-part “Why Drupal?” series!

Jul 08 2015
Jul 08

why drupal

Regardless of industry, staff size, and budget, many of today’s organizations have one thing in common: they’re demanding the best content management systems (CMS) to build their websites on. With requirement lists that can range from 10 to 100 features, an already short list of “best CMS options” shrinks even further once “user-friendly”, “rapidly-deployable”, and “cost-effective” are added to the list.

There is one CMS, though, that not only meets the core criteria of ease-of-use, reasonable pricing, and flexibility, but a long list of other valuable features, too: Drupal.

With Drupal, both developers and non-developer admins can deploy a long list of robust functionalities right out-of-the-box. This powerful, open source CMS allows for easy content creation and editing, as well as seamless integration with numerous 3rd party platforms (including social media and e-commerce). Drupal is highly scalable, cloud-friendly, and highly intuitive. Did we mention it’s effectively-priced, too?

In our “Why Drupal?” 3-part series, we’ll highlight some features (many which you know you need, and others which you may not have even considered) that make Drupal a clear front-runner in the CMS market.

For a personalized synopsis of how your organization’s site can be built on or migrated to Drupal with amazing results, grab a free ticket to Drupal GovCon 2015 where you can speak with one of our site migration experts for free, or contact us through our website.


Drupal in Numbers (as of June 2014):

  • Market Presence: 1.5M sites
  • Global Adoption: 228 countries
  • Capabilities: 22,000 modules
  • Community: 80,000 members on Drupal.org
  • Development: 20,000 developers

Open Source:


The benefits of open source are exhaustively detailed all over the Internet. Drupal itself has been open source since its initial release on January 15, 2000. With thousands of developers reviewing and contributing code for over 15 years, Drupal has become exceptionally mature. All of the features and functionality outlined in our “Why Drupal?” series can be implemented with open source code.

Startup Velocity:

Similar to WordPress, deploying a Drupal site takes mere minutes, and the amount of out-of-the-box functionality is substantial. While there is a bit of a learning curve with Drupal, an experienced admin (non-developer) can have a small site deployed in a matter of days.


Information Architecture:

The ability to create new content types and add unlimited fields of varying types is a core Drupal feature. Imagine you are building a site that hosts events, and an “Event” content type is needed as part of the information architecture. With out-of-the-box Drupal, you can create the content type with just a few clicks–absolutely no programming required. Further, you can add additional fields such as event title, event date, event location, keynote speaker. Each field has a structured data type, which means they aren’t just open text fields. Through contrib modules, there are dozens of other field types such as mailing address, email address, drop-down list, and more. Worth repeating: no programming is required to create new content types, nor to create new fields and add them to a new content type.


Asset Management:

There are a number of asset management libraries for Drupal, ensuring that users have the flexibility to choose the one that best suits their needs. One newer and increasingly popular asset management module in particular is SCALD (https://www.drupal.org/project/scald). One of the most important differences between SCALD and other asset management tools is that assets are not just files. In fact, files are just one type of asset. Other asset types include YouTube videos, Flickr galleries, tweets, maps, iFrames–even HTML snippets. SCALD also provides a framework for creating new types of assets (called providers). For more information on SCALD, please visit: https://www.drupal.org/node/2101855 and https://www.drupal.org/node/1895554


Curious about the other functionalities Drupal has to offer? Stay tuned for Part 2 of our “Why Drupal?” series!

Jun 10 2015
Jun 10

One of the things that makes Drupal great is its flexible user permission system. The out of the box permissions grid we are all familiar with covers most uses cases of controlling what users can and cannot do. It is also very easy for module developers to create new permissions and roles that restrict the logic they implement.

Drupal logo

Nevertheless, I have encountered a practical use case where the default configuration options are not enough. Namely, if you need to have multiple users with access to edit a particular node of a given type but without them necessarily having access to edit others of the same type. In other words, the next great article should be editable by Laura and Glenn but not by their colleagues. However, out of the box, users of a particular role can be masters either of their own content or of all content of a certain type. So this is not immediately possible.

In this article I am going to show you my solution to this problem in the form of a simple custom module called editor_list. Article nodes will have a field where you can select users and only these users (or those who have full access) will be able to edit that particular node. You can find the module already in this git repository and you can install it on your site for a quick start. Do keep in mind that it has a dependency on the Entity Reference module as we will see in a minute.

I will keep the code comments to a minimum to save space but you can find them in the repository if you want. Basic knowledge of Drupal 7 is assumed in the remainder of this tutorial.


We first need the editor_list.info file for our module to get us going:

name = Editor List
description = Module illustrating a custom solution for having multiple editors on a node.
core = 7.x
dependencies[] = entityreference

Next, we need our editor_list.module file where most of our business logic will be located. So go ahead and create it and we will populate it as we go on.

Finally, though not covered here, we can have an editor_list.install file where we can implement hook_install() and hook_update hooks to create fields and/or deploy configuration. In the repository, you’ll find that I provided an install hook that already creates an entity reference field called field_editors and attaches it to the Article content type. If you are following along but not using the code in the repository, you should go ahead and create the field manually through the UI. It’s a simple field that references User entities and allows for unlimited selections. Nothing major.

Node access

Going back to our .module file, it’s time to implement our access logic. First though, to make things as flexible and reusable as possible, let’s have a simple function that returns an array of node types to which we apply our access logic:

function editor_list_node_types() {
  return array('article');

Since we are only targeting articles, this will suffice. But we will use this function in multiple places so in case we need to target other types as well, we just have to update this array.

Next, let’s write another helpful function that returns all the user IDs set in the editors field of a given node. We will also use this in multiple places:

function editor_list_uids_from_list($node) {
  $users = field_get_items('node', $node, 'field_editors');

  $allowed_uids = array();
  if ($users) {
    $allowed_uids = array_map(function($user) {
      return $user['target_id'];
    }, $users);

  return $allowed_uids;

I believe the function is quite self explanatory so I won’t go into details here. Instead, we can turn to our hook_node_access() implementation that gets called by Drupal whenever a user tries to do something with a node (view, edit or delete):

 * Implements hook_node_access().
function editor_list_node_access($node, $op, $account) {
  $node_types = editor_list_node_types();

  if ( ! is_object($node) || ! in_array($node->type, $node_types) || $op !== 'update') {

  $allowed_uids = editor_list_uids_from_list($node);

  if (empty($allowed_uids)) {

  if (in_array($account->uid, $allowed_uids)) {

So what’s happening here?

First, we use our previously declared helper function to get the list of node types we want to target, and we basically ignore the situation and return if the node type of the currently accessed node is not within our list or if the operation the user is attempting is not of the type “update”. Then we use our other helper function to check if there are any users in the editor list for this node and again ignore the situation if there aren’t. However, if there are, and our accessing user is among them, we return the NODE_ACCESS_ALLOW constant which basically gives the user access to perform the attempted operation. And that’s it.

You can check out the documentation for more information about how this hook works.

Let’s say you have admin users who can create and edit any type of content and regular authenticated users who cannot edit articles (apart from maybe the ones they created themselves). Adding one of these latter users to a node’s editor list would give them access to that particular node. And another great thing is that since this is all nicely integrated, contextual filters and tabs also take these dynamic permissions into account.

Field access

We now have a working module that does what I initially set out for it to do. But let’s say that your admin users are the only ones responsible for adding users to the editor lists. In other words, you are afraid that if your editors can edit their nodes and remove themselves from the list, they’ll get locked out of the node they are supposed to work on.

To account for this situation, we need to implement a field access check and remove the possibility that editors tamper with that field. Implementing hook_field_access should do the trick nicely. And if you are wondering, this hook is similar to hook_node_access() but is responsible for individual fields rather than the entire node (+ a couple of other small differences).

 * Implements hook_field_access().
function editor_list_field_access($op, $field, $entity_type, $entity, $account) {
  $node_types = editor_list_node_types();
  if ($entity_type === 'node' && is_object($entity) && in_array($entity->type, $node_types)) {
    return editor_list_control_field_access($op, $field, $entity_type, $entity, $account);

And here we have it. There are a few more parameters because this hook gets called for all entities, not just nodes. But again, we check if the currently accessed node is one of those we defined earlier (and that the entity is in fact a node) and this time delegate to another function to keep things tidier:

function editor_list_control_field_access($op, $field, $entity_type, $entity, $account) {
  if ($op !== 'edit') {

  $uids = editor_list_uids_from_list($entity);
  if (!in_array($account->uid, $uids)) {

  $deny = array('field_editors');
  if (in_array($field['field_name'], $deny)) {
    return false;

Since we only care if the user is trying to update a particular field, we return nothing if this is not the case. Keep in mind that the op string here is edit and not update as it was in the other hook. This is just one of those Drupal quirks of inconsistency we all came to love so much. And like before, we ignore the situation if the current user is not part of the editor list.

Then, we define an array of field names we want to deny access to (in our case only one but we can add to it depending on the use case). Finally, we return false if the currently accessed field is part of our $deny array. Yet another difference here in that we have to return a boolean instead of a constant like we did before.

Now the editors in the list of a given node cannot remove themselves or add anybody else to the list. But then again, in some cases you may want this functionality and in others not. It’s up to you.

Tidying up

The last thing I am going to show you here relates to organization and maybe a bit of user experience. With our current implementation, the editor list field on the Article nodes is present somewhere on the form (wherever you dragged-and-dropped it when editing the field settings). However, wouldn’t it be nice if it were automatically part of the Authoring information group at the bottom of the page? Something like this:

Drupal 7 multiple editors per node

I think so. Let’s see how we can do that.

First, we need to implement hook_form_alter or one of its variations. I prefer the most targeted one to avoid unnecessary calls to it and a bunch of conditional checks:

 * Implements hook_form_BASE_FORM_ID_alter().
function editor_list_form_article_node_form_alter(&$form, &$form_state, $form_id) {
  $form['#after_build'][] = 'editor_list_node_form_after_build';

We went with the BASE_FORM_ID of the article nodes here so if we extend our application to other types we would do the same for those as well. Inside, we just define an #after_build function to be triggered when the form has finished building. This is to ensure all the form alterations have been already done by contributed modules. All that is left to be done is to write the function responsible for making changes to the form:

function editor_list_node_form_after_build($form, &$form_state) {
  $field = field_info_field('field_editors');
  if ( ! field_access('edit', $field, 'node', $form['#entity'])) {
    return $form;

  if ($form['author']['#access'] === 0) {
    return $form;

  $field_editors = $form['field_editors'];
  $field_editors['#weight'] = 0;
  $form['author']['additional_authors'] = $field_editors;
  $form['field_editors'] = array();

  return $form;

This looks complicated but it really isn’t. We begin by loading the field definition of our editor list field. This is so that we can run the field_access check on it and just return the form array unchanged if the current user doesn’t have access to the field. Next, we do the same if the current user does not have access to the author group on the form (this is the Authoring information group we want to place the field into). And lastly, we make a copy of the field definition, change its weight and place it into the group, followed by unsetting the original definition to avoid having duplicates.

And that is pretty much it. Now the editors list field should be tucked in with the rest of the information related to authorship.


In this article, we created a solution to a content editing problem that Drupal 7 could not fix out of the box. However, it did provide us with the development tools necessary to make this an easy task inside of a custom module.

We now have an editor list field on the article node form by which we can specify exactly which users have access to that particular node. Though do keep in mind that in order for this to be of any use, the users you add to these lists must not have a role that allows them to edit all article nodes. Otherwise you won’t see much of a difference.

Jan 27 2015
Jan 27

I decided to write this article after reading The Decline of Drupal, or How to Fix Drupal 8 by Mike Schinkel. I am not a Drupal person at all, but what is discussed here is quite close to discussion I had with my friends from the Plone community, and I am quite sure it is not restricted to those 2 CMS.

The question here is how to preserve popularity (or maybe just approachability) when we decide to restrict hackability.

And just to make clear what "hackable" means, I will just quote Jennifer Lea Lampton (already quoted in Mike's article):

Back in the day, Drupal used to be hackable. And by "hackable" I mean that any semi-technical yahoo (that's me, btw) who needed a website could get it up and running, and then poke around in the code to see how it all worked. The code was fairly uncomplicated, though often somewhat messy, and that was fine. At the end of the day, it did what you needed.

A CMS story

In the beginning was the Hack

When a CMS is still young, it is still light and fresh, not heavily structured, hence it can be hacked in many ways. Hacking is even probably the official way to use it. And that is precisely what is fun and attracting about it. That is what might turn it into a success.

The first versions of Plone were so easy to hack, we had something we named TTW, standing for Through-The-Web, and designating a fantastic feature of Zope (the Plone application server) allowing to code scripts, templates or even classes directly from the web interface. It was great because it allowed a very large audience to be efficient with Plone.

I guess Drupal had also very attractive hacking possibilities like the Drupal hooks.

To hack or not to hack

But soon, some developers point that such hacking is probably not a good idea. They say hacking might seems smart and efficient and productive, but that is in fact the very opposite. It makes maintainability more difficult, it makes upgrades or migration sometimes totally impossible, it does not conform to the programming standards and best practices.

And they are actually right. But saying so (and being right) is obviously not enough to make people stop hacking.

Nevertheless a gap appears, and new versions are not as hack-friendly as it used to:

- "Hey, I cannot do that anymore!",

- "Right, but if you were doing it the right way, you wouldn't have to do it this way",

- "Mmmmokay...".

You shall not hack

You shall not passA CMS is continuously evolving, its users expect it to be able to provide the cool new features invented on the web last week, and its developers want it to integrate the bright new frameworks invented on GitHub last month.

At some point, it is quite clear that offering hackabilty restricts its capacity to evolve, and endangers the system. To be able to survive to all the needed changes, it must rely on a strong and strict architecture.

And a version is released where hackabilty is banished (that's what Drupal 8 is about, right? I guess we did it with Plone 3, even if it is not that clear).

I want my hack back

This is probably a wise technical decision, and the core developers are very proud of it. The system is clean now, and we can confidently face our future challenges.

But it is also a very very impopular decision. A big part of the developers were using the hack way because they cannot afford investing time to learn the straight way, some of them do not even understand why the so called "straight way" is that better than their usual way.

By trying to make our CMS better, hence more attractive, we made it impopular. That is really unfortunate.

And if some of those disappointed people consider moving to another solution, ideally a brand new CMS still its early happy-hacking age, I have a bad news for them: there will be no new CMS (see my post Why CMS will not die).

Hacking is not a bug, it is a feature

The problem here is a severe misunderstanding.

Of course, on the development point of view, hackability can be considered as a flaw and a danger, but that is not the proper point of view here. We must consider it with the usage point of view, and regarding usage, hackability is a very valid use case.

It is even a major use case, and our CMS must preserve it, or it will be endangered.

Nevertheless, I agree that banishing hackability from the core is a good decision. So how do we manage that?

That is simple: we just produce a clean/straight/unhackable core, and we implement hackability on top of it as a feature.

Implementing hackability means offering tools to deeply change the behaviour or the appearence of our system without messing with its underlying architecture.

That is what Plone proposes with the Diazo theming tool: as theming was involving too many Plone knowledge, it was unapproachable for non-Plone integrators, so we provide a theming proxy which dynamically injects a static design on any Plone page using a simple set of rules, and it is entirely controlled from a nice web UI.

That is also my objective with Plomino, so people can easily create a custom application that will work in their Plone site without learning about complex frameworks.

But there are of course many other fields to cover.

It is not easy, because building a tool able to provide as much flexibility as code hacks is a complex challenge, but that is the only way to keep our CMS valid (and to keep it fun too), hence to keep our audience.

Dec 17 2014
Dec 17

Taming Content coverThe final issues of 2014 is out!  Our theme this month in “Taming Content” with features on WordPress, Drupal, and ProcessWire. Also read about PHP tricks, Queues with Laravel, the SoundCloud API, and Community News!

Check out the full magazine details page for more details, Download the Advanced Custom Fields article for free to sample an article.

Oscar still remembers downloading an early version of the Apache HTTP server at the end of 1995, and promptly asking "Ok, what's this good for?" He started learning PHP in 2000 and hasn't stopped since. He's worked with Drupal, WordPress, Zend Framework, and bespoke PHP, to name a few. Follow him on Google+. Tags: , , , , , ,
Dec 15 2014
Dec 15

Angular.js is the hot new thing right now for designing applications in the client. Well, it’s not so new anymore but is sure as hell still hot, especially now that it’s being used and backed by Google. It takes the idea of a JavaScript framework to a whole new level and provides a great basis for developing rich and dynamic apps that can run in the browser or as hybrid mobile apps.


In this article I am going to show you a neat little way of using some of its magic within a Drupal 7 site. A simple piece of functionality but one that is enough to demonstrate how powerful Angular.js is and the potential use cases even within heavy server-side PHP frameworks such as Drupal. So what are we doing?

We are going to create a block that lists some node titles. Big whoop. However, these node titles are going to be loaded asynchronously using Angular.js and there will be a textfield above them to filter/search for nodes (also done asyncronously). As a bonus, we will also use a small open source Angular.js module that will allow us to view some of the node info in a dialog when we click on the titles.

So let’s get started. As usual, all the code we write in the tutorial can be found in this repository.


In order to mock this up, we will need the following:

  • A custom Drupal module
  • A Drupal hook_menu() implementation to create an endpoint for querying nodes
  • A Drupal theme function that uses a template file to render our markup
  • A custom Drupal block to call the theme function and place the markup where we want
  • A small Angular.js app
  • For the bonus part, the ngDialog Angular module

The module

Let us get started with creating a custom module called Ang. As usual, inside the modules/custom folder create an ang.info file:

name = Ang
description = Angular.js example on a Drupal 7 site.
core = 7.x

…and an ang.module file that will contain most of our Drupal related code. Inside this file (don’t forget the opening <?php tag), we can start with the hook_menu() implementation:

 * Implements hook_menu().
function ang_menu() {
  $items = array();

  $items['api/node'] = array(
    'access arguments' => array('access content'),
    'page callback'     => 'ang_node_api',
    'page arguments' => array(2),
    'delivery callback' => 'drupal_json_output'

  return $items;
 * API callback to return nodes in JSON format
 * @param $param
 * @return array
function ang_node_api($param) {

  // If passed param is node id
  if ($param && is_numeric($param)) {
    $node = node_load($param);
    return array(
      'nid' => $param,
      'uid' => $node->uid,
      'title' => check_plain($node->title),
      'body' => $node->body[LANGUAGE_NONE][0]['value'],
  // If passed param is text value
  elseif ($param && !is_numeric($param)) {
    $nodes = db_query("SELECT nid, uid, title FROM {node} n JOIN {field_data_body} b ON n.nid = b.entity_id WHERE n.title LIKE :pattern ORDER BY n.created DESC LIMIT 5", array(':pattern' => '%' . db_like($param) . '%'))->fetchAll();
    return $nodes;
  // If there is no passed param
  else {
    $nodes = db_query("SELECT nid, uid, title FROM {node} n JOIN {field_data_body} b ON n.nid = b.entity_id ORDER BY n.created DESC LIMIT 10")->fetchAll();
    return $nodes;

In hook_menu() we declare a path (api/node) which can be accessed by anyone with permissions to view content and which will return JSON output created in the callback function ang_node_api(). The latter gets passed one argument, that is whatever is found in the URL after the path we declared: api/node/[some-extra-param]. We need this argument because of we want to achieve 3 things with this endpoint:

  1. return a list of 10 most recent nodes
  2. return a node with a certain id (api/node/5 for example)
  3. return all the nodes which have the passed parameter in their title (api/node/chocolate for example, where chocolate is part of one or more node titles)

And this is what happens in the second function. The parameter is being checked against three cases:

  • If it exists and it’s numeric, we load the respective node and return an array with some basic info form that node (remember, this will be in JSON format)
  • If it exists but it is not numeric, we perform a database query and return all the nodes whose titles contain that value
  • In any other case (which essentially means the lack of a parameter), we query the db and return the latest 10 nodes (just as an example)

Obviously this callback can be further improved and consolidated (error handling, etc), but for demonstration purposes, it will work just fine. Let’s now create a theme that uses a template file and a custom block that will render it:

 * Implements hook_theme().
function ang_theme($existing, $type, $theme, $path) {
  return array(
    'angular_listing' => array(
      'template' => 'angular-listing',
      'variables' => array()

 * Implements hook_block_info().
function ang_block_info() {

  $blocks['angular_nodes'] = array(
    'info' => t('Node listing'),

  return $blocks;

 * Implements hook_block_view().
function ang_block_view($delta = '') {

  $block = array();

  switch ($delta) {
    case 'angular_nodes':
      $block['subject'] = t('Latest nodes');
      $block['content'] = array(
        '#theme' => 'angular_listing',
        '#attached' => array(
          'js' => array(
            drupal_get_path('module', 'ang') . '/lib/ngDialog/ngDialog.min.js',
            drupal_get_path('module', 'ang') . '/ang.js',
          'css' => array(
            drupal_get_path('module', 'ang') . '/lib/ngDialog/ngDialog.min.css',
            drupal_get_path('module', 'ang') . '/lib/ngDialog/ngDialog-theme-default.min.css',

  return $block;

 * Implements template_preprocess_angular_listing().
function ang_preprocess_angular_listing(&$vars) {
  // Can stay empty for now.

There are four simple functions here:

  1. Using hook_theme() we create our angular_listing theme that uses the angular-listing.tpl.php template file we will create soon.
  2. Inside the hook_block_info() we define our new block, the display of which is being controlled inside the next function.
  3. Using hook_block_view() we define the output of our block: a renderable array using the angular_listing theme and which has the respective javascript and css files attached. From the Google CDN we load the Angular.js library files, inside ang.js we will write our JavaScript logic and in the /lib/ngDialog folder we have the library for creating dialogs. It’s up to you to download the latter and place it in the module following the described structure. You can find the files either in the repository or on the library website.
  4. The last function is a template preprocessor for our template in order to make sure the variables are getting passed to it (even if we are actually not using any).

As you can see, this is standard boilerplate Drupal 7 code. Before enabling the module or trying out this code, let’s quickly create the template file so Drupal doesn’t error out. Inside a file called angular-listing.tpl.php, add the following:

        <div ng-app="nodeListing">
           <div ng-controller="ListController">
             <input ng-model="search" ng-change="doSearch()">
                <li ng-repeat="node in nodes"><button ng-click="open(node.nid)">Open</button> {{ node.title }}</li>
             <script type="text/ng-template" id="loadedNodeTemplate">
             <h3>{{ loadedNode.title }}</h3>
             {{ loadedNode.body }}

Here we have some simple HTML pimped up with Angular.js directives and expressions. Additionally, we have a <script> tag used by the ngDialog module as the template for the dialog. Before trying to explain this, let’s create also our ang.js file and add our javascript to it (since the two are so connected):

angular.module('nodeListing', ['ngResource', 'ngDialog'])

  // Factory for the ngResource service.
  .factory('Node', function($resource) {
    return $resource(Drupal.settings.basePath + 'api/node/:param', {}, {
      'search' : {method : 'GET', isArray : true}

  .controller('ListController', ['$scope', 'Node', 'ngDialog', function($scope, Node, ngDialog) {
    // Initial list of nodes.
    $scope.nodes = Node.query();

    // Callback for performing the search using a param from the textfield.
    $scope.doSearch = function() {
      $scope.nodes = Node.search({param: $scope.search});

    // Callback to load the node info in the modal
    $scope.open = function(nid) {
      $scope.loadedNode = Node.get({param: nid});
        template: 'loadedNodeTemplate',
        scope: $scope


Alright. Now we have everything (make sure you also add the ngDialog files as requested in the #attached key of the renderable array we wrote above). You can enable the module and place the block somewhere prominent where you can see it. If all went well, you should get 10 node titles (if you have so many) and a search box above. Searching will make AJAX calls to the server to our endpoint and return other node titles. And clicking on them will open up a dialog with the node title and body on it. Sweet.

But let me explain what happens on the Angular.js side of things as well. First of all, we define an Angular.js app called nodeListing with the ngResource (the Angular.js service in charge communicating with the server) and ngDialog as its dependencies. This module is also declared in our template file as the main app, using the ng-app directive.

Inside this module, we create a factory for a new service called Node which returns a $resource. The latter is in fact a connection to our data on the server (the Drupal backend accessed through our endpoint). In addition to the default methods on it, we define another one called .search() that will make a GET request and return an array of results (we need a new one because the default .get() does not accept an array of results).

Below this factory, we define a controller called ListController (also declared in the template file using the ng-controller directive). This is our only controller and it’s scope will apply over all the template. There are a few things we do inside the controller:

  1. We load nodes from our resource using the query() method. We pass no parameters so we will get the latest 10 nodes on the site (if you remember our endpoint callback, the request will be made to /api/node). We attach the results to the scope in a variable called nodes. In our template, we loop through this array using the ng-repeat directive and list the node titles. Additionally, we create a button for each with an ng-click directive that triggers the callback open(node.nid) (more on this at point 3).
  2. Looking still at the template, above this listing, we have an input element whose value will be bound to the scope using the ng-model directive. But using the ng-change directive we call a function on the scope (doSearch()) every time a user types or removes something in that textfield. This function is defined inside the controller and is responsible for performing a search on our endpoint with the param the user has been typing in the textfield (the search variable). As the search is being performed, the results populate the template automatically.
  3. Lastly, for the the bonus part, we define the open() method which takes a node id as argument and requests the node from our endpoint. Pressing the button, this callback function opens the dialog that uses a template defined inside of the <script> tag with the id of loadedNodeTemplate and passes to it the current scope of the controller. And if we turn to the template file, we see that the dialog template simply outputs the title and the body of the node.


You can see for yourself the amount of code we wrote to accomplish this neat functionality. Most of it is actually boilerplate. A very fast node query block that delivers results asynchronously with all of its benefits. And if you know Angular.js, you can imagine the possibility of enhancing the Drupal experience further.

Now, are you interested to learn more about the love between Angular.js and Drupal? Would you have done anything differently? Let us know in the comments below!

Dec 10 2014
Dec 10

I love Drupal and end up undertaking most of my programming projects with it. I have been using it for so long that I find it far easier to push out projects with Drupal than with anything else, despite it’s infamous learning curve.

Whether you want to call Drupal a CMS (Content Management System), a CMF (Content Management Framework) or a CMSomething, the ‘C’ always stands for Content. Content is where Drupal shines and is what it’s designed for.


When an organisation is at a stage and mindset that they also want to manage their contacts and interactions effectively they will often need tools designed specifically for that function. These are generally referred to as a CRM, which stands for Client Relationship Manager or Constituent Relationship Manager, depending on the sector (For-Profit or Not-for-Profit respectively). CRMs are big business, with many free and paid options available, all with their own advantages and disadvantages.

Often these interactions that people have with your organisation will include things such as registering for an event, making a donation, becoming a member, expressing interest in a product or receiving a newsletter. This all sounds quite simple, but often representing a business rule in the digital realm is very difficult as everyone thinks ‘their way’ is ‘the only way’ and that surely every off-the-shelf system should represent them out of the box.

What has a CRM got to do with Drupal? Nothing directly, but indirectly if you’re looking to streamline your business operations and automate the ways people can interact with you, your CRM will need to work well with your website.

If you are reading this, I will assume your website is likely built in Drupal and, unsurprisingly, Drupal continues its talents of playing well with others into the domain of CRMs.

In this article, we will look at several of the big players in the CRM space that work well with Drupal, how they integrate or how developers can get them to integrate.

Roll it yourself

Whilst I mentioned above that Drupal is aimed at Content, Drupal has always excelled at relationships between content, or in newer parlance, ‘Entity References’. Theoretically you could create content types for contacts (or the User entity) and content types for the interactions they may have with you alongside other modules such as Event and Commerce. Then create a bunch of Views and you effectively have a ‘CRM’. In some simpler cases this may be enough and you have complete control of the processes you want to represent. This could end up consuming a lot of Developer time and using a tool designed specifically for the job may be a better solution.


The team at ThinkShout effectively followed the advice above and created a collection of modules that will provide you with a lot of Drupal-Native CRM functionality. It takes the Drupal Commerce approach and instead of providing you functionality our of the box, rather provides you with a toolkit for creating that functionality. This does mean you may still need to undertake a lot of extra work yourself but you are adding no new systems into your technology stack and the problems that can entail. The other downside of RedHen is that it isn’t updated that regularly (in comparison with other options on this list), its release cycle is based more upon when ThinkShout have client requirements or run a code sprint.

If you want to customize RedHen then you can create your own sets of modules and theme overrides, it’s Drupal!


Often when searching for CRM options for Drupal, people come across CiviCRM and it initially appears as a Drupal module. I have undertaken a lot of work with CiviCRM (and contribute to the project) and the fact that it masquerades as a Drupal module is often a massive point of confusion. It’s best thought of what it actually is, an external service that happens to integrate quite well with Drupal and almost look like it’s a part of it. CiviCRM is a custom PHP application that also integrates with Joomla! and WordPress and is primarily aimed at not-for-profits but can be customized to work with commercial organisations. Out of the box CiviCRM comes with a LOT of features and is thus quite a weighty program, as an open-source project it can sometimes be a bit rough around the edges and inconsistent, but development has increased and matured a lot in the past year.

CiviCRM integrates directly with Drupal in many places, some better than others, and these include:

  • A direct (optional) relationship between a Drupal user and a contact record as well as synchronization between Drupal roles and CiviCRM groups and memberships.
  • Views for constructing listings of CiviCRM entities.
  • Rules and triggers
  • Webform for replacing CiviCRM’s inbuilt forms.
  • Commerce and Ubercart
  • Organic Groups
  • Theming (sort of). You can use the Drupal theme to override CiviCRM CSS but CiviCRM does use its own templating engine (currently smarty but likely switching to twig).
  • Another option is to set aside the Drupal/CiviCRM modules and utilise CiviCRM in a ‘headless’ approach, utilizing it’s API and REST interfaces.

CiviCRM offers a plethora of its own inbuilt customization options that I won’t go into, which, being PHP, will be reasonably familiar to many of you. You can also utilize direct CiviCRM to Drupal customization through creating your own Drupal module. In the module you can access CiviCRM hooks and API functions which offers an endless level of options to suit a plethora of client needs.


Salesforce is the main player for commercial sales focused companies and is reasonably entrenched in many business workflows. It is a large application with its own long established ecosystem and extension marketplace. It is expensive, proprietary and written in its own programming language, ‘Apex’. Development moves fast and it is a reasonably stable system.

Salesforce is a cloud based CRM, so integration happens via a REST interface. Fortunately as Salesforce is so popular in the types of environments that Drupal is also popular, there are a few prebuilt options. Bear in mind that your license may limit the options available to you:

  • The SalesForce Suite is a module with a long history and it starts you on your integration journey. It will handle authentication, mapping Drupal entities to SalesForce fields, pushing and pulling data between Drupal and SalesForce and a legacy module to connect with SalesForce’s older SOAP API.
  • There is some basic Webform integration via a module with seemingly stalled development.
  • Springboard is a commercial Drupal distribution from Jackson River that bundles Drupal and SalesForce together into an offering specifically for not-for-profits. It’s a little unclear what it offers above just doing integration yourself, but it includes support. There are also a couple of other agencies that offer Drupal / SalesForce integration services.

Theoretically, once you have SalesForce entries represented as Drupal entities you can utilize the plethora of customization options that Drupal offers such as views, rules and module hooks. If you want to enhance SalesForce functionality then it could potentially be accomplished through Drupal and pushed to SalesForce, but chances are you will need to learn SalesForce itself at some point.

Sugar CRM

Sugar is another long established player and comes in community (open source PHP) and commercial editions. It is aimed at commercial sales focused organisations and much like SalesForce, development moves quickly and Sugar CRM also has its own marketplace for extensions.

OSSCube created a Drupal module and accompanying SugarCRM project to allow for some direct integration. I haven’t personally used them and find the documentation somewhat hard to understand. However, it claims to offer:

  • Field mapping between Drupal and Sugar entities
  • Data syncing between the two systems
  • Webform integration to create Sugar entities

Again, you also have the option of utilizing Sugar’s SOAP and REST APIs to create Drupal entities and continue from there. Sugar also offers LDAP, so there is the potential to create a single sign on between the two systems.

Other Options

I have grouped together several other options here. All the CRMs vary wildly, but their integration options are mostly the same so I didn’t want to just repeat those options over and over again. I have attempted to undertake Drupal integration work with some of them in the past and often struggled to accomplish anything. A lot of this is due to the proprietary nature of these systems, finding information on their API and developer options is a challenging endeavor unless you pay some money.

Microsoft Dynamics and BlackBaud

It is worth including Dynamics and Blackbaud as they are big players in the CRM space. Both offer their own options for a CMS (and other systems), so are often reluctant to offer integration options outside of their ecosystem.

Nation Builder and Salsa

These are both CRMs of a sort that are aimed more at the newer wave of engagement focused organisations. They are not just about tracking contributions and interactions, but also encouraging interactions.

Salsa has some integration modules for Drupal 6, so if you’re feeling generous you may want to update them. Otherwise it’s a process of communicating via the Salsa API and fortunately there is a Drupal module under development to get you started.

NationBuilder have gone out of their way to not create any direct CMS integrations, citing that their inbuilt CMS is a far better option instead. However, they do have an API that can be used with the options noted below.

How to integrate with Drupal?

Here are some potential options, but your mileage may vary:

  • Utilize the CRM’s API (if it exists in your version / license) to pull entities into Drupal and then proceed in a similar vein to the SalesForce options via Services or a custom module.
  • Using the Migrate module and optionally the MSSQL Server PHP extension for any .NET based systems to directly query the CRM database and import into Drupal entities. Again, your license and setup may or may not allow this.
  • There is a Sandbox module for Dynamics integration, last time I tried, it didn’t work anymore, but you may feel like updating it.


This is by no means a comprehensive list of CRMs or the possible options to integrate them with Drupal. I have mainly focused on the ones I have experience with and can’t possibly keep up with all the new options that are constantly emerging. I also have far more experience working with not-for-profits, so my solutions are somewhat skewed to that sector. What are some of the systems you have tried to connect with Drupal? Did you succeed? Have you had to overcome any hurdles? Let us know!

Oct 20 2014
Oct 20

How to Build a Drupal 8 Module

Please be aware that due to the development process Drupal 8 has been undergoing at the time of writing, some parts of the code might be outdated. Take a look at this repository in which I try to update the example code and make it work with the latest Drupal 8 release.

With the incorporation of many Symfony components into Drupal in its 8th version, we are seeing a shift away from many Drupalisms towards more modern PHP architectural decisions. For example, the both loved and hated hook system is getting slowly replaced. Plugins and annotations are taking away much of the need for info hooks and the Symfony Event Dispatcher component is replacing some of the invoked hooks. Although they remain strong in Drupal 8, it’s very possible that with Drupal 9 (or maybe 10) hooks will be completely removed.

In this article we are going to primarily look at how the Symfony Event Dispatcher component works in Drupal. Additionally, we will see also how to invoke and then implement a hook in Drupal 8 to achieve similar goals as with the former.

To follow along or to get quickly started, you can find all the code we work with here in this repository. You can just install the module and you are good to go. The version of Drupal 8 used is the first BETA release so it’s preferable to use that one to ensure compatibility. Alpha 15 should also work just fine. Let’s dive in.

What is the Event Dispatcher component?

A very good definition of the Event Dispatcher component can be found on the Symfony website:

The EventDispatcher component provides tools that allow your application components to communicate with each other by dispatching events and listening to them.

I recommend reading up on that documentation to better understand the principles behind the event dispatcher. You will get a good introduction to how it works in Symfony so we will not cover that here. Rather, we will see an example of how you can use it in Drupal 8.

Drupal 8 and the Event Dispatcher

For the better part of this article, we will focus on demonstrating the use of the Event Dispatcher in Drupal 8. To this end, we will create a simple demo module (event_dispatcher_demo) that has a configuration form which saves two values as configuration. Upon saving this form, we will dispatch an event that contains the config object and which will allow other parts of the application to intercept and modify it before being saved. Finally, we will do just that by demonstrating how to subscribe (or listen) to these events.

In Drupal 7, this type of modularity is only achieved with hooks. Hooks are being invoked and modules have the option to implement them and contribute with their own data. At the end of this article, we will see how to do that as well in Drupal 8. But first, let’s get on with our demo module.

If you don’t know the basics of Drupal 8 module development, I recommend checking out my previous articles in this series.

The form

The first thing we need is a simple config form with two fields. In a file called DemoForm.php located in the src/Form folder, we have the following:


 * @file
 * Contains Drupal\event_dispatcher_demo\Form\DemoForm.

namespace Drupal\event_dispatcher_demo\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class DemoForm extends ConfigFormBase {

   * {@inheritdoc}
  public function getFormID() {
    return 'demo_form';

   * {@inheritdoc}
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('event_dispatcher_demo.demo_form_config');
    $form['my_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('My name'),
      '#default_value' => $config->get('my_name'),
    $form['my_website'] = [
      '#type' => 'textfield',
      '#title' => $this->t('My website'),
      '#default_value' => $config->get('my_website'),
    return parent::buildForm($form, $form_state);

   * {@inheritdoc}
  public function submitForm(array &$form, FormStateInterface $form_state) {

    parent::submitForm($form, $form_state);

    $config = $this->config('event_dispatcher_demo.demo_form_config');

    $config->set('my_name', $form_state->getValue('my_name'))
      ->set('my_website', $form_state->getValue('my_website'));


Let’s also create a route for it (in the event_dispatcher_demo.routing.yml file) so we can access the form in the browser:

  path: 'demo-form'
    _form: '\Drupal\event_dispatcher_demo\Form\DemoForm'
    _title: 'Demo form'
    _permission: 'access administration pages'

So now if you point your browser to example.com/demo-form, you should see the form. Submitting it will create and persist a configuration object called event_dispatcher_demo.demo_form_config that contains two fields: my_name and my_website .

The event dispatcher

Now it’s time to work on the form submit handler (the formSubmit() method) and dispatch an event when the form is saved. This is what the new method will look like:

public function submitForm(array &$form, FormStateInterface $form_state) {

  parent::submitForm($form, $form_state);

  $config = $this->config('event_dispatcher_demo.demo_form_config');

  $config->set('my_name', $form_state->getValue('my_name'))
    ->set('my_website', $form_state->getValue('my_website'));

  $dispatcher = \Drupal::service('event_dispatcher');

  $e = new DemoEvent($config);

  $event = $dispatcher->dispatch('demo_form.save', $e);

  $newData = $event->getConfig()->get();



So what happens here? After we take the submitted values and add them to the config object like before, we retrieve the event dispatcher object from the service container:

$dispatcher = \Drupal::service('event_dispatcher');

Please keep in mind that it’s recommended you inject this service into your class, but for brevity, we will retrieve it statically. You can read this article about dependency injection and the service container for more information.

Then we create a new DemoEvent object and pass it the $config through its constructor (we have not yet created the DemoEvent class, we will do that in a minute). Next, we use the dispatcher to dispatch an event of our type and assign this action the identifier demo_form.save. This will be used when subscribing to events (we’ll see this later). The dispatch() method returns the event object with modifications made to it so we can retrieve the config values that may or may not have been altered elsewhere and merge them into our original configuration. Finally, we save this object like we did initially.

Before moving onto the event subscription part of our application, let’s create the DemoEvent class we just instantiated above. In a file called DemoEvent.php located in the src/ folder of our module, we have the following:


 * @file
 * Contains Drupal\event_dispatcher_demo\DemoEvent.

namespace Drupal\event_dispatcher_demo;

use Symfony\Component\EventDispatcher\Event;
use Drupal\Core\Config\Config;

class DemoEvent extends Event {

  protected $config;

   * Constructor.
   * @param Config $config
  public function __construct(Config $config) {
    $this->config = $config;

   * Getter for the config object.
   * @return Config
  public function getConfig() {
    return $this->config;

   * Setter for the config object.
   * @param $config
  public function setConfig($config) {
    $this->config = $config;


As you can see, this is a simple class that extends the default Event class and which defines setters and getters for the config object we will be passing around using this event. And since we created it, let’s also make sure we use it in the file where we defined the form:

use Drupal\event_dispatcher_demo\DemoEvent;

The event subscriber

Now that our form is functioning normally and an event is being dispatched when the form is saved, we should take advantage of that and subscribe to it. Let’s start with the event subscriber class that implements the EventSubscriberInterface. Inside a file called ConfigSubscriber.php (name of your choice) located in the src/EventSubscriber/ folder, we have the following:


 * @file
 * Contains Drupal\event_dispatcher_demo\EventSubscriber\ConfigSubscriber.

namespace Drupal\event_dispatcher_demo\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ConfigSubscriber implements EventSubscriberInterface {

  static function getSubscribedEvents() {
    $events['demo_form.save'][] = array('onConfigSave', 0);
    return $events;

  public function onConfigSave($event) {

    $config = $event->getConfig();

    $name_website = $config->get('my_name') . " / " . $config->get('my_website');
    $config->set('my_name_website', $name_website);


So what happens here? The EventSubscriberInterface has only one required method called getSubscribedEvents(). This method is used to register events and callbacks to these events. So above we registered the callable onConfigSave() (found in the same class below) to the event dispatched with the identifier of demo_form.save. And in the callback method we simply add another value to the config object (based on a concatenation of the existing two values). The latter part is just for our demo purposes: here you can do what you want.

When we subscribed our onConfigSave() method to listen to the demo_form.save event, we passed a weight of 0. If you register multiple callbacks to the same event, this weight becomes important (the higher the number, the earlier it gets called). And if a callback alters the same values as one triggered before, they will get overridden. It’s good to keep this in mind.

Now in order for this event subscriber to work, we need to define it as a service and give it the event_subscriber tag. So in a file called event_dispatcher_demo.services.yml found in the root folder of our module, we will have this:

    class: Drupal\event_dispatcher_demo\EventSubscriber\ConfigSubscriber
      - { name: event_subscriber }

This is a simple service definition with the right tag that will make the container automatically instantiate an object of this class whenever the dispatcher is in play. And that is pretty much it. Clear the cache and if you now save the form again, the configuration object that gets saved will always contain a new value that is based on the first two.


In the final part of this article we will demonstrate the use of hooks to achieve a similar goal.

First, let’s change the form submit handler and instead of dispatching events, we will invoke a hook and pass the config values to it. This is what the new submitForm() method will look like:

public function submitForm(array &$form, FormStateInterface $form_state) {

        parent::submitForm($form, $form_state);
        $config = $this->config('event_dispatcher_demo.demo_form_config');
        $config->set('my_name', $form_state->getValue('my_name'))
          ->set('my_website', $form_state->getValue('my_website'));
        $configData = $config->get();
        $newData = \Drupal::service('module_handler')->invokeAll('demo_config_save', array($configData));

We are not using any event objects nor the dispatcher service. Instead, we retrieve the Module Handler service that contains the invokeAll() method used to invoke hook implementations from all modules. This is essentially replacing the Drupal 7 module_invoke_all() helper. And again, it is recommended to inject this service, but for brevity, we’ll retrieve it statically.

The hook implementation invoked in our case is hook_demo_config_save and it gets one parameter, an array of values pulled from our config object. Inside $newData we will have an array of values merged from all the implementations of this hook. We then merge that into our config object and finally save it.

Let’s quickly see an example hook implementation. As with Drupal 7, these can only be in .module files:

 * Implements hook_demo_config_save().
function event_dispatcher_demo_demo_config_save($configValues) {

  $configValues['my_name_website'] = $configValues['my_name'] . " / " . $configValues['my_website'];

  return $configValues;


As you can see, we are adding a new value to the config array that will later be merged into the object getting persisted. And we have essentially the same thing as we did with the event dispatcher.


In this article we have taken a look at how the Symfony Event Dispatcher component works in Drupal 8. We’ve learned how flexible it makes our application when it comes to allowing others to extend functionality. Additionally, we’ve seen how the invoked hooks work in the new version of Drupal. Not much has changed since Drupal 7 in this respect apart from the frequency with which they are used. Many hooks have been replaced by plugins and annotations and the Event Dispatcher component has also taken on a big chunk of what was in D7 a hook responsibility.

Although the Event Dispatcher approach is more verbose, it is the recommended way to go forward. Where possible, we no longer use the old procedural approach characteristic to hooks but rather object oriented, decoupled and testable solutions. And Symfony helps greatly with that.

Oct 14 2014
Oct 14

In this quick tip, we’ll be installing a local instance of Drupal 8, beta 1. By the end, you’ll have a copy of Drupal that’s not only ready to be extended with Symfony bundles and other packages, but also ready to accept content and display it to end users.

Step 1: Prepare Environment

In order for everyone to have the same starting point, we’ll be using our trusty old Homestead Improved vagrant box. It’s important to note that even if this tip will be installing Drupal 8 into the Vagrant box, the procedure is absolutely identical for any Ubuntu based environment.

So, somewhat optional, please clone a new Homestead Improved instance as per instructions in this tip. Then, add a new site and make sure you add the entry to your host machine’s hosts file. In my case, it’s test.app and Homestead.yaml looks like this:

ip: ""
memory: 2048
cpus: 1

    - map: .
      to: /home/vagrant/Code

    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public
    - map: test.app
      to: /home/vagrant/Code/drupal

    - key: APP_ENV
      value: local

Step 2: Download and extract Drupal 8 b1

If you’re using a VM, log into it and enter the folder where you keep your projects. In the case of the Homestead Improved installation above, that’ll be /home/vagrant/Code. If you’re using your own LAMP stack or whatever, just go into your projects folder.

wget http://ftp.drupal.org/files/projects/drupal-8.0.0-beta1.tar.gz

When downloading finishes, extract the archive and rename the resulting folder to drupal.

tar -xvzf drupal-8.0.0-beta1.tar.gz
mv drupal-8.0.0-beta1 drupal

Step 3: Create the DB

In this case we’ll be using MySQL. We’ll also be using Homestead-specific user/pass defaults. If you’ve got your own environment, adapt as needed. For PostgreSQL see here.

mysqladmin -u homestead -psecret create drupaltest
mysql -u homestead -psecret

Once in the MySQL console, execute the following:



Step 4: Settings

In this step, we create a settings and services file from the provided templates, and let the Drupal installer edit them by altering permissions.

cd drupal
cp sites/default/default.settings.php sites/default/settings.php
cp sites/default/default.services.yml sites/default/services.yml
chmod a+w sites/default/settings.php
chmod a+w sites/default/services.yml
chmod a+w sites/default

Step 5: Install

In your host’s browser, enter the URL test.app:8000/install.php and follow the instructions of the wizard.

Choose a standard installation profile for the quickest setup. You can find out more about these profiles here, if interested.

Optional Cleanup and Tweaks

Optional but recommended:

  1. Remove the original downloaded archive to free up disk space
  2. Activate the cron
  3. Change the permissions back:

    chmod 644 sites/default/settings.php
    chmod 644 sites/default/services.yml
    chmod 755 sites/default


As you can see, adding a new Drupal installation onto your server can be done in minutes from total zero to fully functional CMS. For more information on other aspects and edge cases of Drupal installation, see their installation guide.

Bruno is a coder from Croatia with Master’s Degrees in Computer Science and English Language and Literature. He’s the editor of SitePoint’s PHP channel and a developer evangelist for Diffbot.com. He avoids legacy code like the plague and when picking projects makes sure they’re as cutting edge as possible. He’s a treadmill desk enthusiast and active (board)gamer who sometimes blogs.

Oct 11 2014
Oct 11

As has been the pattern of many recent DrupalCons and Camps, DrupalCon Amsterdam 2014 was all about Drupal 8 and the changes that it’s bringing to the platform and community.

This has coincided with an increase in attendance at Drupal events (2300 in Amsterdam) and an increasing professionalism to DrupalCons. Drupal 8 has pulled us (sometimes forcibly) from out of our comfort zone and into the wider PHP and developer community. This has resulted in more talks covering a variety of non-Drupal topics, which, in my opinion, is a great thing.

The big news of the conference came on day 2, with Drupal 8 finally making it into beta. You can now effectively build basic sites in Drupal 8. In fact, a few brave souls already have, and I intend to do so too with my next site.

Dries Keynote

The regular ‘Driesnote’ was a thought provoking academic discussion on a current hot topic in the Open Source world, sustainability of projects and funding models. He started by stating that there are actually few good Open Source examples we could be following. In Dries’ opinion, the prevalent model of one company funding development is not a good one. Instead he suggested we look to other models, especially the concept of how Open Source software could be treated as a public good, or to coin a British term, ‘The Commons’. He used the example of public roads to show how community desire and amateur implementation can grow. Firstly via business investment (and sometimes privatization) and often resulting in Government control and management. To summarize:

Invention -> Product -> Utility

As a project grows, its reach widens, but so does its complexity and cost of maintenance and management. He then discussed the reasons that people get involved with Open Source projects in the first place, what they ‘get out of it’ and why.

Dries then aired some of his ideas for encouraging Drupal users to become contributors and for contributors to contribute more. A lot of his ideas involved methods of rewarding contributors in better ways. View his keynote here for more detail, it is worthwhile watching for anyone involved with Open Source, not just Drupal fans. In his words:

“An imperfect solution beats no solution”

Cory Doctorow

In typical style, Cory delivered the other side of the open source world, the political and activist attitudes and it complemented the Dries Keynote well. I would imagine that many non-English speakers struggled to keep up with Cory’s speed of speaking. I was hoping he would inject more Drupal specific content, but his general point was that making software isn’t enough. Alongside this we need to be pushing for change, lobbying and fighting against issues such as DRM, surveillance and net neutrality.

Lightning talks

Replacing the day 3 keynote were lightning talks, which, being in the main auditorium, must have been quite nerve racking for the participants. Lightning talks always throw up a myriad of ideas and this was no exception – you can view them here. They included:
* Drupal & Bitcoin
* The Drupal 8 Console
* Druphpet (A Drupal implementation of Puphpet)
* Creating a Drupal 8 site
* Healthy attitudes to managing a project

Main Sessions

There were many talks and there’s no possibility of covering them all. What follows is a summary of some of those that I feel may appeal to you or that contained particularly interesting information or resources.

Models & Service Layers; Hemoglobin & Hobgoblins

As Drupal 8 pushes Drupal developers into fully object orientated programming, we open ourselves to a new world of design patterns and possibilities. This talk covered slimming down models in MVC code and instead utilizing services of common code that can be shared between models. This starts to create ‘JQuery-like events’ that ‘listen’ and are triggered by occurrences in code such as sending an email. There are many pros and cons to this approach and for more in-depth coverage, watch the video of the session here.

Object Oriented programming for Drupal developers

For any Drupal developer starting down the path of object-oriented PHP, this was an invaluable introductory session. It was devoid of jargon and complex phrases and Lorna Jane explained concepts clearly and concisely, probably why she is also a popular PHP book author. She started by setting everyone at ease, describing many OOP concepts as:

“Perfectly simple concepts dressed up”

Much of this talk will be familiar to SitePoint readers, but some points made that are worthy of mention were: treating exceptions as an opportunity, not an error, the power of traits and a clear explanation of Interfaces.

If you’re a beginner PHP programmer or are in need of a refresher, this session is required viewing.

Open Source design

We often forget that the interfaces, icons, imagery and layouts used in open source software were designed by someone. This was a session on getting involved and working as an open source designer from Jan, a designer with OwnCloud. Jan stated that to attract designers to your project you will need some good initial designs in the first place. Aim to create a consistent design credibility and culture and provide a starting point for those who want to get involved. He cited the Gnome design wiki as a great example. Your project should not be afraid of presenting rough mockups of what you are aiming for, even if you don’t have any designers on board yet. This was a presentation packed full of tips and resources, I suggest you watch the presentation here or take a look at the Open Source Designers Github account.


One of the frequent issues with extensible projects such as Drupal is duplication of functionality, as developers often like to outdo each other. Utilizing external APIs is a classic example of this, with many options that present the ‘best’ way to integrate with a service, and yet there will be other API integrations that are unavailable. Enter API hub a sandbox Drupal module that aims to create a method for defining your own API endpoints and allows you to pull them into the Drupal ecosystem, leveraging other modules such as views and rules. It’s a great idea that I hope makes a full release soon.

Building a tasty Backend

We often forget that admin and editorial users are important users of our web apps, too. Their experience needs to be as clear and user friendly as possible so they can create and curate the site for their users. This session was a tour through tips and resources to help make your content admin and edit screens as usable as possible to a non-developer audience. This included:

The best approach is to strip everything to what is only necessary and slowly add back what users need. Jeni has created a ‘Tasty Backend’ install profile that sets up the above – find out more about that and view the session here.

Elastic Search in Drupal

For large scale search functions, Elastic Search is the new cool kid on the block. Drupal is used in Enterprise web apps that often require complex and reliable search infrastructures, so they are a perfect pairing. Unsurprisingly, “There’s a module for that” and it’s the Elastic Search Connector module. It brings full integration to your Drupal site with sub modules for views, Search API, Views and more. This is a complex topic, so it’s best you follow the expert and view Skek’s presentation here.

EmberJS and Drupal

“Headless Drupal” was the buzz phrase of the conference, the concept of decoupling Drupal from what it’s not so good at (front end) and what it’s great at (backend) and instead, allow something else (generally JavaScript) to take care of displaying data. There were several talks covering this topic, but this was by far the best. Not only clearly explaining why you may want to take this approach, but also a great overview of how JavaScript Frameworks work. View the session here for a great practical walkthrough and example.


PHPStorm has fast become the IDE of choice for Drupal developers, thanks to JetBrains fantastic job with Drupal related integrations. This was a fast summary of some of the goodies in PHPStorm such as coding standards, Drush, API reference and much, much more. View the session here.


From sessions to the social activities and beyond, this was a great DrupalCon, the best I’ve attended. It might have been due to the relief that the release of Drupal 8 was in sight. Or maybe because the Drupal community seems to be figuring out how to balance it’s increasing interest from the corporate world with a community project. Whatever the reason, I had a fantastic time and I would like to thank the organizers for all the (mainly voluntary) work they do to get an event like this to happen.

Have you been? What impressed you most?

Chris Ward

Chris is a Melbourne-based web developer and open source advocate. He has particular experience in the community, nonprofit and social enterprise sectors, with a focus on UX and business analysis. Aside from technology, Chris loves to learn and spread ideas from diverse topics like the environment, history, philosophy, music, reading, writing, games, and much more.

Aug 18 2014
Aug 18

In this article, we’ll discuss how you can leverage various Drupal API functions to achieve more fine grained theming. We’ll cover template preprocessing and alter hooks using path patterns, types and args(). We’ll use the arg() function which returns parts of a current Drupal URL path and some pattern matching for instances when you want to match a pattern in a URL. We’ll also take a look at creating a variable for an array of content types.

Template preprocessing is a means to define variables for use within your page. For example, you can define a body class variable. In turn you can use the resulting class in your Sass or CSS. An alter or build hook is something that’s run before the page renders so you can do things such as adding JS or CSS to specific pages or content types.

I’ll explain and demonstrate these hooks and how you can use them to:

  • Add a <body> class to a specific page for better theming
  • Add Javascript or CSS to specific pages and paths
  • Use wildcard path arguments
  • URL pattern matching using preg_match
  • Create an array of content types to use as a variable in your argument
  • Using path arguments as parameters

The functions we discuss here will be added to your theme’s template.php file. Although you can also use these functions in a custom module, you’ll need to specify that the functions are not for admin pages unless that’s your intent, and I’ll cover how to do that.

Getting Started

When using preprocess or alter functions within your theme, you’ll want to be sure template.php exists but if not, you can go ahead and create this file in the root of your theme. So if my theme name is foobar, the path to template.php will be:


API functions are prefaced by the machine name of your theme. For example, if you are using hook_page_alter and your theme name is foobar, we’d write it as function foobar_page_alter(). (The machine name is simply the theme’s folder name.)

Custom Body Classes Using a Content Types Array

A body class is a class that’s added to your HTML <body> tag. For example, on a blog page, you might see something like this:

<body class="page-node page-node-blog">

You can leverage that class in your Sass or CSS to fine tune your theming by doing something like this just for blog pages on your site:

.page-node-blog h1 {
// custom Sass here

Out of the box, Drupal 7 comes with some pretty good body classes and usually these are fine for most use cases. In addition, Drupal contribution or Contrib themes such as Zen add enhanced and expanded classes.

In our case, we want to add a class to some pages which share some common attributes but may not necessarily derive from the same content type. Let’s say we have two content types that we want to add a specific class to in order to theme those alike but perhaps different from other pages on our website. We can build an array of Drupal content types we want to target and then use that array to add the class. Once we’ve defined the array, we just check to ensure that a given node exists and then pass the array in.


 * Implements template_preprocess_html().
 * Define custom classes for theming.
function foobar_preprocess_html(&$vars) {

  // Build a node types array from our targeted content types.
  $foo_types = array(

    // Define the node.
    $node = menu_get_object();
  // Use the array to add a class to those content types.
  if (!empty($node) && in_array($node->type, $foo_types)) {
    $vars['classes_array'][] = 'page-style-foobar';

This function preprocesses variables for anything that would typically be before the ending HTML </head> tag which is in Drupal’s core template, html.tpl.php. We add the body class using $vars['classes_array']. This variable gets rendered with <?php print $classes; ?> in the <body> tag. In our case, this class will only render in landing_page and our_services content types. Now we can use .page-style-foobar in our Sass or CSS to style these pages.

URL Pattern Matching

You can also use URL pattern matching for adding useful custom classes. Let’s say we have an “Our Services” landing page and then some sub-pages under that path. The URL architecture might look like this:

- example.com/our-services/subpage-1
- example.com/our-services/subpage-2

We’ll add a custom body class to those pages using preg_match, regex, PHP matches and Drupal’s request_uri function. Once again, we’d put this in a foobar_preprocess_html as above.

function foobar_preprocess_html(&$vars) {

  // Define the URL path.
  $path = request_uri();

  // Add body classes to various pages for better theming.
  if (preg_match('|^/our-services((?:/[a-zA-Z0-9_\-]*)*)?|', $path, $matches)) {
    $vars['classes_array'][] = 'page-services';

Now you can use .page-services .some-common-element for theming these “our-services” pages. Obviously this method has pitfalls if your URL structure changes so it may only fit some use cases.

Path Arguments

Another clever way of custom theming specific parts of your site is to partition those off using arg(). Drupal tends to get script and CSS heavy so ideally if you’re adding extra CSS or JS and you don’t need it for every page (which is normally done using your theme’s .info file), you can use path arg() to add these only to pages where they’re needed. For example, if I want to add a custom script to just the Drupal registration page, I can create a path arg() if statement and then add the script within that. The URL path we’ll focus on here is /user/register and you’ll see how the arg() breaks down the URL structure.

We’ll be using hook_page_alter here which can apply alterations to a page before it’s rendered. First we define the theme path and use Drupal’s attached function.


 * Implements hook_page_alter().
 * Add custom functions such as adding js or css.
function foobar_page_alter(&$page, $form) {

  // Define the module path for use below.
  $theme_path = drupal_get_path('theme', 'foobar');

  if (arg(0) == "user" && arg(1) == "register") {
     $foobar_js = array(
      '#attached' => array(
        'js' => array(
          $theme_path . '/js/custom.js' => array(
            'group' => JS_THEME,

In this function, note that we’ve substituted our theme name for hook so hook_page_alter becomes foobar_page_alter. The arg() number signifies the position in the URL path. Zero is first, one is second and so on. You can get pretty creative with these adding more parameters. Let’s say you wanted to add JS to just the user page but no paths underneath it. You could add a NULL arg() after the initial arg().

if (arg(0) == "user" && arg(1) == NULL) {
// code here

In the examples above, we’ve implemented various functions in our theme’s template.php file. You can also use these in a custom module as well and in that case you’d just preface your module name in the function rather than the theme name. When theming from a module, you’ll probably want to exclude admin paths since a module can target anywhere in your site. You can do that excluding admin paths.

if (!path_is_admin(current_path())) {
// code here


As you can see, leveraging the Drupal API Toolbox for theming extends your reach as a developer. The examples above are not definitive but they do give you a feel for what’s possible. As a Drupal Themer, using these has helped me expand my bag of tricks when theming and building a site. Comments? Feedback? Leave them below!


Jul 05 2014
Jul 05

How to Build a Drupal 8 Module

Even though Drupal 7 core fell short of a proper way of handling its brand new entity system (we currently rely on the great Entity module for that), it did give us EntityFieldQuery. For those of you who don’t know, EntityFieldQuery is a very powerful querying class used to search Drupal entities programatically (nodes, users, etc).

It provides a number of methods that make it easy to query entities based on conditions such as field values or class properties. If you don’t know how it works, feel free to check out this documentation page or this great tutorial on the subject.

In this article I am going to talk about what we have in Drupal 8 for querying entities. There is no more EntityFieldQuery, but there’s an entity.query service that will instantiate a query object for a given entity type (and that implements the \Drupal\Core\Entity\Query\QueryInterface). We can access this service statically through the \Drupal namespace or using dependency injection.

First up, we’ll look at querying node entities and then we’ll see how to load them. The same techniques will work with other content entities as well (users, comments etc), but also with configuration entities, and that’s really cool.

The entity query service

As mentioned, there are two ways we can access the entity.query service that we use for querying entities. Statically, we can do this:

$query = \Drupal::entityQuery('node');

Instead of node, we can specify any other entity type machine name and what we get inside the $query variable is the query object for our entity type. The entityQuery() static method on the \Drupal namespace is a shortcut for doing so using the entity.query service.

Alternatively (and the highly recommended approach) is to use dependency injection.

If you have access to the container, you can load the service from there and then get the right query object:

$entity_query_service = $container->get('entity.query');
$query = $entity_query_service->get('node');

As you can see, we use the get() method on the entity_query service to instantiate a query object for the entity type with the machine name passed as a parameter.

Querying entities

Let’s illustrate a couple of examples of querying for node entities using this object.

A very simple query that returns the published nodes:

$query = \Drupal::entityQuery('node')
    ->condition('status', 1);
$nids = $query->execute();

$nids will be an array of entity ids (in our case node ids) keyed by the revision ids (if there is revisioning enabled for the entity type) or the entity ids if not. Let’s see an example in which we add more property conditions as well as field conditions:

$query = \Drupal::entityQuery('node')
    ->condition('status', 1)
    ->condition('changed', REQUEST_TIME, 'condition('title', 'cat', 'CONTAINS')
    ->condition('field_tags.entity.name', 'cats');

$nids = $query->execute();

In this query, we retrieve the node ids of all the published nodes that have been last updated before the current time, that have the word cat inside their title and that have a taxonomy term called cats as a reference in the field_tags.

As you can see, there is no more distinction between propertyCondition and fieldCondition (as there is in D7 with EntityFieldQuery). Additionally, we can include conditions based on referenced entities tacking on the entity.(column) to the entity reference field name.

An important thing to note is that we also have the langcode parameter in the condition() method by which we can specify what translation of the node should be included in the query. For instance, we can retrieve node IDs that contain a specific value inside of a field in one language but another value inside the same field for another language.

For more information on the condition() method you should consult the API documentation.

The next thing we are going to look at is using condition groups (both AND and OR) for more powerful queries:

$query = \Drupal::entityQuery('node')
    ->condition('status', 1)
    ->condition('changed', REQUEST_TIME, 'orConditionGroup()
    ->condition('title', 'cat', 'CONTAINS')
    ->condition('field_tags.entity.name', 'cats');

$nids = $query->condition($group)->execute();

Above, we altered our previous query so as to retrieve nodes that either have the cat string in their title or have a reference to the term called cats in their field_tags field. And we did so by creating an orConditionGroup object that we then pass to the query as a condition. And we can group together multiple conditions within a andConditionGroup as well.

There are many other methods on the QueryInterface that can extend the query (such as for sorting, range, etc). I encourage you to check them out in the documentation and experiment with them. For now, though, let’s take a quick look at what to do with the result set.

Loading entities

As I mentioned above, the execute() method on the query object we’ve been working with returns an array of entity IDs. Supposedly we now have to load those entity objects and work with them. How do we do that?

In Drupal 7 we had the entity_load() function to which we passed an array of IDs and that would return an array of objects. In Drupal 8, this helper function is maintained and you can use it pretty much in the same way, except only for one entity at a time:

$node = entity_load('node', $nids[1]);

And the return value is a node object. To load multiple nodes, you can use the entity_load_multiple() function:

$nodes = entity_load_multiple('node', $nids);

Which then returns an array of entity objects keyed by their ids.

A bonus nugget of information is that both of these functions are wrappers for the storage manager of the entities in question. They basically retrieve the storage manager statically and then call the load() and loadMultiple() methods, respectively, on it:

Statically, you could do similarly:

$node_storage = \Drupal::entityManager()->getStorage('node');

// Load multiple nodes
// Load a single node

But better yet, you could use dependency injection and retrieve the storage class from the container:

$node_storage = $container->get('entity.manager')->getStorage('node');

And then proceed with the loading. Using dependency injection is usually the recommended way to go when it’s possible, i.e. when working within a class. This makes it easier to test your class and better decouples it from the rest of the application.


In this article we’ve seen how to work with querying and loading entities in Drupal 8. There has been an overhaul of the D7 EntityFieldQuery class that turned into a robust API for querying both content and configuration entities. We’ve looked at querying content entities but the system works just the same with config entities. And that is a bit of a win for the new Drupal 8 entity system.

We’ve also seen how to load entities based on the IDs resulted in these queries and what is actually behind the wrapper functions that perform these operations. Next up, we are going to look at defining our own content entity type in Drupal 8. For a refresher on how we do it in Drupal 7, you can check out these Sitepoint articles on the subject.

Jun 23 2014
Jun 23

In this article we will continue exploring the powers of Views and focus on how to use relationships, contextual filters and rewrite field outputs. In a previous tutorial I showed you how to create a new View and perform basic customizations for it. We’ve seen how to select a display format, which fields to show and how to filter and sort the results.

In this article we will go a bit further and see what relationships and contextual filters are – the two most important options found under the Advanced fieldset at the right of the View edit page. Additionally, we’ll rewrite the output of our fields and combine their values into one.

To begin with, I have a simple article View that just shows the titles. Very easy to set up if you want to follow along. And there are three things I want to achieve going forward:

  1. Make it so that the View shows also the username of the article author
  2. Make is so that the View shows only articles authored by the logged in user
  3. Make it so that the author username shows up in parenthesis after the title


First, let’s have the View include the author of the articles. If the View is displaying fields (rather than view modes or anything else), all we have to do is find the field with the author username, right? Wrong. The problem is the following: the node table only contains a reference to the user entity that created the node (in the form of a user ID – uid). So that’s pretty much all we will find if we look for user related fields: Content: Author uid.

What we need to do is use a relationship to the user entity found in the user table. Relationships are basically a fancy way of saying that table A (in our case node) will join with table B (in our case user) in order to retrieve data related to it from there (such as the name of the user and many others). And the join will happen in our case on the uid field which will match in both tables.

So let’s go ahead and add a new relationship of the type Content: Author. Under Identifier, we can put a descriptive name for this relationship like Content Author. The rest we can leave as default.

Now if you go and add a new field, you’ll notice many others that relate to the user who authored the content. Go ahead and add the User: Name field. In its settings, you’ll see a Relationship select list at the top where the relationship identifier we just specified is automatically selected. That means this field is being pulled in using that relationship (or table join). Saving the field will now add the username of the author, already visible in the View preview.


You can also chain relationships. For instance, if the user entity has a reference to another table using a unique identifier, you can add a second relationship. It will use the first one and bring in fields from that table. So the end result will be that the View will show fields that relate to the node through the user who authored the node but not strictly from the user table but somewhere else connected to the author. And on and on you can join tables like this.

Contextual filters

Contextual filters are similar to regular filters in that you can use mainly the same fields to filter the records on. Where contextual filters differ greatly is that you do not set the filtering value when you create the View, but it is taken from context.

There are many different contexts a filter value can come from, but mainly it comes from the URL. However, you can instruct Views to look elsewhere for contexts as well – such as the ID of the logged in user.

What we’ll do now is add a contextual filter so that the View shows only the articles authored by the logged in user. So go ahead and add a new contextual filter of the type Content: Author uid. Next, under the WHEN THE FILTER VALUE IS NOT IN THE URL fieldset, select the Provide default value radio. Our goal here is to have Views look elsewhere if it does not find the user ID in the URL.

contextual filters

You then have some options under the Type select list, where you should choose User ID from logged in user. This will make Views take the ID of the user that is logged in and pass it to the View as a filter. The rest you can leave as is and save the filter. You’ll immediately notice in your preview that only articles authored by you show up. The filtering is taking place dynamically. If you log in with another user account, you should see only the articles authored by that user account.

A great thing about contextual filters is that if you are displaying a View programatically in a custom module, you can pass the filtering value in code, which opens the door to many possibilities.

Rewriting fields

The last thing we will do in this tutorial is look at rewriting fields in order to concatenate their values. We will illustrate this technique by changing the title field to include the author username in parenthesis.

We’ll start by rearranging the order of the fields and move the title to be the last one showing. The reason we want to do this is that when you rewrite fields, you can use tokens that get values only from fields that are added before the one being rewritten. And since we want to rewrite the title field, we want the token for the username value to be present so we need to move it before the title field.

Now that the title field is last, edit the author username field and uncheck the box Create a label and then check the box Exclude from display. You can now save the field. The reason we are excluding this field from being displayed in our View is so that we don’t duplicate it once we concatenate it to the title field.

rewriting fields

Next, edit the title field and under REWRITE RESULTS, check the box Rewrite the output of this field. A new textarea should appear below where we will write the new contents of this field. If you write some gibberish in there and save the field, you’ll notice the title gets replaced by that gibberish.

Below this textarea, you’ll notice also some REPLACEMENT PATTERNS. These represent tokens of all the fields in the View loaded before this one (and including this one as well). So if you followed along, you’ll see there [name] and [title], among others.

What we need to do now is put these tokens in this box, wrapped with the text or markup we want. Having said that we want the username to be in parenthesis after the node title, we can add the following to the text box to achieve this:

[title] ([name])

Save the field and check out the result. Now you should have the author user in parenthesis. However, it’s still not perfect. We left the title field’s Link this field to the original piece of content box checked and this is breaking the output for us a bit due to also the username having a link to the user profile page. What we want is a clean link to the node title and in parenthesis (which themselves do not link to anything), the username linking to the user profile page.

So first up, add a new field called Content: Path (the path to the node). Make sure you exclude it from display, remove its label and move it before the title field. Then, edit the title field, uncheck the Link this field to the original piece of content box and replace the REWRITE RESULTS text with this:

 href="[path]">[title] ([name])

The [path] token is available from the new field we just added. And after you save, you should see already in the preview a much cleaner display of title nodes and usernames in parenthesis.


In this tutorial we’ve looked at three main aspects of building Views in Drupal 7: relationships, contextual filters and rewriting fields. We’ve seen how with the use of relationships we can use information also from related entities, not just those on the base table a View is built on. Contextual filters are great for when the View needs to display content dynamically depending on various contextual conditions (such as a URL or logged-in user). Lastly, we’ve learned how to rewrite fields and build more complex ones with values taken from multiple fields. As you can see, this technique is very powerful for theming Views as it allows us to output complex markup.

Views is pretty much the most popular Drupal module and it is highly complex. Despite its complexity, building views as a site administrator is very easy. All you need to understand is a few basic concepts and you are good to go. Developing for Views to extend its functionality or expose data to it is also an enjoyable experience. If you’d like to know more about that, you can read my tutorial on exposing your own custom module table to Views right here on Sitepoint.com.


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