Markdown to formatted FAQ?

I have been asked to add a FAQS to several pages, but also make it so the sections are collapsable. Although I could hard code this in HTML, I would rather avoid doing this and instead have it specified in a Markdown document and then have it transformed.

What I had considered doing is adding a content section “content/faq” and then adding the individual FAQs as markdown formatted docs in that page. Then the markdown could be included and processed as appropriate.

An example markdown I had considered:

### This is a question

This is an answer,

  - list A
  - list B

### This is another question

This is another answer

With the output being something along the lines:

<div class="faq-entry">
  <div class="faq-entry-question">This is another question</div>
  <div class="faq-entry-answer">This is another answer</div>
</div>

Could this approach work, and if so how could I include and transform it? If not, what other suggestions are there?

Using markdown, the best approach I can think right now is to use a definition list:

Question
: Answer

Question
: Answer

Question
: Answer

It would be rendered as:

<dl>
<dt>Question</dt>
<dd>Answer</dd>
<dt>Question</dt>
<dd>Answer</dd>
<dt>Question</dt>
<dd>Answer</dd>
</dl>

Throw some style on it and it should work.

Or, if you’re a masochist like myself, you can use definition lists AND replaceRE in your content:

{{ $replaceDL := printf "%s${1}%s" "<div class=\"faq-entry\">" "</div>" }}
{{ $replaceDT := printf "%s${1}%s" "<div class=\"faq-entry-question\">" "</div>" }}
{{ $replaceDD := printf "%s${1}%s" "<div class=\"faq-entry-answer\">" "</div>" }}

{{ .Content | replaceRE "(?:(?:<dl>)((?:.|\n)+?))(?:</dl>)" $replaceDL | replaceRE "(?:(?:<dt>)((?:.|\n)+?))(?:</dt>)" $replaceDT | replaceRE "(?:(?:<dd>)((?:.|\n)+?))(?:</dd>)" $replaceDD | safeHTML }}

And you should get:

<div class="faq-entry">
<div class="faq-entry-question">Question</div>
<div class="faq-entry-answer">Answer</div>
<div class="faq-entry-question">Question</div>
<div class="faq-entry-answer">Answer</div>
<div class="faq-entry-question">Question</div>
<div class="faq-entry-answer">Answer</div>
</div>

The one issue I have here is that I am not sure how add list items and paragraphs to items in definition section. In the mean time I’ll play around with what you shared.

Question
: Answer

  Paragraph
  - list A
  - list B

Question
: Answer

I’m no markdown expert. Maybe someone else can guide you further.

3 Likes

heyhey, not sure if that helps you, but this is how I added FAQs to one of my sites:

I created a shortcode. Obviously.

In the page.md I add:

{{< faq title="What accomodation is available?" >}}
... answer ...
{{< / faq >}}

{{< faq title="What size are the groups on this tour?" >}}
... answer ...
{{< / faq >}}

In layouts/shortcodes/faq.html:

<div class="mb-4 faq">
<h3>{{ with .Get "title" }}{{ . }}{{ end }}</h3>
<div class="faq-answer">
{{ .Inner | markdownify }}
</div>
</div>

You can use Javascript for any kind of collapsible script using the .faq-answer class.

Now, having done that, you could add structured data to your shortcode to excel in the SEO department. Something I am planning for a while but not having time to :wink:

2 Likes

Is the FAQ a standalone page?

If yes, you can define a custom content/page type, pick two tags to sacrifice, and bend them beyond recognition in custom CSS to your needs. If you need to wrap each Q/A pair in a block element, you can use > for that (translates into <blockquote>).

That’s ugly, but allows to avoid shortcodes in Markdown.

Conceptually, a FAQ is just another type of content:

content/
└── faq
    ├── how-to-bake-a-cake.md
    ├── how-to-ride-a-bike.md
    └── why-is-the-sky-blue.md

This approach allows you to tag and categorize (taxonomies), provide metadata (front matter), display a subset (using where), control the order in which they are displayed, make a few of them “sticky” at the top of lists, etc.

If you only have a handful of FAQs on the site, this approach is probably overkill, but it is largely future proof due to its extensibility.

2 Likes

I would make it a bit more elaborate instead, as it is a perfect case for page bundle resources. Just add index.md and loop through page resources. Or add _index.md, and make it a section. That’s what it is usually called, the FAQ section.

If a single FAQ page doesn’t have to sit in a single file, of course.