Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tune layout for a particular page/post in Jekyll?

Tags:

I would like to make some changes in Jekyll's layout. Changes are small and different. For example, linking an additional CSS or JavaScript file. Or adding some info in header. Or tuning page title. Important that these changes depend on a page/post.

Since changes are small and diverse, creating a special layout for each of them seems to be too expensive.

I tried to create my own solution but run into impossibility to use variables in including instructions.

Has anyone solved something similar? For example, linking a special CSS to a particular post?

like image 856
Varvara Stepanova Avatar asked Jan 01 '13 19:01

Varvara Stepanova


People also ask

What is front matter in Jekyll?

Front matter tells Jekyll to parse a file. You add predefined variables, which are YAML sets, to the front matter. Then, you can use Liquid tags in your files to access the front matter. Front matter is indicated with two triple-dashed lines.


1 Answers

You can use YAML front matter to tune anything you want for any post/page. Any info you provide there would be accessible through in layouts and includes under page variable or under specific post in any list of them.

This sounds like a solution for your case: you could use YAML front matter like this:

--- extra_css:   - foo.css   - dir/bar.css   - /s/baz.css --- 

And then use this in your layout's header like this:

{% for css_name in page.extra_css %}     <link rel="stylesheet" href="{{ css_name }}"> {% endfor %} 

In such way you could add any logic based on what data you provide with a post in YAML front matter.

If you'd like to abstract some of those logic to modules, you can use a hack around the includes, assigning a variable before that include and then using it inside. Here is a link with a description how it's made in Jekyll Bootstrap project (btw, the site for it have a lot of nice info on Jekyll).

And, yes, Jekyll don't allow the use of variables in includes, so if you'd like to include something conditionally, you would need a list of all available includes somewhere and then create all the conditions for inserting one or another when you'll need them.


Another solution is to divide everything in layout to includes, and make layouts with different levels of complexity — this way you could set any of those basic layouts for post and then write any extra code with includes of any blocks you'll need from the basic layouts, so you post could look like this:

--- layout: custom --- <aside class="sidebar">     {% include comments.html %}     {% include sidebar.html %} </aside> <div class="content" role="main">     Foo bar baz </div> 

There you could use a custom layout that don't include a basic layout for page and don't include the sidebar and comments, so you could per-post decide what level of layout you want and then redefine anything that needed to be redefined.

Also, if you'll need to tweak different places but with an unknown content, you could use YAML front matter with blocks, like

extra_head: |     <style>     * {background: red}     </style> 

then you could call such variable from head: {{ page.extra_head }} and get any content you placed there. However, you can't use any liquid tags inside YAML, but you could then use any YAML tags on such variables, so you could markdownify them or replace any strings inside with anything else by simple replace filter.

And if nothing of those fit you, then Jekyll won't fit you — as I wrote in a comment, Jekyll is just a blog engine and you shouldn't wait it to be complex as XSLT.

like image 53
kizu Avatar answered Sep 27 '22 22:09

kizu