Liquid - Conditionally Include File From _includes Folder - jekyll

I have a default.html file in _layout folder. This file contains elements that are common throughout the entire site (e.g., the <head> element), and is supposed to be called in other layout files, which will further extend it.
Depending on the file that calls default.html, I want to include the appropriate snippets in the <head> element.
For instance, consider the (simplified) example files bellow:
_includes/post_metadata.html:
<link rel="stylesheet" href="post.css">
_layouts/default.html
<html>
<head>
{% if <is_post_layout> %}
{% include post_metadata.html %}
{% endif %}
</head>
<body>
{{ content }}
</body>
</html>
_layouts/post_layout.html
---
layout: default
---
<article>
{{ content }}
</article>
_posts/2021-09-22-post.md:
---
layout: post_layout
---
[...]
The final page generated by Jekyll should contain:
<html>
<head>
<link rel="stylesheet" href="post.css">
</head>
<body>
<article>
[...]
</article>
</body>
</html>
So, what code should I use to replace <is_post_layout> to make it work?

There are two (and even more) options.
One is similar to the comment of #Brad West.
You can create many layouts, see docs. So create a post.html (e.g. based on default.html) layout and place it inside _layouts folder. Then you can use the layout in the front matter block. For layouts from scratch can use none for an empty layout.
Use a default layout
---
layout: default
---
Use a post layout
---
layout: post
---
The _layouts/default.html
<html>
<body>
{{ content }}
</body>
</html>
The _layouts/post.html
---
layout: none
---
<html>
<head>
{% include post_metadata.html %}
</head>
<body>
{{ content }}
</body>
</html>
The other one is do it with a variable include_post_metadata in the front matter block. Set the variable to true, when it will be omit then it is false / nil, and the if condition will be not excuted.
---
layout: default
include_post_metadata: true
---
The _layouts/default.html
<html>
<head>
{% if page.include_post_metadata %}
{% include post_metadata.html %}
{% endif %}
</head>
<body>
{{ content }}
</body>
</html>
Page (page.include_post_metadata) is valid for pages and posts

Related

Generate standalone Jekyll page with variables

I'm trying to generate an additional Jekyll page called posts.html.
I'm looking to use the Jekyll variables such as site.posts to iterate through the posts I've written for my site, and create a standalone page (posts.html) using these variables.
Here's my current version:
<!DOCTYPE html>
<html lang="en">
<body>
<main>
{% for post in site.posts %}
{{post.title}};{{post.date}},
{%endfor%}
</main>
</body>
</html>
If I include this at the root of my site, the command bundle exec jekyll build will build posts.html to my _site directory, but does not compile the variables into readable text. It outputs it in plaintext.
I've attempted to hook into the existing build cycle by moving the posts.html file to the _includes directory, and referencing it at the bottom of blog.html.
This does generate the HTML, but as part of the index.html like so:
... Additional markup here
</main>
<section id="category-modal-bg"></section>
<section id="category-modal">
<h1 id="category-modal-title"></h1>
<section id="category-modal-content"></section>
</section>
<!DOCTYPE html>
<html lang="en">
<body>
<main>
MyPostName;MyPostDate,
</main>
</body>
</html>
This makes sense as the layouts/posts.html file is an include, so building the markup where the include exists is working as expected.
I'm trying to compile the posts.html file as a standalone, navigatable file that will sit alongside my _site/index.html. If I need to copy this file across as part of my CI/CD pipeline thats fine too.
Is this possible?
Add an empty front matter before posts.html to let Jekyll process your file. (and move back posts.html)
---
---
<!DOCTYPE html>
<html lang="en">
<body>
<main>
{% for post in site.posts %}
{{post.title}};{{post.date}},
{% endfor %}
</main>
</body>
</html>
Any files with front matter are subject to processing. For each of these files, Jekyll makes a variety of data available via Liquid. (Variables | Jekyll Doc)
You must include front matter on the page for Jekyll to process any Liquid tags on it. (Front Matter | Jekyll Doc)
However in most cases, this is better.
---
layout: default
---
{% for post in site.posts %}
{{post.title}};{{post.date}},
{% endfor %}
By using a layout, you don't have to write <head> or <footer> again and again and again. Layouts also makes it easier to change <head>, etc. (let's say, you want to add Google Analytics someday.)
Besides, I think this may help you, though irrelevant to the question's title.
---
layout: default
---
<ol>
{% for p in site.posts %}
<li>{{ p.title }} — {{ p.date }}</li>
{% endfor %}
</ol>
Comprehensive version: Pagination | Jekyll doc

html doc not using external css style sheet

