Supercharge Your Bridgetown Site with Ruby Front Matter

jaredcwhite profile image Jared White Originally published at bridgetownrb.com ・4 min read

Starting in Bridgetown v0.13, you can now write real Ruby code directly in your Front Matter! 🤯 This feature is available for pages, posts, and other documents–as well as layouts for site-wide access to your Ruby return values.

Note: This requires the environment variable BRIDGETOWN_RUBY_IN_FRONT_MATTER to be set to "true" in your development and deployment setups. Otherwise the code will not be executed and will be treated as a raw string.

Now you may be wondering, how is this even possible? Front Matter is in YAML format, and the only place you can write actual code is in a custom plugin, right? RIGHT??

Well…it just so happens that there's this nifty bit of the YAML specification which allows for serialization and deserialization of objects. Normally that functionality is switched off in Bridgetown for security reasons. But we figured out a way to punch a hole through this security barrier to allow for a special type of string that represents Ruby code. It looks like this:

title: "I'm a page"
permalink: /ruby-demo
calculation: !ruby/string:Rb |
  [2 * 4, 5 + 2].min

Title: {{ page.title }}
Calc Result: {{ page.calculation }}

In this example, the value of the calculation variable is the return value of the Ruby code defined by the special string !ruby/string:Rb. The | symbol at the end just means all the indented code in the line(s) below are attached to that front matter variable.

The value printed out in the rendered page for the calculation will be 7 (since 7 is less than 8 and thus the minimum integer in the array).

In Ruby Front Matter you can return any kind of value that is accessible from a Liquid template. So strings, numbers, arrays, hashes, integers: they all work. Even objects can be returned if they are implemented as a Liquid drop.

You can also access other Front Matter variables from within the Ruby code itself.

title_fragment: Title of a Page
title: !ruby/string:Rb |
  "This is the #{data["title_fragment"].sub("Title", "Name")}"

Now the page title will read: This is the Name of a Page

Use Cases for Ruby Front Matter

One particularly compelling use case for Ruby Front Matter is to load data in from a third-party source for inclusion on a page (typically in JSON format, but it could be anything really). Here's an example of loading a file from a remote GitHub repository and parsing it to obtain useful information:

seo_tag_gem_version: !ruby/string:Rb |
  url = "https://raw.githubusercontent.com/bridgetownrb/bridgetown-seo-tag/master/lib/bridgetown-seo-tag/version.rb"
  result = Faraday.get(url).body
  result.match(/VERSION = "(.*?)"/)[1]

This will pull the current gem version of the master branch from bridgetown-seo-tag and output it via {{ page.seo_tag_gem_version }} (it's 3.0.4).

Another example is a feature we include on this very website's footer to show the average number of commits to the Bridgetown project on GitHub over the past month. (At the time this article was posted, that number is 110.)

Here's the Ruby Front Matter we include in _layouts/default.html:

github_participation: !ruby/string:Rb |
  endpoint = "https://api.github.com/repos/bridgetownrb/bridgetown/stats/participation"

  conn = Faraday.new(
    url: endpoint,
    headers: {"Accept" => "application/vnd.github.v3+json"}
    username, token = ENV["BRIDGETOWN_GITHUB_TOKEN"].split(":")
    conn.basic_auth(username, token)
  json = JSON.parse(conn.get.body)
<!doctype html>

Then in our footer (or anywhere on the site), we simply add {{ layout.github_participation }} to output that value.

Caveats and Takeaways

If you need to write a lot of Ruby code, or write code that is easily customizable or reusable in multiple contexts, we still recommended you write a Bridgetown plugin—either in the plugins folder in your site repo or as a separate Gem-based plugin.

But if you just need to add a little bit of dynamic functionality to a page or a layout and like being able to see the code and content combined into a single file, Ruby Front Matter is a powerful and immensely flexible solution.

And remember, this isn't a "lite" or stripped-down version of Ruby. This is 100% full Ruby. So you can process page or site data, instantiate objects, require gems, perform network requests, interact with the underlying filesystem, monkeypatch and metaprogram and do anything you'd ever need to do via Ruby.

Warning: For security reasons, please do not allow untrusted content into your repository to be executed in an unsafe environment (aka outside of a Docker container or similar). Just like with custom plugins, a malicious content contributor could potentially introduce harmful code into your site and thus any computer system used to build that site. Enable Ruby Front Matter only if you feel confident in your ability to control and monitor all on-going updates to repository files and data.

In summary, if you're excited to give Ruby Front Matter a try, all you have to do is install Bridgetown v0.13 or later, set BRIDGETOWN_RUBY_IN_FRONT_MATTER to "true" in your development environment, and go to town (Bridge…town 😋). And be sure to share your sweet solutions on Twitter with the hashtag #SpinUpBridgetown to let the community know what you've built with Ruby Front Matter!

(Also learn which internal Bridgetown objects are made available to your Ruby code in the documentation here.

Posted on by:

jaredcwhite profile

Jared White


Founder and lead developer at Whitefusion, a boutique web studio located in Portland, Oregon. On the core team of Bridgetown, a static site generator. Proud Rubyist!


markdown guide