Jekyll: including a post inside another post - include

Does Jekyll provide a way to include a post inside another post? I know that sounds a bit goofy, but I'm using it for a cooking/recipe site. Some of my recipes are made up of components, or other, smaller recipes.
I'm looking for a way to include a handful of posts inside another post, complete with template and all. Is this possible?
I did a ton of googling, and found I was only able to include into a page, not post, and it didn't use the default liquid template, just plain markdown.
Ideas?

I used Jekyll's Collections in my website to solve a problem similar to yours.
Collections are still an experimental feature in Jekyll, and the solution I used is pretty hacky by itself, but if you don't go too crazy with it it's manageable enough.
For a more detailed and friendly intro to collections, here's a great post about getting started with them.
One thing we need to have in mind is that we should get away from posts for cases like this.
As mentioned by Ben Balter in the link above, “If people are using blog posts for a non-blog post thing, Jekyll has already failed”. Recipes are not posts, and we should avoid using them as such if we can.
With that said, here's my approach in three steps:
Create two collections (our custom post types) — let's say these are “Recipes” and “Ingredients”
Find a way to relate them to each other — To make sure “lettuce” will be listed under “salad”
Include the relevant “Ingredients” in your “Recipes” — Adding the liquid code to actually display information from “lettuce” somewhere in the “salad” page.
Step 1
Create _ingredients and _recipes folders for each of your collections (make sure to name them in plural) and add them to your _config.yml file:
collections:
ingredients:
output: true
recipes:
output: true
permalink: /recipes/:path/
The output: true parameter creates an individual HTML page for each item in the collection and permalink (optional) lets you control the URL.
Step 2
Add a piece of metadata like this to the YAML front-matter of your lettuce.md collection item:
---
parent-collection: salad
---
If lettuce.md belongs to more than one recipe, you can add more than one. Make sure to add content below the metadata if you need a description:
---
parent-collection:
- salad
- hamburguer
- taco
---
Lettuce is really good for your health, but it kinda sucks as a food.
Note that salad, hamburguer and taco should named exactly like the recipe URL slug or this won't work (i.e. greatrecipes.com/recipes/salad). If you have a recipe name that's a sentence, you wrap it in quotes.
This variable will be slugified later on, so a name like parent-collection: The Amazing Souflè Français will match the-amazing-soufle-francais. Still, weird stuff happens: when in doubt, just write smallcaps salad.
This is the hacky part.
Step 3
Create a specific layout for your recipes (like _layout/recipe-page.html) and add the code below — this is where we'll include the ingredients into the recipe page.
Remember your recipes (salad.md and friends) should be pointing to this layout.
{% capture current_collection %}{{ page.url | remove: "recipes" | remove: "/" | remove: " " }}{% endcapture %}
Here we capture the name of the recipe from the URL and assign it to the current_collection variable. Make sure this in a single line because making it multi-line will add a bunch of whitespace to the captured string and break your code 10/10 times. Insane.
<div class="recipe-content">
<p>{{ content }}</p> -- This is the content of the current recipe in the collection, your "post text".
</div>
{% for ingredient in site.ingredients %}
{% capture captured_parent_collection %}{{ ingredient.parent-collection | slugify }}{% endcapture %} -- This capture is just to pass the slugify filter and sanitize parent.collection to make sure it matches the URL slug
{% if captured_parent_collection == current_collection %}
<div class="recipe-ingredient">
<h3>{{ ingredient.name }}</h3> -- "<h3>Lettuce</h3>"
<p>{{ ingredient.content }}</p> -- "<p>Lettuce is really good for your health, but it kinda sucks as a food.</p>"
</div>
{% endif %}
{% endfor %}
Match the ingredients for this recipe and includes each one of them into the layout. YASS!
Each of your ingredients should be appearing right under your recipe text.
Note that you're not pulling the ingredients inside the recipe text like you described in your question, but including them in the layout after it. As far as I know you can't really add things in the middle of your post/collection text — unless you hack your way through a custom plugin for Jekyll.
There are certainly less hacky ways to do this, but this is how I made it work. Let me know if you find any trouble trying this for yourself — and anyone else, feel free to correct me.
I have this setup going on in my site — take a look at the layout where I pull in my child collection items and the metadata on the child collection items themselves.

I stumbled upon this question while looking for a way to do this, and here's what I ended up doing. I figured I'd post it in case somebody else is looking for a way to do this as a one-off and doesn't feel like creating a whole collection.
In the post where you want to include your other post, you can use Jekyll's where filter to get a reference to your other post, and then print that post's content:
---
layout: whatever
---
Your original post's content here.
{% assign myOtherPost = site.posts | where:"url", "/other/post/url" | first %}
{{ myOtherPost.content }}
Some more content here.

Related

Unable to print liquid variable values in Shopify

I want to print the weight of variants in lbs and the quantity of variants of the products in the products page in Shopify. Here are the few things I am trying
This is the code inside js file:
Able to print the weight in grams:
$('#variant-weight').text(variant_weight);
But I want to print in lbs something like this
$('#variant-weight').text({{ variant.weight | weight_with_unit: variant.weight_unit }});
For the above code I am not getting any output.
Also I want to print the quantity which is left, but not able to get the desired output. Here is the code:
$('.variant-sku').text(variant.inventory_quantity);
You are miss matching JS and LIQUID wrongly.
Yes you can add liquid in JS files if the files have an extension of .js.liquid but in your case this is not doing you any good since you don't have direct access to the variant object.
Instead of using {{ variant.weight | weight_with_unit: variant.weight_unit }} in the JS, add this in the liquid files.
For example (assuming that you):
<div id="variant-weight" data-weight="{{ variant.weight | weight_with_unit: variant.weight_unit }}"></div>
And in the JS you can get data value if you need it.
PS:
Please note that once again you don't have direct access to the variant object. You must be in the product.variants loop or get something like product.first_available_variant.weight instead. And if you are in the variants loop please don't use an ID but a class instead.

