From Hugo in Action by Atishay Jain
In this article we show how the data driven nature of Hugo coupled with the dynamic form providers of the Jamstack make a powerful combination.
Take 40% off Hugo in Action by entering fccjain into the discount code box at checkout at manning.com.
In this article, we will see how the data-driven nature of Hugo coupled with the dynamic form providers of the Jamstack makes a potent combination.
A survey usually consists of a dynamic number of questions with multiple answers or a plain text field to fill the answers. YAML is the perfect language for creating a survey form. It keeps data together and moves the presentation logic to the template. A proper survey should have content and presentation wholly separated. The content consists of questions and answers which should be present in the markup document, while the layout and conversion to the final HTML form should form the layout.
The questions in the survey content file are present as a plain list in YAML, with options provided as an answer where available. (https://github.com/hugoinaction/hugoinaction/ tree/chapter-09-resources/03):
Listing 1. The content file for a survey form. Hugo generates the survey dynamically based on the supplied data. Questions with answers turn into dropdowns, while the ones without them are present as text boxes. (content/survey/random.md)
--- title: Random questions from Hugo In Action survey: - question: Do you like websites that are slow to load? answer: [Yes, No] - question: Rate your confidence using Hugo to build fast websites. answer: [1 (Very Low),2,3,4,5 (Very High)] - question: What is the answer to life, the universe, and everything? - question: Any further comments. ---
We will create a form by looping through the list of questions and then creating a dropdown if the answer field is present and text boxes if not. We could alternatively add a key called
type to define the form element we want to use for it.
Since there will be multiple surveys on the website, the natural place to put one is its custom section with a new content type. We will be defining a new content type called survey and placing a
single.html template inside it. In this template, we will loop through the questions provided in the front matter’s survey section and create a dropdown (HTML select element) when there are answers available else, resort to a text box (HTML input element).
Listing 2. Survey form used to create a survey. This code parses the front matter’s survey parameters and runs through a loop creating form entries. (AcmeTheme/layouts/survey/single.html)
❶ Class for CSS styling
❷ Provide markdown content and title from header.
❸ Loop through the survey section in the front matter.
❹ Create the HTML
<select> tag if the question has options for answers.
❺ Do not select anything by default.
❻ Else create the
<input> tag for a text box.
With this small template, we can generate as many surveys as we want by placing Markdown documents in the survey folder within the content folder for our website. Note that if we are using formspree, we will need to create a new form id for each survey form and provide its code.
The survey for
random.md should be present at http://localhost:1313/survey/random/.
Figure 1. Dynamic surveys created via Hugo. Combining a backend form service with Hugo, we can get dynamically generated forms that provide a considerable amount of flexibility, including creating forms like surveys based on dynamic markdown content created by a content author.
NOTE The ability to create dynamic forms within a website is a compelling feature. A content author can create surveys using plain Markdown and YAML. The form contents are very dynamic, and we can change them after publishing the form without involving a single change to the theme code.
To use Formspree, we will need to add the Formspree id to the front matter.
Listing 3. Providing the formspree id for each form (content/survey/random.md)
form: <Formspree id>
Marking surveys as unlisted
Note that with this change, the survey pages can now start showing up in the list of pages if we navigate through
site.Pages . Survey pages are mainly unlisted. To make the survey pages unlisted, we can specify the build parameters to Hugo to set the list setting to false in the build settings for the survey section.
Listing 4. Disable index listing for survey (content/survey/_index.md)
--- title Surveys cascade: _build: list: false --- Please use the survey link provided in the email to access the survey.
Don’t include any page in the list page (via cascade).
The survey pages will have URLs with this change, but they will not show up in the page lists like
Note that unless the survey section is disabled in robots.txt, search engines will index the survey links. Also, if we want to have random URLs for surveys, we can use the
slug key in the front matter to define our custom URLs.
Code Checkpoint. Live at https://chapter-09-06.hugoinaction.com. Source code at https://github.com/hugoinaction/hugoinaction/tree/chapter-09-06
Figure 2. No contest – Bob discovers the joys of the Jamstack. He moves over the survey component to this new approach and likes it so much that he declares to the management that they should move to the new stack.
That’s all for this article. If you want to learn more, check out the book on Manning’s liveBook here.