Search code examples
rubyyamlmiddlemanstatic-pagesmiddleman-4

Middleman: choosing information from data files in frontmatter


I am using Middleman static page generator and I would like to pull information from data files based on selection made in frontmatter.

Example

I have data file located at data/cta.yaml with different variants of Call-To-Action text that can be repeated on various pages, meaning that each CTA text can be used on more than one page.

data/cta.yaml:

basic: This is default CTA
special: Something special here
other: Some other CTA

Then I have layout.erb:

<body>
<%= yield %>
<p class="cta">No data yet</p>
</body>

And test.html.erb:

---
title: Some page for testing
cta: It works with layout if I do not reference 'data/cta.yaml'
---

Some page content.

If I want to use, let's say, first CTA text, I could use <p class="cta"><%= data.cta.basic %></p> either in layout.erb layout file or remove it from layout and move it directly to the end of test.html.erb template file. Or, I could drop data file altogether and simply type CTA text for each page in frontmatter. However, I would prefer to keep CTA text in data file and all HTML in layout.erb and then be able to "choose" information from cta.yaml in test.html.erb frontmatter.

I tried to change

<p class="cta"><%= data.cta.basic %></p>

in layout.erb to

<p class="cta"><%= current_page.data.cta %></p>

and then in test.html.erb frontmatter:

---
title: Some page for testing
cta: data.cta.basic
---

but that resulted in verbatim data.cta.basic text instead of "This is default CTA" from cta.yaml data file.

Question

Is it possible at all to use frontmatter to select which text from data file should be used for given page?


Solution

  • As I mentioned in my comment, the frontmatter is parsed before the ERB, that’s the reason you are seeing data.cta.basic instead of the correct cta.

    You could add a helper to achieve this though.

    Here’s my helper

    module CtaHelpers
      def page_cta
        cta = current_page.data.cta
        data.cta.send(cta)
      end
    end
    

    Here’s my test.html.erb file:

    ---
    cta: special
    ---
    <p class="cta"><%= page_cta %></p>
    

    The test.html.erb file is calling the helper that determines from the Frontmatter which CTA to use, so the output is:

    Something special here