Hello there! There has been a lot of discussion in the Drupalsphere lately about a concept that has been coined “Headless Drupal”, and rightly so. It’s basically theming, but throwing out the theme layer. The theme layer in Drupal is very powerful, but has always felt severely over-engineered to me, especially in contrast to pretty much any MVC framework I’ve played with. With those, you define view-layer variables in a controller class, and you write HTML with a little bit of code to print them out into HTML. It’s more work up front, since you have to write code, but it’s vastly easier once you get over that hump.
The company I work for has been doing exactly this with AngularJS since early this year, and I’ve yet to see a concise post about how to get started with it in the context of Drupal. I rarely write “how-to” posts, but I figured it’d be a good way to inaugurate the ABM tech blog.
Our use case (feel free to skip)
Early this calendar year, my boss’ boss came to us with a business request — build us a framework on which we can make our up-until-lately desktop-only websites a little more mobile friendly. We were using a rather ungainly combination of Panels and Adaptivetheme, and though those should have given us a good base on which to build, we had managed to mess it up.
Our original themer was a designer who learned CSS on the job, and our stylesheets were an enormous mess. Absolute positioning, widths specified in pixels, subthemes that had huge amounts of repetitive CSS rules that could’ve been rolled up into the parent theme. Rewriting these sheets would’ve been prohibitively expensive, and wouldn’t have gained us anything in the eyes of the business.
To add to that, the aforementioned boss’ boss was really keen on what we in the biz call “HTML5 mobile apps” that felt more like a native app rather than just a website that is readable on the phone. UI patterns would include swiping to navigate between stories, storing articles to read later, offline support, etc. Basically, not things you can do in any Drupal theme that I know of.
I spent a few days in R&D mode trying to figure out how to fake these things with pre-fetching pages so they’d be rendered already when the user swiped, but it was a mess.
I knew in the back of my head that I was doing it the wrong way, but it took some prototyping to convince myself that what we indeed needed to do was to throw out the book on Drupal theming and do this another way.
I love writing Javascript, and I’d finally found a use case for which one of these JS MV* frameworks might actually fit the bill.
The Drupal setup
So, assuming you have a clean Drupal install spun up already (if you don’t, may I suggest drush core-quick-drupal
?), you’ll want to download a couple of modules to get going.
- Views (obviously! don’t forget the ctools dependency!)
- Views Datasource (this lets you spit out views as JSON).
- Devel (for generating some content if you don’t already have some)
- CORS (just trust me, I’ll get to this one later)
Or you can just do a drush dl views ctools views_datasource cors devel
and be done with it.
Enable all these modules - drush en views views_ui devel devel_generate cors views_json -y
.
Generate some content - drush generate-content 50 0 --types=article
Ok, you’re ready to hop into the UI!
Pretty much all the action at this point is going to happen in Views, so navigate to admin/structure/views, and “Add new view”.
- Name it whatever you want, may I suggest “json articles”?
- You want to show “Content” of type “Articles” sorted by “Newest first”.
- Create a page, yes. Display format will be “JSON Data Document”. Continue and edit. .
- Just add a few fields, since you only have the title so far. Add the Body, the nid, and the date in whatever format you please.
- You do want to create a label, but you’ll be better off customizing it to be all lowercase and to have no spaces. ie. body, post_date, etc.
In the preview, you should see a pretty-printed json list of your 10 most recent articles, as generated by Devel.
Congrats! The Drupal part is done! We’ll be visiting the more interesting part in the next post.