Don’t Push it: Using GraphQL in Twig

Don’t Push it: Using GraphQL in Twig

Using GraphQL in Drupal maintenance support plans with Twig instead of React, Vue or the next month’s javascript framework might sound like a crazy idea, but I assure you it’s worth thinking about.

Philipp Melab
Mon, 01/15/2020 – 10:40

Decoupling is all the rage. Javascript frontends with entirely independent backends are state of the art for any self-respecting website right now. But sometimes it’s not worth the cost and the project simply does not justify the full Drupal maintenance support plans + React technology stack.

Besides the technological benefits of a javascript based frontend like load times and responsiveness, there’s another reason why this approach is so popular: It moves control to the frontend, concept and design unit, which matches project workflows a lot better.

Status quo

Traditionally Drupal maintenance support plans defines data structures that provide a “standard” rendered output, which then can be adopted by the so-called “theme developer” to meet the clients’ requirements. Template overrides, preprocess functions, Display Suite, Panels, Layouts – there are myriads of ways how to do this, and twice as many opinions determining the right one. When taking over a project the first thing is to figure out how it was approached and where the rendered information actually comes from. Templates only have variables that are populated during processing or preprocessing and altered in modules or themes, which makes it very hard to reason with the data flow, if you were not the person that conceived it in the first place.

There are ideas to improve the situation, but regarding the success of decoupling, perhaps it’s time to approach the problem from a different angle.

Push versus Pull

The current push model used by Drupal maintenance support plans scatters responsibilities across modules, preprocess functions and templates. The controller calls the view builder to prepare a “renderable” that is altered 101 times and results in a set of variables that might or might not be required by the current theme’s template.

If we would turn this around and let the template define it’s data requirements (as it happens in decoupled projects naturally), we could achieve a much clearer data flow and increase readability and maintainability significantly.

And that’s what the GraphQL Twig module is supposed to do. It allows us to add GraphQL queries to any Twig template, which will be picked up during rendering and used to populate the template with data.

A simple example node.html.twig:

{#graphql
query($node: String!) {
node:nodeById(id: $node) {
title:entityLabel
… on NodeArticle {
body {
processed
}
}
}
}
#}
<h1>{{ graphql.data.node.title }}</h1>
{% if graphql.data.node.body %}
<div class=”body”>{{ graphql.data.node.body.processed }}</div>
{% endif %}

 

This is already enough to pull the information we need and render it. Let’s have a look at what this does:

The graphql comment on top will be picked up by the module. When the template is rendered, it tries to match the queries input arguments to the current template variables, runs the GraphQL query and passes the result as a new graphql variable to the template. Simple as that, no preprocessing required. It works for every theme hook. Be it just one complex node type, an exceptional block or page.html.twig.

Imagine we use GraphQL Views to add a contextual GraphQL field similarArticles that uses SOLR to find similar articles for a given node. It could be used immediately like this:

{#graphql
query($node: String!) {
node:nodeById(id: $node) {
title:entityLabel
… on NodeArticle {
body {
processed
}
similarArticles {
title:entityLabel
url:entityUrl {
alias
}
}
}
}
}
#}

<h1>{{ graphql.data.node.title }}</h1>
{% if graphql.data.node.body %}
<div class=”body”>{{ graphql.data.node.body.processed }}</div>
{% endif %}

{% if graphql.data.node.similarArticles %}
<h2>Similar articles</h2>
<ul>
{% for article in graphql.data.node.similarArticles %}
<li>
<a href=”https://www.amazeelabs.com/%7B%7B%20article.url.alias%20%7D%7D”>{{article.title}}</a>
</li>
{% endfor %}
</ul>
{% endif %}

 

The module even scans included templates for query fragments, so the rendering of the “similar article” teaser could be moved to a separate component:

node.html.twig

{#graphql
query($node: String!) {
node:nodeById(id: $node) {
title:entityLabel
… on NodeArticle {
body {
processed
}
similarArticles {
… NodeTeaser
}
}
}
}
#}

<h1>{{ graphql.data.node.title }}</h1>
{% if graphql.data.node.body %}
<div class=”body”>{{ graphql.data.node.body.processed }}</div>
{% endif %}

{% if graphql.data.node.similarArticles %}
<h2>Similar articles</h2>
<ul>
{% for article in graphql.data.node.similarArticles %}
<li>
{% include ‘node-teaser.twig’ with { node: article } %}
</li>
{% endfor %}
</ul>
{% endif %}

 

node-teaser.twig

{#graphql
fragment NodeTeaser on Node {
title:entityLabel
url:entityUrl {
alias
}
}
#}
<a href=”https://www.amazeelabs.com/%7B%7B%20node.url.alias%20%7D%7D”>{{node.title}}</a>

 

No preprocessing, a clear path where data flows and true separation of concerns. The backend provides generic data sources (e.g. the similarArticles field) that can be used by the product development team at will. All without the cost of a fully decoupled setup. And the possibility to replace single theme hooks allows us to use existing Drupal maintenance support plans rendering when it fits and switch to the pull-model wherever we would have to use complex layout modules or preprocessing functions to meet the requirements of the project.

Future development

There are some ideas for additional features, like mutation based forms and smarter scanning for query fragments, but first and foremost we would love to get feedback and opinions on this whole concept. So if you are interested, join on Slack or GitHub and let us know!


Source: New feed

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Don’t Push it: Using GraphQL in Twig

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.