Robin van Emden's blog on things Drupal
Robin van Emden's blog on things Drupal
The program committee shares about impostor syndrome and wants to remind community members that you know more than you give yourself credit for.
In the first days of December, the great news makes our hearts feel warm! We are happy to meet the sparkling fresh release — and show all our readers what’s new in Drupal 8.8.
It is, in fact, the last minor release of Drupal 8. The next one, 8.9, will come out on the same day with Drupal 9 — June 3, 2020. All D8 sites that are regularly updated and free from deprecated code will be instantly ready for Drupal 9.
Per the D7 release schedule we aim to release Drupal 7.68 on 2019-12-04.
Details of what will be in the release can be seen here:
https://www.drupal.org/project/drupal/issues/3097342
The final patches for 7.68 have been committed and the code is frozen (excluding documentation fixes and fixes for any regressions).
Relevant Change Record(s) for the release (this is not the full list of changes, rather only a list of notable API additions and other changes that might affect a number of other modules, so it's a good place to start looking for any problems):
If you do find any regressions, please report them in the issue queue. Thanks!
The last normal feature release of Drupal 8 includes a stable Media Library as well as several improvements to workspaces and migrations. The new experimental Claro administration theme brings a fresh look to site management. This is also the first release to come with native Composer support.
Stable Media LibraryThe Media Library module allows easy reuse of images, documents, videos, and other assets across the site. It is integrated into content forms and seamlessly fits into CKEditor. You can upload media right from the library and even reuse a combination of uploaded and existing media. Media Library was previously included with Drupal core as a beta experimental module.
New experimental administration themeThe Claro administration theme was added to Drupal core with beta experimental stability. The new theme is clean, accessible, and powerful. Administration pages are more touch-friendly, and color combinations and contrasts are more accessible.
Significant improvements to WorkspacesIt is now possible to define hierarchical workspaces (such as preparing a "New Year's" issue for a magazine under the "winter issue", while both receive changes to be deployed). Workspaces can now work with Content Moderation, and path alias changes can also be staged.
Native Composer support includedDrupal 8.8.0 is the first release to include native Composer support without reliance on third-party projects to set up Drupal with its dependencies. New sites can be created using a one-line command.
Migration improvementsThe multilingual migration path is still experimental, but has received various updates. This includes handling of vocabulary language settings, term language information, and localization. Modules can now specify whether migrations provided by them are finished or not finished to help audit completeness of available migrations.
New experimental Help Topics moduleThe existing help system is module based, whereas users intend to complete tasks, not use modules. A new task-based Help Topics beta experimental module has been added to bring in-Drupal help to the next level.
The way to Drupal 9Drupal 8.8 is the last minor release of Drupal 8 to include significant new features or deprecations prior to 9.0.0. The next (and final) minor release, 8.9, is planned to be a long-term support release that will include all the same changes as Drupal 9.0. It will not contain significant new features compared to 8.8.0, although existing experimental modules may become stable, and small API and UX improvements can still be added.
Drupal 8.9.0's planned release date is June 3, 2020, and our target release date for Drupal 9.0.0 is the same day. Most Drupal 9 preparation steps can be done on your Drupal 8 site, custom code and contributed modules now.
What does this mean for me? Drupal 8 site ownersUpdate to 8.8.0 to continue receiving bug fixes and prepare for 9.0.0 (or 8.9.0). The next bug-fix release (8.8.1) is scheduled for January 8, 2020. (See the release schedule overview for more information.) As of this release, sites on Drupal 8.6 will no longer receive security coverage. (Drupal 8.7 will continue receiving security fixes until June 3, 2020.)
Note that all Drupal 8.8.0 sites (new installs and updates) now require at least PHP 7.0.8.
Updating your site from 8.7.10 to 8.8.0 with update.php is exactly the same as updating from 8.7.8 to 8.7.9. Drupal 8.8.0 also has updates to several dependencies. Modules, themes, and translations may need updates for these and other changes in this minor release, so test the update carefully before updating your production site. Read the 8.8.0 release notes for a full list of changes that may affect your site.
Drupal 7 site ownersDrupal 7 is fully supported by the community until November 2021, and will continue to receive bug and security fixes throughout this time. From November 2021 until at least November 2024, the Drupal 7 Vendor Extended Support program will be offered by vendors.
The migration path for monolingual Drupal 7 sites is stable, as is the built-in migrationuser interface. For multilingual sites, most outstanding issues have been resolved. Please keep testing and reporting any issues you may find.
Translation, module, and theme contributorsMinor releases like Drupal 8.8.0 include backwards-compatible API additions for developers as well as new features.
Since minor releases are backwards-compatible, modules, themes, and translations that supported Drupal 8.7.x and earlier will be compatible with 8.8.x as well. However, the new version does include some changes to strings, user interfaces, internal APIs and API deprecations. This means that some small updates may be required for your translations, modules, and themes. Read the 8.8.0 release notes for a full list of changes that may affect your modules and themes.
This release has advanced the Drupal project significantly and represents the efforts of hundreds of volunteers and contributors from various organizations, as well as testers from the Minor release beta testing program. Thank you to everyone who contributed to Drupal 8.8.0!
Drupal VM 5.1.0 was just released (release name Recognizer), and the main feature is PHP 7.4 support; you can now begin running and testing your Drupal sites under PHP 7.4 to check for any incompatibilities.
PHP 7.4 includes some new features like typed properties, arrow functions, and opcache preloading which could help with certain types of code or site deployments (I'm interested to see if opcache preloading could help the startup time of Drupal inside container environments like Kubernetes!).
About the Webform module
The Webform module is a form builder and submission manager for Drupal. The Webform module allows site builders to customize forms and route submissions to multiple systems, including email, remote servers, and spreadsheets.
About the Group module
The Group module allows site builders to create arbitrary collections of content and users on a site and then grant users access to these collections. The Group module allows sites to build communities and manage their organization by creating groups of users with various levels of membership.
Problem
The Webform module for Drupal 8 does not fully integrate with the Group module. In Drupal 8, webforms are configuration entities, however, the Group module currently only supports content entities. To learn more about this issue, see Issue #2856333: Webform as group content.
Webforms can be attached to nodes, which are content entities which are supported by the Group module. This approach only provides access controls to determine which group members can simply view and submit a webform. It does not provide webform submission and element level access controls.
For example, a group could have a dedicated event registration system with a dedicated registration webform. A group administrator can control who has access to the event registration webform but there is no mechanism to allow group-specific roles to view, manage, and delete event registrations.
Solution
Provide webform submission and element level access controls to webforms attached to nodes.
Existing access controls
The Webform module already provides roles, user, and permission level access controls to webforms,...Read More
With our Drupal SEO guide, you don’t have to go too far in search of SEO tips, features and modules to boost your Drupal website ranking. Read and bookmark this for future reference!
We all know Drupal as this robust, flexible and dependable CMS platform but not many realize its abilities when it comes to SEO.
SEO can be one of the most influential factors for the success of an organization or a business. Did you know that 93% of online experiences start with search engines and 51% of all website traffic is attributed to organic searches (source)?!
When people from around the globe search for your product or services, you want to appear as high as possible on the search engine ranking. Improving your SERP (Search Engine Results Page) ranking is now more important than any other marketing strategy. Ideally, Drupal SEO is about making your website easy for both your visitors and the search engine crawlers to understand. Thus, your SEO strategy begins long before your Drupal website is built.
With an effective long-term perspective, its amazing collection of modules, its flexibility and customization options and not to forget, the loyal community working towards the betterment of the open source platform, Drupal 8 tops the CMS chart. Drupal 8 offers some exemplary SEO modules that can boost your Drupal 8 SEO and SERP ranking.
With Drupal 8, most of the required SEO best practices are already embedded into the core of the platform and with a little knowledge of SEO and some must-have configurations, anybody can possibly boost their website’s SEO to drive more traffic. But before you jump right into the tools and other configurations on Drupal 8, sit back and think about the basics which you need to get right for your website's success.
Things to remember -With Drupal 8 and the continuous innovation approach, it has adopted some of the best-in-class technologies thus making it more future-proof. More importantly, it has made content authoring more powerful and easier at the same time. One of the great things about Drupal 8 is that it is "SEO ready" right out of the box. To begin with, let us talk about some important Drupal SEO modules that help enhance your SEO efforts on your Drupal website.
1.Drupal SEO Checklist ModuleIf you are a ‘To-do-list’ person who is in love with organizing things, this module is for you. This is an important module which does not directly affect your Drupal SEO and improve the SERP but will provide critical information on the changes to be made on the site. The Drupal SEO Checklist module checks your entire Drupal website for proper search engine optimization against SEO best practices and tells you what to do. It provides a detailed report on what needs to be done to improve the performance of your Drupal website.
Drupal SEO Checklist
It keeps a track of how tasks have been taken care of, what has already been done (with timestamps) and what needs to be attended to. If a task needs you to install a module, it provides with a link to download it as well. This data provides a report that can be used for further monitoring.
2.Pathauto ModuleUsing clean URLs that indicate what content it represents is extremely important for SEO. One of the most important and useful modules for Drupal SEO, Pathautho plays a major role in creating SEO-friendly URLs on your website. The usual "example[dot]com/node/1" can be replaced with more SEO specific URL aliases such as "example[dot]com/page/keyword". Based on the category of your website page or based on the page title, with Pathauto you can build URLs which are SEO friendly. These intuitive URLs are easy for the visitors on your site to understand what they are looking at and where they are, which helps in improving your site ranking on search engines.
Pathauto Module
In our recent post, we discussed how you can add Google Analytics module to your Drupal website and also create custom reports for better performance of your website. Though the Google Analytics Drupal SEO module does not have any direct effect on your Drupal SEO or does not improve your ranking, it plays a major role in providing the necessary information that can amplify your Drupal 8 website's SEO success. By tracking your visitors, their behavior and interests within your site, you can change or add new strategies to drive more traffic and increase conversions. You can also use the GA Reports module that can provide you with a graphical representation and details reports about your Drupal website.
Google Analytics Module
Google certainly does not like spammy duplicate content on a web page. Such content can have a negative impact on your SEO efforts and as a result, can harm your rankings on the search engine. On Drupal, while you are happy creating clean URLs with the alias system, you should note that there is a small problem arising. With the creation of new URLs, the default URL still exists and the search engines do not see it as a good sign.
Global Redirect module
The Global redirect module helps in rectifying this problem by verifying the existence of an alias for a URL and redirecting it to the same. The module also plays a role in checking the URL implementation and permission or the access required to the nodes and URLs. However, this module has been deprecated for Drupal 8 and the functionalities are now merged into the Redirect module.
5. SEO Compliance Checker ModuleA module which is of great help to Drupal SEO beginners and webmasters, SEO Compliance Checker performs a complete check when a node is created or modified on your Drupal site. The execution includes checking if the titles and meta tags are optimized, no alt tags are missing, optimized keywords usage and other important factors for better SEO and to improve keyword ranking.
SEO Compliance Checker Module
While the core module - seo_checker does not perform any of these checks, it is the submodules that come along (basic_seo_rules.module and keyword_rules.module) which execute these checks for the implementation of some basic SEO rules. The core Drupal module on the other hand, gathers the required information about the checks to be performed and applies them to collect the results.
In addition to these modules, there are many other Drupal 8 SEO modules such as the Page Title module which allows the page title to be set, the Meta tag module which equips you with complete control of meta tags on your Drupal website, and the XML Sitemap module to create a search engine readable, dynamic sitemaps.
Just to let you know, in the time you took to read the blog until this point,
The internet is noisier than ever now, and it doesn't seem like it is going to stop anytime soon. SEO at its beginning stages was all about cramming your website with keywords and let the crawlers do their magic. But over time, SEO has blossomed with Google introducing some amazing algorithms and updates to curb the black hat SEO practices.
Right now, for a successful Drupal 8 SEO campaign, you need to study your visitors, their behavior and interests on your website and curate the content accordingly to stay ahead of the curve. You don't want to be in the midst of a content gap which can create problems for your website's conversions. With this study, you have a real opportunity in hand to develop fresh content for your Drupal website and optimize it for the searches on the search engine.
With Drupal, using the right SEO modules can take your website to the top of search engine rankings to set you up for success. But not everybody knows how the Google algorithms work and when the team is going to make the next change that could affect your Drupal website. So, stick to your basics, avoid duplicate content, keyword stuffing, use human-friendly URLs and create your website in a way that your visitors find it quite helpful. Partner with the right
Drupal development company who will design your Drupal strategy carefully and use the best Drupal SEO modules for your website.
Leave us a Comment
Shefali ShettyApr 05, 2017 Recent Posts Image How these Drupal SEO Modules (and tips) can boost your Website Ranking Image A quick guide to Drupal Sitemaps (and why you need one) Image Spam prevention guidelines for your Drupal Website Looking to optimize your Drupal site for SEO in the best way possible ? Talk to us Featured Success StoriesKnow more about our technology driven approach to recreate the content management workflow for [24]7.ai
linkFind out how we transformed the digital image of world’s largest healthcare provider, an attribute that defined their global presence in the medical world.
linkDevelop an internal portal aimed at encouraging sellers at Flipkart to obtain latest insights with respect to a particular domain.
link
The BigCommerce for Drupal module, created by Acro Media in partnership with BigCommerce, was released early this year and brings together two different platforms – BigCommerce, the open SaaS ecommerce platform, and Drupal, the open source content management system. The result provides a wonderful new way for retailers to implement an innovative and content rich headless ecommerce strategy. If you use one and would like to have the capabilities of the other, the BigCommerce for Drupal module is the bridge you need. With this module, you can use Drupal as the powerful front-end CMS with BigCommerce as the easy-to-use and scalable ecommerce backend.
This post is a step-by-step guide for people who want to know how to install the BigCommerce for Drupal module and get started with both platforms. If you just want to know more about the BigCommerce and Drupal together as ecommerce solution, check out this post instead.
How this module worksHere’s a quick overview of how this all works. The BigCommerce for Drupal module integrates BigCommerce and Drupal together, but each platform is still used for different tasks.
In BigCommerce, you configure products, categories, shipping, taxes and everything else for the ecommerce side of your site. BigCommerce is also where you go to manage orders as they come in.
Drupal is then used for the website frontend and theming. Product and category information from BigCommerce are synced to Drupal, importing them as Drupal Commerce products so that they can be displayed and used like any other Drupal-based content. Any non-commerce content is also managed within Drupal. When a customer goes to checkout, a BigCommerce checkout pane is embedding in the Drupal site to securely process payment and save customer and order information.
Setup BigCommerce and DrupalOn to the guide! Follow these steps and you’ll have your BigCommerce and Drupal store configured in no time!
PrerequisitesThis guide already assumes that you have the following ready.
With the prerequisites done, here’s what you need to do to the the BigCommerce for Drupal connection made.
Step 1: Create a BigCommerce API accountThe BigCommerce for Drupal module is ready for production and available for all to use. When writing this guide, there were some additional notes that I wanted to share.
Acro Media is the development team partnered with BigCommerce that made the BigCommerce for Drupal module a reality. We have many, many years of ecommerce consulting and development experience available to support your team too. If you’re interested in exploring Drupal, BigCommerce or both for your online store, we’d love to talk.
The steps that any new launch or high traffic event should go through in order to have the best chance of success. This post is aimed at the project management level, so will try to stay out of the weeds, and focus on the high level topics you need to think about. There is a ~18 minute recording at the end of this post where I presented this topic at Drupalsouth 2019.
Title slide from the presentation.Preamble: What could be considered a high traffic eventLaunching a brand new site
Additional insurance against a lot of traffic is distributing your cached content to all corners of the globe.
Tiered caching should be used to ensure the highest offload rate. Most CDN providers will support this at a given price point.
Step 3) Cache tuning and minimising origin requestsEvery request that bypasses your CDN layer adds load to the platform. In order to have the best chance of surviving a high traffic event, origin traffic needs to be carefully considered and reduced where possible.
Requests to origin that are often overlooked
It you are interested in WAF tuning, you should check out my talk last year on using Cloudflare to secure your Drupal site.
This has happened to a customer of mine in the past. Fun fact the gclid and dclid query parameters are guaranteed unique for every user and click. This effectively makes them un-cacheable.Step 4) Load testingIf you are building a new site, or are expecting a substantially different traffic profile than what you have currently, then you should look to load test the system.
At the end of this task (they you may need to run several times), you should have the confidence that you can handle the traffic expected.
Step 5) Hardware (auto) scalingNow that you have the hardware you need to have in place with load testing, ensure you have autoscaling in place to deal with the peaks and troughs (it is unlikely you need to run your peak hardware for the entire duration of the event).
Autoscaling can also help if the origin traffic that you experience is higher than anticipated.
Test the autoscaler, set limits that you are comfortable with, and ensure you know how quickly the new resources take to come to life.
Be nice to your OPs team, use an auto scaler.Step 6) Have a good fallbackSay the worst does happen, and you site does go down, or a critical API drops off the face of the internet, what does the end user see? Can you offer at least a better experience than a generic web server error page?
Most CDNs will have the ability to load balance origins (hot DR), and even fallback to a static version of the site if all origins are down.
It would make sense to test this prior to the high load event as well.
ABC's news website went down just before Drupalsouth 2019, and someone managed to screencap it, and then send it to me. I am confident that you can come up with a better fallback than this error page.Step 7) Warm your cacheIf you have a rather long tail website, it will be worth warming your cache prior to the event. An excellent module called warmer has been written, to which allows warming all sorts of caches. It can for instance load every page in the XML sitemap. So this is fairly low effort, high reward.
Step 8) Third party API dependenciesThis is more of a fundamental design decision likely made much earlier on in the project. Say the content of your page is dependent on the content in an API response. If you request the API content during page generation time, then you are tying the speed and availability of your site to another site (often outside your control).
This can lead to slow page load times, and worse case scenario can tie up your server's resources.
New Relic APM has "external requests" to which allow you to visualise this.
There are ways to mitigate this:
During the event, having access to realtime (or near realtime) analytics to find out
Is extremely valuable. Even more valuable is being able to respond to this data in a quick and efficient matter. Having access to technical people can help. The types of logs and analytics you should be looking to get a hold of:
To see where you can take this, you might also be interested in reading this blog post that shows off some dashboards that were purpose built for a high traffic event.
An example dashboard that was written for a previous high traffic event that I was involved with. The data is around 6 minutes delayed, but still proved invaluable.Step 10) Application changes in a pinchIf you do spot something in your analytics, knowing what tools you have at your disposal to mitigate issues quickly and easily is worth knowing.
Knowing what tool will solve what problem, how long each option takes to deploy, how safe it is, how easy is the rollback is is absolutely critical.
Cloudflare's pagerules feature is an excellent way to make quick changes to how your application functions.Step 11) Letting your hosting provider and their support team knowNo-one likes surprises, so plan ahead. Ensure there are people available or on call during your traffic event. This goes for both your hosting provider, to CDN provider to support staff.
Postamble: What success looks likeSo after your high traffic event has ended, here are some simple things to check in order to see how successful you were:
Let me know in the comments if this was of use, and also if you have any other words of wisdom for anyone else.
With the Views module, it is possible to fetch pieces of data from a Drupal entity and display them according to a specific format. The Views module acts as a query builder, which generates the SQL code, in charge of retrieving the data from the database.
The first setting when creating a view allows you to choose the base table from which the aforementioned data will be recovered.
When you choose Content as the base table, you also have to specify the Content type, so it will not be possible to retrieve data from other content types and present it within the view unless you set a Relationship between those content types.
This tutorial will explain the concept of Relationships in Views with a basic example.
Let’s start!
At NEDCamp I had the pleasure of seeing many wonderful people and sessions, but, as you may know, my favorite track at most events is the "Hallway Track". If you're not familiar, the Hallway Track is the time in-between sessions where some real magic happens. You have a chance to talk with some of the most amazing minds in the world about topics you're passionate about. You can share knowledge, bounce ideas, have epiphanies, and realize that your current problems (code-wise) are things that other people have run into. One such conversation happened that inspired me to think outside the box to solve a problem.
In my last post we went over how to create a related content section with references to entities that may have empty fields. Today, we're going to take that one step further and create landing pages for content types.
In Drupal, we would ordinarily build these by attaching a view to a content type based on contextual filters or similar in order to get a collection of all content of that content type. Since we don't have Views in GatsbyJS, we need another solution. There are a couple of options out there, including the recently released JSON:API Cross Bundles module, compliments of Centarro and Matt Glaman. However, at the time of this writing there is an issue with the JSON:API Cross Bundles conflicting with JSON:API Extras. So, if you're relying on JSON:API Extras, you'll need another solution.
The problem:Out of the box, JSON:API does not create a route to retrieve all nodes with any ease. However, there's no need to fear. This post is here!
Now if you're not using JSON:API Extras, I strongly recommend looking into JSON:API Cross Bundles. It creates a route to all content and will simplify your life. If you are using JSON:API Extras, have I got something for you.
Let's dive in.
Scenario:You're building a decoupled Drupal site and you want to have a reusable template for landing pages that display all content of a content type. This is easy enough to do in Drupal using Views, but we lose Views when going decoupled so we need another way. How do we accomplish this in a decoupled application using GatsbyJS as the front-end?
Solution:Strap in folks, this one gets a little bumpy.
Drupal side:We need to do some work on both sides of the application for this to work. First, we will setup a content type in Drupal to use for our Content Landing Pages. This is kind of a choose your own adventure scenario, but one thing that you absolutely must have is an Entity Reference field that references the Config Entity: Content Type with a cardinality of 1.
Select this field type:
And this is the entity type to referenc
Now that we have our field created, select any content type that will require a content landing page as an available option.
Whatever else you want to put on this page is up to you. Go wild. Want a hero image? Add a hero image. Want a dancing baby gif? That's your choice and I respect it. Once you've finished making the greatest landing page content type ever™ we can move on to the fun part in GatsbyJS.
GatsbyJS side:JSON:API gives us something that can help us out a bit. It goes by the name allNodeTypeNodeType and it will let us workaround the lack of a base all-content route. If we explore this in GraphiQL we'll see that we can drill down a bit and get exactly what we need.
{ allNodeTypeNodeType { nodes { relationships { node__article node__landing_page node__basic_page } } } }NOTE: I didn't drill down too far, but all fields are available here.
Let's first create our landing page template in Gatsby.
First, let's just create a simple, empty component for our Landing Page with a basic graphql query.
// src/components/templates/LandingPage/index.js import React from 'react' import { graphql } from 'gatsby' function LandingPage({ data }) { return ( ) } export default LandingPage export const query = graphql` query($LandingPageID: String!){ nodeLandingPage(id: { eq: $LandingPageID }) { id title } } `Nothing too fancy here, right? Just a template that we can use to build our pages out without Gatsby yelling at us on build.
Next, we're going to add this template to gatsby-node.js so that we create our pages dynamically.
// gatsby-node.js exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions const LandingPageTemplate = require.resolve(`./src/components/templates/LandingPage/index.js`) const LandingPage = await graphql(`{ allNodeLandingPage { nodes { id path { alias } } } } `) LandingPage.data.allNodeLandingPage.nodes.map(node => { createPage({ path: node.path.alias component: LandingPageTemplate, context: { LandingPageID: node.id, } }) }) }This is pretty straightforward so far, right? Let's think about what we're going to need in order for this to work the way we want it to and pull all of a single content type into our landing page.
We're going to need:
How are we going to get these things? Let's go down the list.
The content type we want to build a landing page from:
We have this from our Drupal side. Remember, we created the Content Type field on our Landing Page content type? This can be placed in our gatsby-node.js and passed to our query via the context option.
Let's add it in. First we need to update our graphql query to pull it in:
// gatsby-node.js const LandingPage = await graphql(`{ allNodeLandingPage { nodes { id relationships { // <---- add from this line field_content_type { drupal_internal__type name } } // <---- to this line } } } `)What we're doing here is looking at GraphiQL and exploring our data to see what we have available. If we drill down into allNodeLandingPage.nodes we can see that in relationships we have field_content_type with some useful things. Specifically, our drupal_internal__type and name values. Also, notice that we removed nodes.path.alias from the query.
By adding these to our query we can now pass the info through to our created pages. We're going to do a bit of data manipulation here to create our paths dynamically as well. I follow the convention that a landing page's path should reflect the content type that it's a landing page for. So, if we were making a landing page for "Articles" the path would be path-to-my.site/articles and articles would have that as a base path to path-to-my.site/articles/my-awesome-article. However, you can follow whatever convention you see fit.
To do this, we're going to manipulate the name from the content type into a URL-friendly string by using the JavaScript .replace() function and then pass that to the path option. Since we also want to query for the content type on our landing page, we're going to pass the drupal_internal__type through the context option.
Let's do that:
// gatsby-node.js LandingPage.data.allNodeLandingPage.nodes.map(node => { const pathName = node.relationships.field_content_type.name.toLowerCase().replace(/ /g, '-') // <---- New line createPage({ path: pathName, // <--- Changed line component: LandingPageTemplate, context: { LandingPageID: node.id, ContentType: node.relationships.field_content_type.drupal_internal__type, // <---- New line } }) })What does the the context option do? It passes data to our component as props. GraphQL already pulls the context data for the queries, which you can see in any query that has a variable for the filter. Usually this is the content ID so that it can build a page for a specific piece of content from Drupal, but we can leverage this to add more variables and more filtering however we see fit.
Our next step is going to be to actually USE this additional info to do something amazing with.
A query to fetch all content a content type:
Let's look back at our src/components/templates/LandingPage/index.js and see what we need to query. We know we want to get all nodes of a certain content type, and we know that we want to reuse this template for any landing pages with content listing. Since we've established that allNodeTypeNodeType gives us access to all content on available to Gatsby, let's query on that.
// src/components/templates/LandingPage/index.js export const query = graphql` query($LandingPageID: String!, $ContentType: String!){ nodeLandingPage(id: { eq: $LandingPageID }) { id title } allNodeTypeNodeType(filter: { drupal_internal__type: { eq: $ContentType }}) { // <---- New section nodes { relationships { node__article { id title path { alias } } node__page { id title path { alias } } } } } } `What we're doing here is using that variable we passed via the context option in gatsby-node.js and filtering to only return the content type we're wanting to see. One 'gotcha' here is that this query will also return the landing page that references the content type. However, if you're not creating a landing page of landing pages then you should be alright.
Since we're only creating landing pages for two content types, this is fine, although we're not getting a lot back. Most projects that I've worked on have had some kind of "teaser" display for these kinds of pages. I'm not going to cover the specifics of creating a teaser template here, but the TL;DR is: start with your full display and take out everything but what you want on the teaser. For this post, we're going to create the list of links using the titles.
Now, if the content types that we're creating landing pages for don't have any content, then you're going to have a bad time. In this case, go back to my previous post about empty entity reference fields and see if you can use that to create some default fields and prevent errors or just create some content of the missing type.
Next, let's flesh out our landing page template a bit.
The landing page template with logic to display the content type:
So far, our template, minus the query, is pretty empty and not doing a lot. Let's add in the title of this landing page.
// src/components/templates/LandingPage/index.js function LandingPage({ data }) { const landingPage = data.nodeLandingPage return ( {landingPage.title} ) }I like to clean up the variables a bit and rename data.nodeLandingPage to landingPage. It's a bit cleaner to me, but do what you want.
Alright, we have the title of this content, but what about the list of content we want to show on this page? Well, we're going to need to do some logic for that. First off, we need to know which content type we're looking for. Second, we need a way find it. Third, we need to clean this data into something usable. Finally, we need to display it.
We could just display everything returned from our allNodeTypeNodeType query, but there would be a lot of nulls and issues parsing the arrays. Here's an example of what that query returns before we massage the data, using the Drupal internal type article:
{ "data": { "allNodeTypeNodeType": { "nodes": [ { "drupal_internal__type": "article", "relationships": { "node__article": [ { "id": "0e68ac03-8ff2-54c1-9747-3082a565bba6", "title": "Article Template", "path": { "alias": "/article/article-template" } } ], "node__basic_page": null } } ] } } }Now, to get the content this way we could do some complex mapping and sorting and filtering, but I tried that and it wasn't fun. Fortunately, Gatsby is here to rescue us and make life easier. Our context option gets passed into our page component as props. If you're unfamiliar with the concept of Props in React, and therefore Gatsby, props are properties that are passed into components. The line
function LandingPage({ data }) {could be rewritten as
function LandingPage(props) { const data = props.databut we're using a concept called Destructuring to only pass in the prop that we need. This allows us to create variables from object keys without having to take the extra steps. Our page component props object also contains the key pageContext which is where anything in the context option gets stored to give the page template access to.
Let's bring that in:
// src/components/templates/LandingPage/index.js function LandingPage({ data, pageContext }) { const landingPage = data.nodeLandingPage const nodeType = data.allNodeTypeNodeType const contentType = 'node__' + pageContext.ContentTypeSince we set our ContentType in gatsby-node.js we're able to use that here. Note that we're concatenating the string node__ with our pageContext.ContentType. We're doing this because everything in Gatsby is a node, including content types. This allows us to do the next steps.
Next, we want to clear out all of the non-content type data from the allNodeTypeNodeType query. This is what it looks like if we were to console.log(nodeType.nodes):
Array(1) 0: relationships: node__article: Array(1) 0: {id: "0e68ac03-8ff2-54c1-9747-3082a565bba6", title: "Article Template", path: {…}, …} length: 1 __proto__: Array(0) node__page: nullWe only want the node__article array, so how do we get that? Well, we need to use .map() and a concept called currying. This is essentially creating a function that allows us to use a variable from outside of the .map() scope inside of the .map() callback. It allows us to break down a function into more functions so that we have more control over it, which is what we need here.
// src/components/templates/LandingPage/index.js function LandingPage({ data, pageContext }) { const landingPage = data.nodeLandingPage const nodeType = data.allNodeTypeNodeType const contentType = 'node__' + pageContext.ContentType const getContentArray = (contentType) => { // <---- Curry function, but not as delicious return (node) => (node.relationships[contentType]) } const contentArray = nodeType.nodes.map(getContentArray(contentType))We created our curry function that takes our contentType as an argument. From within there, it completes the mapping and returns our desired array... almost.
Here's what we get back if we console.log(contentArray):
[Array(1)] 0: Array(1) 0: {id: "0e68ac03-8ff2-54c1-9747-3082a565bba6", id: 1, title: "Article Template", …} length: 1 __proto__: Array(0) length: 1 __proto__: Array(0)We're almost there, but now we have an array of our content within another array. If only there were a function to help us out here...
Just kidding, there is! For this, we're going to use .flat(). The .flat() function flattens out a nested array into a single level. However, there's a gotcha with it, as mentioned in this Stack/Overflow question. We can get around this by using the gatsby-plugin-polyfill-io plugin.
Add gatsby-plugin-polyfill-io to your project by installing with yarn or npm
npm install gatsby-plugin-polyfill-io // or yarn add gatsby-plugin-polyfill-ioand in your gatsby-config.js file add the following within module.exports = {
plugins: [ { resolve: `gatsby-plugin-polyfill-io`, options: { features: [`Array.prototype.map`, `Array.prototype.flat`] }, }, ]This will also create polyfills for the .map() function, which I use heavily.
So, let's flatten that array!
function LandingPage({ data, pageContext }) { const landingPage = data.nodeLandingPage const nodeType = data.allNodeTypeNodeType const contentType = 'node__' + pageContext.ContentType const getContentArray = (contentType) => { return (node) => (node.relationships[contentType]) } const contentArray = nodeType.nodes.map(getContentArray(contentType)) const contentArrayFlat = contentArray.flat()And the resulting console.log(contentArrayFlat):
0: id: "0e68ac03-8ff2-54c1-9747-3082a565bba6" path: {alias: "/article/article-template"} title: "Article Template" length: 1 __proto__: Array(0)Now we've got exactly what we wanted! The final step is to put this to work. We'll do that by creating a list of titles that link to the content. Your finished component should look like:
// src/components/templates/LandingPage/index.js import React from 'react' import { graphql, Link } from 'gatsby' // <--- added 'Link' here to use the link component function LandingPage({ data, pageContext }) { const landingPage = data.nodeLandingPage const nodeType = data.allNodeTypeNodeType const contentType = 'node__' + pageContext.ContentType const getContentArray = (contentType) => { return (node) => (node.relationships[contentType]) } const contentArray = nodeType.nodes.map(getContentArray(contentType)) const contentArrayFlat = contentArray.flat() return ( {landingPage.title}And that's all there is to it. Hopefully you find this useful and it helps speed up your development with Gatsby a little bit. If I missed anything on here, please don't hesitate to let me know in the comments. Always feel free to reach out to me on Twitter or Slack or any way you want to.
Credit where credit is due: Shane Thomas (AKA @codekarate) and Brian Perry (AKA @bricomedy) helped me work through this issue at NEDCamp.
Patron thanks:Thank you to my Patreon Supporters
For helping make this post. If you'd like to help support me on Patreon, check out my page https://www.patreon.com/jddoesthings
Category Development Tags Drupal Planet GatsbyJS react Drupal CommentsGiven the facts and figures in this study, there are more than 58 percent of people who prefer their smartphones over desktop or laptop to browse information on the internet. And when those responsible for the development (at the backend) decide to go ahead without any changes for the mobile, the users start getting annoyed.
In this blog post, we’ll take a look at what a typical month looks like for a developer working at Agiledrop: their daily and weekly tasks, monthly activities and events, and the general office atmosphere.
READ MOREWhen was the first time you decided to write some generic code and publish on Drupal.org? Thank you for taking that decision! That idea has grown big and your code is might be in Drupal core now! You still remember about views and CCK, right?
Drupal community is driven by you, me and all the users who want to build awesome websites using Drupal. One way or the other, we enrich the community by sharing tips in forums, on various Drupal channels and events we take part in. Some of us take this to next level by volunteering at those events and make everything easier for us! We are not stranger to each other anymore as we used to be a decade ago. We now know everyone from social media, posts in forums, Drupal channels and Drupal events. Isn’t Drupal community amazing?
Help Drupal community grow further Build modules
If you have an idea that can benefit everyone, you are welcome to share it with the community. For example, You can integrate third party APIs with Drupal and contribute that code to community. Or maybe some generic code from your latest project! Every bit counts.
Build themesClaro and a few other themes are completely community efforts. If you have this awesome design idea, you can consult with other developers and put efforts in to build a theme out of it.
Submit patchesOf all those projects contributed to community, most of them are well maintained but usually due to the time constraints, maintainers may not be able to address all the issues listed on the queue. You can take this opportunity and help fix those issue. Once done, you can submit the path for a community review. After testing, your patch goes to production version and We Won!!!
Reply in forumUsually, new Drupal developers post in Drupal forums. Most of us did when we were first introduced to Drupal. Forums are the best way to help Drupal aspirants and give them what they are looking form – some tips and right approach to a problem!
Review patchesLend a helping hand by reviewing those submitted patches on project issue queue. This expediates the process to fix the particular issue and confirms that if particular patch works or not.
Write a book page or twoIs there something big on your mind that community can get benefit from? You can write a book page or pages and guide the community. This can be some insights about a Drupal feature or a trick you learned while working on your project at your job.
Help organize eventsIf an event is going to be organized in your city/country, can you help them anyways? They need help with logistics, building and updating the event website and what not!
Educate / mentor Drupal aspirantsYou can guide both junior and senior developers by helping them with contributing to Drupal in all the ways just described. You can speak at an event and that is a great experience for both new developers as well as senior developers.
Share tipsSharing tips is fun! We do it on social media and those Drupal channels on various other platforms on regular basis. When we see someone struggling with an issues with Drupal and post on those media, we rescue them by posting multiple approaches and tips. Sometimes, these conversations take interesting turn and end up being a contribution to Drupal in form of an event, a module or a theme!!
You can find all the details about how to get involved on communit page
Drupal Drupal 8 Drupal 9 Drupal Planet Get Updates I agree to the privacy policy Email Address CAPTCHA This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.Giving Tuesday (known online as #GivingTuesday) is the Tuesday after the Thanksgiving holiday in the United States, held on December 3, 2019. What began in the States has grown over the years into an international day dedicated to charitable giving at the beginning of the holiday season, whereby hundreds of millions of people give, collaborate and celebrate generosity.
Coincidentally, givingTuesday.org is built using Drupal!
At the Drupal Association, we’ve decided to participate for the first time this year. Knowing the Drupal Community likes to have fun and delve into challenges — such as the ever-popular Trivia Night held during DrupalCons — our staff collaborated to create a trivia challenge never before seen, with Drupal project and product questions, Association facts and more.
We challenge you to take the quiz on #GivingTuesday December 3rd, and to share with friends to see who can crack this code! Note: Not a literal code! Visit Drupal.org/giving-tuesday-2019 on Tuesday for the link.
We’ll update the leaderboard and congratulate players throughout the day on December 3!
Thanks in advance for playing, and we encourage you to post your trivia score on social media; this may be our most challenging trivia game yet!
We hope you'll take a minute to support the Drupal Association and join/renew membership or donate on this international day of giving. At the end of Giving Tuesday, we’ll announce three leaderboard winners: who has won the trivia, who donated the most, and who referred the most new members. The top 10 winners shown on each leaderboard will be entered to win a handcrafted Drupal prize (hint: it might be pictured in this photo)!
#GivingTuesday
#MyGivingStory
#GivingToDrupal
photo from DrupalCon Seattle opening reception by Hussain Abbas (hussainweb)