YAML inheritance


#1

Hi all,

I was not able to find any information online and I hope someone could share their knowledge.

Is it possible that posts can inherit YAML from the parent? For example, we have this following tree

en
├── _folder.yml
├── begin
│   ├── _folder.yml
│   ├── onepage.html
│   └── _posts
│       ├── 2000-04-12-exercise-6-sketch.md
│       ├── 2000-04-13-exercise-7.md
│       └── 2000-04-14-exercise-7-sketch.md
└── setup
    └── _posts
        └── 2017-10-23-article.md

When

en/_folder.yml

has a setting

---
myconfig: "Hello this is my config"
---

is it possible that

en/begin/_post/*.md

will also inherit myconfig ?

If there is another myconfig in

en/begin/_folder.yml

myconfig will use the value from `en/begin/_folder.yml

and if en/begin/_post/*.md has their own myconfig will use their own?

Thanks and appreciate if anyone could share some light. The use case is group configuration.

Cheers
JP


#2

Front Matter within a page or a post is strictly local to that page or post
To configure a group of documents with a single declaration, define them in the _config.yml. Jekyll understands such declarations as Front Matter Defaults


#3

Thanks @ashmaroli. Appreciate your reply.

Yes, this can be done with _config.yml or _data folder.

But when using these two methods, if we have multi-level sub-folder, in the _config.yml we also need to define them multi-level and reading multi-level YAML variable in liquid is really hard as they need to be hardcoded. This makes maintaining the code really hard.


#4

someone also asked about this question here

but no answer.


#5

I don’t see why you need to define them multi-level… could you illustrate with an example?


#6

I like the beautiful part of how Jekyll take care of categories using folders, and be able to do it muti-level. Lets take this as an example, assuming we have 1000 files in book/nonfiction/science/biology/_posts in the following order:

book
└── nonfiction
    ├── maths
    │   ├── stats
    │   │   └── _posts
    │   └── trig
    │       └── _posts
    └── science
        └── biology
            └── _posts
                ├── 2000-01-01-test.md
                ├── 2000-01-02-test2.md
                ├── 2000-01-03-test3.md
                ├── 2000-01-04-test4.md
                └── 2000-01-05-test5.md

In each of the post in book/nonfiction/sciense/biology/_posts it can access this variable

{{ post.categories | split: ',' }}

and returns

[“book” “nonfiction” “science” “biology”]

This means if we decided to move 200 books in book/nonfiction/sciense/biology/_posts to book/nonfiction/sciense/biology/ecology/_posts we can just move them there and

{{ post.categories | split: ',' }}

will magically returns

[“book” “nonfiction” “science” “biology” “ecology”]

We don’t need to edit 200 files and add ecology category to their front matter. post.categories will automatically inherit the categories along the folders. This is the truely beautiful part of Jekyll categories.

Now lets look at how front matter inheritance can add synergy to the folder based categories feature in Jekyll.

Currently, each post will need to have their own front matter, for example:

---
layout: book
article-type: rectangle
----
{% if page.article-type %}
* this article is type {{ page.article-type }}
{% endif %}

All 1000 files will have the above front matter.

Scenario 1 - Change the article-type to circle for all

We will need to edit all 1000 files to change rectangle to circle

Solution 1 - Use _data (_config.yml should be similar to this)

book.yml

nonfiction:
  science:
    biology:
      article-type: circle
    chemistry:
      article-type: quad
  maths:
    stats:
      article-type: triangle
    trig:
      article-type: sphere

In the 1000 posts we have this, looks simpler when using _data

---
layout: default
---
{% if site.data.book.nonfiction.science.biology.article-type %}
* this article is type {{ site.data.book.nonfiction.science.biology.article-type }}
{% endif %}

Now this is perfect if the posts stays the same. Lets say due to “temporary” business decision, we want all nonfiction posts to be article-type: temptype to reflect a temporary promotion or temporary status.

We either need to go through all the 1000 files and add article-type: temptype into the them or we edit each individual posts to change the hard-coded site.data.book.nonfiction.science.biology.article-type liquid code to site.data.book.nonfiction.article-type instead. Which ever way it is, it is tedious.

Proposed Solution using folder based YAML inheritance

In the 1000 posts we have this

---
---
{% if page.article-type %}
* this article is type {{ page.article-type }}
{% endif %}

Note that there is no article-type and no layout: default in the post.

Logic 1

In folder book/nonfiction/ we add a YML file, lets just call it _folder.yml

Inside the _folder.yml we have this

---
layout: default
article-type: temptype
---

If there is YML inheritance, any posts down the folder `book/nonfiction’ will inherit these two variables. Therefore, by just adding or editing 1 file, we can change the behavior of 1000 files down folder branches.

Now, lets say, there is this particular post 2000-01-05-test5.md that is not affected by the temporary business decision, and it need to have its own article-type, we just need to edit this file to have

---
article-type: individual-type
---

of its own.

Therefore, 999 files inherited the variables of _folder.yml from their parent, and ` file has its own variable.

Now, lets say, there is another change that only affects book/nonfiction/science , we just need to add _folder.yml inside that folder and all files down the folder branch will inherit the variables in book/nonfiction/science/_folder.yml and over-ride the parent’s variables. This change also does not affect other folders like book/nonfiction/maths that has the inheritance from book/nonfiction/_folder.yml

And the most beautiful part is in the 1000 posts, we just need to have this

---
---
{% if page.article-type %}
* this article is type {{ page.article-type }}
{% endif %}

They all use the same variable name page.article-type, and the liquid code is not affected by any changes done. We can move the posts anywhere, any folder and still the rules follows the parent’s _folder.yml.

I think the proposed solution can be achieved by plugins, but ideally if it is inside the core of Jekyll, it will help lots of uses hosting on github.

Sorry for such a long-winded reply, this is just a suggestion and I do believe it will make Jekyll more beautiful and powerful.

Cheers


#7

I think the quickest way to do this is to collect _folder.yml along the folder branches and merge them temporary to the post. For example

book/nonfiction/_folder.yml

---
layout: default
article-type: temptype
---

book/nonfiction/science/_folder.yml

---
layout: default
article-type: science-temptype
---

In the individual post, we combine the _folder.yml collected along the folder branches, we have this

---
layout: default
article-type: temptype
layout: default
article-type: science-temptype
---

YAML processor will take the last

layout: default
article-type: science-temptype

as the variables.

For the case of post 2000-01-05-test5.md after collecting all the ymls, we have

---
layout: default
article-type: temptype
layout: default
article-type: science-temptype
article-type: individual-type
---

and YML processor will take

layout: default
article-type: individual-type

as the variables.

Cheers