Hugo (go static site generator) list for specific URLs

let's say I have the following structure
content
- blog-folder-1
-- blog-article-1-1.md
-- blog-article-1-2.md
- blog-folder-2
-- blog-article-2-1.md
-- blog-article-2-2.md
Then I also have the layouts/_default/list.html file which will be called every time I visit the URLs example.com/, example.com/blog-topic-1/, and example.com/blod-topic-2/
So the problem I have is that I don't want the layouts/_default/list.html file to generate the same content for these different paths..
I overcame the problem of only displaying certain articles in the homepage by adding ++ displayHomepage = "true" ++ to the .md files and {{ range $index, $page := first 50 (where .Site.Pages.ByPublishDate ".Params.displayHomepage" "true") }} to the list.html file, but I can't figure out what to do if I don't want to display blog-article-2-1.md when visiting example.com/blog-folder-1/
Any help would be greatly appreciated <3
At this point the documentation is a little bit hard to order. I am going to link the important topics to the hugo documentation so that you are able to read more details. After looking to your Content Organisation there are two Sections:
blog-folder-1
blog-folder-2
So inside your theme you are able to define one template for each section. If there is no template provided hugo uses the default.
So inside your layouts folder there is that logic: /layouts/SECTION/LAYOUT.html
For your case you can define a default layout. When for example blog-folder-2 needs another template your structure would look like this:
layouts/
▾ _default/
single.html
▾ blog-folder-2/
single.html
If you want to filter out one section inside a list, you need to use the page variables.
At that points where you are ranging over the sites you can add a where clause:
{{ range $i, $p := (.Paginate (where .Data.Pages "Section" "!=" "blog-folder-2")).Pages }}

Preventing category downcasing in octopress

I've been using Octopress for a while, but I haven't pulled upstream changes for ages. I just made a new local branch to do so, and the merging was pretty painless, but one problem I have is that my category names are now downcased everywhere. This didn't use to happen, and it's a problem for me because I colorize links differently based on the category of each post, using the following:
{% capture category_class %}
{% for category in post.categories %}
{{ category | prepend:'category-' }}
{% endfor %}
{% endcapture %}
# ...
<div class="{{ category_class | strip_newlines }}">
Here, the category_class ends up being something like "category-coding" even though the category is specified in the post source as Coding, with a capital C. Now, I could just change my SASS to use lowercase category names for the classes... but then my category names would still be lowercase everywhere else, and I'd prefer them not to be.
So I'd like to remove this downcasing of category names throughout Octopress. But I can't for the life of me figure out where it is actually happening. (It probably doesn't help that I don't know Ruby.)
There's a downcase call in Jekyll which produces the lowercased categories:
https://github.com/jekyll/jekyll/blob/v2.5.3/lib/jekyll/post.rb#L83
def populate_categories
categories_from_data =
Utils.pluralized_array_from_hash(data, 'category', 'categories')
self.categories = (Array(categories) +
categories_from_data).map {|c| c.to_s.downcase}.flatten.uniq
end
There doesn't seem to be any other way to access the categories array within a post. You would need to modify or monkey patch Jekyll yourself or just use Javascript or CSS (text-transform) to re-capitalize.
It seems Octopress also supports plugins, so that could be one more solution if you want to do some custom Ruby hacking. I.e. create a capitalized categories plugin.

Jekyll / Liquid include files dynamically

currently I'm working on a new site with Jekyll and have some kind of problem there. I have a layout page, where I can define the background image with variables from each page.
Layout:
class="background background-{{ page.header_bg }}"
Page:
---
header_bg: storm
---
But now I want to include some file dynamically, depending on the variable value. Well, I can do it with some if or case statements, but actually I want to do something like
{% include page.header_bg %}
But this does not work, because Jekyll is looking for a file, that is called "page.header_bg" and not the value.
Can some one help me please?
According to the docs, you need to put the variable name inside additional {{ }}.
Quote from the link:
ProTip™: Use variables as file name
The name of the file you wish to embed can be literal (as in the
example above), or you can use a variable, using liquid-like variable
syntax as in {% include {{my_variable}} %}.
I know this question is 6 years old but here's a clear answer for posterity. You need to assign page.header_bg to a variable first and then use the variable in the include statement.
{% assign headerBg = page.header_bg %}
{% include headerBg %}
You will get an error Liquid Exception: Invalid syntax for include tag if you attempt to use page.header_bg directly in the include statement.

Explain structure of site.categories

Jekyll supplies a site.categories variable that is accessible to liquid templates. In my site I currently have two categories with one post each. From looking at the jekyll bootstrap categories.html I know:
{% for category in site.categories %}
{{ category[0] }}
I know this renders to the category's name. However if I also do:
{% for item in category %}
{{ item }}
It seems category has two items: its name and the post. This makes no sense to me. category[0] is name and then an array of posts starts at index 1? Why does this make sense? I wonder if this comes from Ruby somehow, but I don't know Ruby. (Since Jekyll is written in Ruby I'm adding this tag, since I suspect much of the syntax is derivative.)
How do I determine the structure of site.categories? I don't know how to debug this and don't understand liquid syntax well enough to know why this behavior makes sense.
site.categories is a multi-dimensional array of categories. Each category consists of it's name as first element, and a list of posts contained in that category. The posts themselves consist of their name, content, permalink and more (the same info as in site.posts entries).

Resources