1

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?

Rafal
  • 864
  • 10
  • 21
  • What you are describing is the expected behaviour since the frontmatter is parsed before the ERB. Am I right in thinking you sometimes want to set a manual CTA in the frontmatter of `test.html.erb` and sometimes want to reference a CTA held in `data/cta.yml` from the frontmatter of `test.html.erb`? – Andy Stabler Apr 19 '17 at 19:40
  • Not exactly: for most pages (ones using specific layout, which includes paragraph with 'cta' class) I want to be able to reference CTA held in ``data/cta.yaml`` from frontmatter of ``test.html.erb``. Whole point is to edit CTAs in one place (``data/cta.yaml``) without need to edit it manually on each page that uses that text (should text change in the future). "Manual CTA text" was there to show that it works when entered manually ;) – Rafal Apr 20 '17 at 07:29

1 Answers1

1

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

Andy Stabler
  • 1,309
  • 1
  • 15
  • 19
  • 1
    Works perfectly! I used ``<%= page_cta %>`` in my layout (as intended originally, but it works also in page templates as shown in the answer) and put helper in my ``config.rb`` (instead of saving it as separate module. – Rafal May 01 '17 at 09:11