I am starting to learn CSS and after trying to implement an external stylesheet, i found I was unable to change the color of my html document. I am using Visual Studio Code and my html templates are using Djangos inheritance.
I have tried double checking that everything is saved, I have checked spelling for the href, and i even restarted VSC. So far nothing.
Here is the base html sheet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{% block style %}
{% endblock %}
<title>
{% block title %}
{% endblock %}
</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
Here is an html sheet that should use the styling:
{% extends 'student_view_base.html' %}
{% block title %}
Socrates Home Page
{% endblock %}
{% block style %}
<link rel="stylesheet" type="text/css"
href="css/sidebar.css">
{% endblock %}
{% block content %}
<h1>Socrates Home Page</h1>
<div>
Login
</div>
Admin Login
{% endblock %}
Here is the css sheet:
h1{
color: blue;
}
As you can tell, I am pretty new to Web Dev in general and this was mostly to experiment and make sure I could implement it properly.
As far as I can tell the h1 tags text should be turning blue. Currently it remains black.
EDIT: I can confirm that the href is linked to the proper document, ctrl clicking takes me to the right document.
You are better off placing your html code on templates and your css on static when you use django. Create a templates and static folders on your project as here. enter image description here
Then edit settings.py'DIRS': [os.path.join(BASE_DIR, 'templates')], inside TEMPLATES. Also add the following code to your settings.py :
STATIC_URL = '/static/'
STATIC_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
You should be good to go.

Jekyll: Page not parsing custom variable from layout

I've just begun learning Jekyll and I've run into a little speedbump.
I have 2 layouts in my _layout folder which essentially look like this:-
default.html
<html>
<head> <!-- Meta Tags etc --> </head>
<body>
{{ content }}
</body>
</html>
hero.html
---
layout: default
---
<section id="hero">
<h3>{{ hero.descr }}</h3>
</section>
{{ content }}
My index page extends the hero layout as follows:-
index.html
---
layout: hero
descr: Hello there.
---
The layouts work just fine, and the website appears as it should, except for the hero.descr variable. The heading tag is just empty.
The flow of data is uni-directional.
default.html => hero.html => index.html
hero.html will not know what's defined in index.html
But, the rendering is in the opposite direction (inserted into the {{ content }} variable of the parent.
index.html ==> hero.html ==> default.html
It seems to me that the variable {{ hero.descr }} does not exist. I think that it should be {{ page.descr }}.

Jekyll - Change menu when on posts pages

I'm using Jekyll to build a static website and the front page scrolls to anchor points up and down the page but if the user go off to a post then the menu obviously doesn't go anywhere due the links being like:
<li class="nav-link"><a data-scroll-goto="4" href="#contact">Contact</a></li>
In Jekyll is there a way say in the cofig file to say if post page then replace menu-A with menu-B?
Thanks,
That's what layouts are made for.
Your /index.html page will use the home.html template
Your posts will use the post.html then the default.html template
index.html
---
layout: home
...
---
your content here
_layouts/home.html
<!DOCTYPE html>
<html>
{% include head.html %}
<body>
{% include menu-a.html %} <----------LOADING Menu a
<div class="page-content">
<div class="wrapper">
{{ content }}
</div>
</div>
{% include footer.html %}
</body>
</html>
_layouts/default.html
<!DOCTYPE html>
<html>
{% include head.html %}
<body>
{% include menu-b.html %} <----------LOADING Menu b
<div class="page-content">
<div class="wrapper">
{{ content }}
</div>
</div>
{% include footer.html %}
</body>
</html>

Detect if a file is included in Jekyll

In my posts, I sometimes include the same HTML pattern.
To do it so, I created pattern.html in _includes/ and include it in my posts with :
{% include pattern.html %}
I would like to add a CSS file (or any other code) in my header if, and only if, pattern.html as been used in my post. To put it in pseudo-code, I would like to get the following layouts/default.html:
<!doctype html>
<html>
<head>
{% if pattern.html is included in the post %} code here {% endif %}
</head>
<body>
{{ content }}
</body>
</html>
I already tried to assign a variable in pattern.html and to test it in my layout, but this assignement occurs too late: the layout is already processed. I know I can pass a variable through YALM, but my objective is to get rid of it. I would prefer not to use plugins to do this.
It seems asking the question helped me to answer it!
You can use the Liquid contains in order to look for a pattern in your post.
For example, if the included pattern.html contains a particular piece of code (<!--pattern--> for instance, or any particular HTML), you can use in your head:
<!doctype html>
<html>
<head>
{% if content contains "<!--pattern-->" %} code here {% endif %}
</head>
<body>
{{ content }}
</body>
</html>
This can be used for any HTML pattern. For example, if you want to call the CSS file producing syntaxic coloration only if there is code in the page, use:
<!doctype html>
<html>
<head>
{% if content contains "<code>" %}
<link rel="stylesheet" href="code.css">
{% endif %}
</head>
<body>
{{ content }}
</body>
</html>