Goal
Add a content type to Acquia CMS Headless and the Next.js frontend, with Markdown input.
Prerequisites
Overview
The latest iteration of Acquia CMS is designed to be significantly more flexible. Out of the box, you can choose between Enterprise (low-code), Community, and Headless versions. It has also moved away from being a distribution, which should make it much easier to customize and maintain over time.
In this tutorial, we’re going to demonstrate this flexibility by customizing a fresh install of Acquia CMS Headless to manage tutorials as a new content type. This will demonstrate the process of adding a new content type to a headless site, as well as accepting input in both Markdown and a standard WYSIWYG in one headless CMS.
-
Add and Install the Markdown and Editor.md modules
Be sure to also add a Markdown parser:
composer require drupal/editor_md:^4.0 league/commonmark:^1.0Next, enable the Markdown and Editor.md modules through the admin UI, or using drush:
drush en editor_mdDrupal 10.1 will provide the ability to specify which text formats are available to a text field. If your site's version of Drupal is older than that, install the Allowed Formats module to add this ability.
-
Create the Markdown text format
In the admin menu, go to Configuration > Content authoring > Text formats and editors and click "Add text format". Name the new format "Markdown".
Assign which roles should be able to use it, set Editor.md as the editor, and enable the Markdown filter. You can optionally change the Markdown parser in the filter settings at the bottom of the form, but we'll leave it to use the default.
-
Add a Skill Level vocabulary and terms
In the admin menu go to Structure > Taxonomy > Add vocabulary and give it a name like Skill Level, then Save. Once it's created, add some terms, such as Novice, Intermediate, and Expert
We've now created our Markdown content type and configured it to use Markdown for the content, with a couple of additional fields. Now we need to update our Next.js site to display any Tutorial content we create.
Updating our Next.js Front End
-
Create component template
We need to create a file in the components directory of our Next.js application that will define how the output for our tutorials will be structured. You can write a new file from scratch (using an existing on for reference) or you could clone an existing one an update it.
For example, you could clone node--place.tsx and rename the copy to node--tutorial.tsx. Then in your text editor you could do case-sensitive searches to replace "Place" with "Tutorial" and "place" with "tutorial".
Keep in mind that because of the fields we've configured for our Tutorials, our code will need to be somewhat different. For example, based on the configuration above we wouldn't need the MediaImage import at the top of the file, and we would need to output our duration and skill level in the NodeTutorial function (to display them when viewing the tutorial in full) and in the NodeTutorialTeaser function (to show them on the summary page).
-
Create a tutorials page
Now we need to provide a template to actually list all of our tutorials, in our Next.js app's pages directory. As above we could write a new file from scratch, or copy an existing one an update it to use our Tutorial content type and its fields.
The key for this file is to import all the files that will define necessary integration, as well as components that will be used to build out the page, including the teaser view for our tutorials that we defined in the previous step. Additionally this file needs to define functions that will specify how the data should be retrieved from the CMS, and then pass this data into our template to generate all the markup for the page.
-
Update the [..slug].tsx file
Finally we need to update the central [..slug].tsx that defines routes for the site and associates them with the relevant template files. In the import section at the top we need to import from NodeTutorial from the node--tutorial template we created in step 1. Next we need to include as one of the defined entity types. Within the EntityPage function declaration, we also need to specify that this NodeTutorial should be used when an incoming node has the appropriate type. Finally, in the getStaticProps function, since the field_skill_level field is a reference field we need to use a params.addInclude for the field to make sure we can use data from the referenced entity (in our case, the name) rather than just the id value stored in the reference field.
With those changes done, your team should now be able to start writing tutorials in Markdown, and have them displayed in your Next.js headless site. For syntax highlighting you could add a library like Prism.js to the front end app, or any other libraries that will enhance the formatting your team intends to use. Note that all of these formatting upgrades will be visible to content authors when they preview the content in the CMS, even when unpublished, because Acquia CMS uses the front end application to do a live render of the unpublished content.