javascriptnunjuckseleventyjamstack

Front Matter Data in Layouts is not working Eleventy


I'm having troubles using front matter in my layouts. It simply displays out the front matter to the page without creating the data needed for my layout.

Here goes the code:

/src/_includes/layouts/base.html

---
rightLinks : [
        {
            "icon": "mail_outline",
            "href": "https://google.com"
        }
    ]
---
<!DOCTYPE html>
<html lang="es-AR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{ title }}</title>
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
  <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,300;0,400;0,600;0,700;0,900;1,300;1,400;1,600;1,700;1,900&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="/css/global.css">
</head>
<body>
  <!-- top-nav try to use rightLinks data from this layout -->
  {% include "partials/top-nav.html" %}
  {% include "partials/main-nav.html" %}
  <main tabindex="-1" id="main-content">{% block content %}{% endblock %}</main>
</body>
</html>

/src/_includes/layouts/home.html

{% extends "layouts/base.html" %} 
{% block content %}

<section class="hero is-black is-fullheight-with-navbar hero-home">
  <div class="hero-body">
    <div class="container">
      <div>
        <h1 class="title text-black text-huge">
          Nexus Materiales Eléctricos
        </h1>
        <h2 class="subtitle is-4">
          Somos mayoristas en insúmos eléctricos de calidad.
        </h2>
      </div>
      <div class="mt-6">
        <a href="/marcas" class="button is-rounded is-large is-dark is-uppercase text-semi-black">
          ver marcas
        </a>
      </div>
    </div>
  </div>
</section>

<section class="section has-background-white">
  <h2 class="title">Nuestras marcas destacadas</h2>
  <h3 class="subtitle">Calidad y seguridad</h3>
</section>

{% endblock %}

/src/index.md

---
title: 'Hello World!'
layout: 'layouts/home'
---

I get as a visual result the actual string at the top: enter image description here

It seems to me that Eleventy, for some reason, is skipping the front matter.

Here is my Eleventy configuration file:

module.exports = function(config) {
    config.addWatchTarget("./src/sass/");
    config.addPassthroughCopy('./src/images')

    // Return your Object options:
    return {
        dir: {
            input: "src",
            output: "dist"
        },
        markdownTemplateEngine: 'njk',
        dataTemplateEngine: 'njk',
        htmlTemplateEngine: 'njk',
    }
  };

Someone can explain to me why is this happening, and how can I solve this? Thanks


Solution

  • Front-matter data is only available in layout files that are directly referenced by pages with the layout: front matter key, not with Nunjucks {% extends %}. Front matter data in directly referenced layout files are merged with other data as part of 11ty's data cascade. (11ty docs: front matter in layouts)

    For example:

    <!-- index.md -->
    ---
    layout: layouts/content
    ---
    # some content here
    
    {# layouts/base.njk #}
    ---
    hello: "world"
    ---
    {# ^ the above will be printed as plain text and isn't available #}
    
    {# layouts/content.njk #}
    ---
    someKey: "something"
    ---
    {% extends "layouts/base.njk" %}
    
    {{ someKey }}
    {# ^ this will render "something" as expected #}
    

    This is likely because {% extends %} is a feature of Nunjucks, and Eleventy is not aware of which other Nunjucks files are being referenced.

    For your situation, you have a couple of options. First, you could place your front matter data in layouts/home, since that's what you're referencing in your index.md. Another option is to just use Nunjuck's set tag.

    {% set links = [
        {
            "icon": "mail_outline",
            "href": "https://google.com"
        }
    ] %}
    
    {% for link in links %}
        {{ link.icon }}
        {{ link.href }}
    {% endfor %}