Building an app in Drupal's theme layer

Submitted by swim on Thu, 11/05/2015 - 11:30

Drupal 8 as many people have already pointed out provides a great base for front end developers regardless of your chosen stack. Providing REST as core functionality has created a standardised approach which when left up to contrib can often become enigmatic.

This article aims to explain the benefits of building a JavaScript application via Drupal's theme layer. Mithril JS will be used as the client side framework, however the core concepts could be applied to others as well. 

For those interested in learning more JavaScript instead of another framework I strongly recommend giving Mithril JS a try. Mithril is more inline with React than Angular providing a classic MVC design pattern without the additional weight and learning curve a framework traditionally inroduces.

One of the biggest pitfalls of building an app is the ability to provide a HTML fallback. This is not solely for visitors which have JavaScript disabled (1.3% ish) but instead for search engines and crawlers. Eiriksm has already written a fantastic article which outlines these concerns. Eiriksm points out what a typical setup generally consists of and the benefits of using Drupal to generate your HTML. The flip side is if you don't have something like Drupal's traditional rendering method to fall back on you'll need to implement a service such as https://prerender.io.

The one downside here being a duplication of theme work. This can of course be mitigated by matching your HTML output from Drupal. Rule of thumb for me is to focus on the app; as long as the fallback provides a clean and readable page. Crawlers won't care about your sweet styles and people with JavaScript disabled probably aren't on Twitter so it won't come back at you.

Before we start writing any JavaScript we need to configure our REST client; there's a number of articles already on downloading and configuring the REST UI, follow those first if it's not setup. Enable the content resource, enable the GET method with your desired format and auth (I use JSON and cookie).

To help handle our requests to Drupal I have written a small wrapper for Mithril's m.request function. The wrapper provides a number of common features we'll need when communicating with Drupal. The wrapper can be found here.

  • Checks and sets the users CSRF token
  • Tracks request completion status
  • Provides a request queue
  • Provides a request cache
  • Sets the request format

The first example illustrates how to load a single node from Drupal. The first object passed contains all the standard information required by m.request; method, url etc.


var response = md.request({
  method: 'GET',
  url: '/node/1',
  background: true
});

The second example illustrates how to override the default format type, set request headers and provide a redraw timeout.


var response = md.request({
  method: 'GET',
  url: '/node/1',
  background: true
}, {
  headers: [
    {
      type: 'Content-Type',
      value: 'application/json'
    }
  ],
  format: 'json',
  redrawTimeout: 1500
});

Requests to Drupal can also be queued, allowing access to an array of results. This generally makes for more performant and organised code.


var nodes = md.queue([
  {
    method: 'GET',
    url: '/node/1',
    background: true
  },
  {
    method: 'GET',
    url: '/node/2',
    background: true
  },
  {
    method: 'GET',
    url: '/node/4',
    background: true
  }
]);

Bringing all of the above together I have made a very rough version of the classic Bartik theme. The example theme/site is located here.

While these are some nice examples they are very simple and lack (any) finesse, a problem only love can solve (more time). Hopefully over the coming months I'll have the opportunity to utilize these tools in more projects.