Static files from collection (Jekyll) - jekyll

I have this site structure:
mysite
_artworks
category1
category2
category3
In _config.yml file I have:
collections:
artworks:
output: true
All static files are moved to a folder _site, but I can not refer them through {{ site.artworks.static_files }} in index.html.
In fact, I try to display pictures in cycle like this:
{% for art in site.artworks.static_files %}
<img src="{{ art.path }}">
<br>
{{ art.path }}
<br>
<br>
<br>
{% endfor %}
Why is it not working? And how to best organize a collection to store photos and display them by category, if this is a project gallery?

To access the collection generated pages you need to browse them directly:
{% for art in site.artworks %}
<img src="{{ art.path }}">
{{ art.path }}
{% endfor %}
If you have specified any image with a special tag and the image filename in a category of the collection, then you can access them inside the loop with:
Supposing you have in your collection front matter: my_image: hello.jpg and you have an image in the assets folder /assets/hello.jpg
{% for art in site.artworks %}
<img src="assets/{{art.my_image}}">
{% endfor %}
If your collections will just contain images, I would rather prefer specifying them in Jekyll data files and then include them in posts.

Related

Jekyll how to write posts for different topics

I am very new to jekyll. Currently, I noticed that there is only one /_posts folder in my project. All the posts I wrote in this folder will create a site in /_site/posts.
I wonder is there a way that I can write posts for different topics and generate the sites at different folders? For example, I want to write some posts related to 'travel', so I hope to put the markdown files in a folder like /_travel. I also want to write some posts related to 'work', so I hope to have a folder like /_work. And I hope jekyll can generate these websites separately, like /_site/travel and /_site/work.
The reason I want to solve this is I hope to create a path at the head of my posts. Currently, I am using
{% assign paths = page.url | split: '/' %}
{% for item in paths %}
{% if forloop.first %}
<span>
<a href="{{ '/' | relative_url }}">
{{ site.data.locales[site.lang].tabs.home | capitalize }}
</a>
</span>
{% elsif forloop.last %}
{% if page.collection == 'tabs' %}
<span>{{ site.data.locales[site.lang].tabs[item] | default: page.title }}</span>
{% else %}
<span>{{ page.title }}</span>
{% endif %}
{% elsif %}
<span>
<a href="{{ item | relative_url }}">
{{ site.data.locales[site.lang].tabs[item] | default: page.title }}
</a>
</span>
{% endif %}
{% endfor %}
But apparently, all my work and travel posts are located in the same folder _site/posts
First, you can create your own collections in _config.yml:
collections:
travel:
output: true
permalink: /:collection/:name
work:
output: true
permalink: /:collection/:name
output: true will render a page for each document in the collection.
Then you can create two folders named _travel and _work where you can put your posts.
You access the content of posts in each folder like this:
{% for travel_post in site.travel %}
...
<p>{{ travel_post.content }}</p>
...
{% endfor %}
Lastly, permalink: /:collection/:name should create a link at /travel/name_of_post. See Permalinks for collections for a list of placeholders for the permalink configuration variable.

How to display single product gallery with Timber?

Following the Timber docs, the single product page does not display the pictures gallery. How can I do that with Timber?
Using {{ product|print_r }}, I have found the answer, considering the product context, you can use:
{% for id in product.gallery_image_ids %}
<img src="{{ Image(id).src }}" />
{% endfor %}

Output link to "parent page"?

I have a collection _colletion. In there is a file _collection/path/topic.md and a folder _collection/path/topic/ that includes lots of .md files with content. The permalinks for these files are /path/topic and /path/topic/file-x - so a parent page with a folder with the same name with multiple random pages in it.
Now I want to output a link to /path/topic in all these .md files with the title of topic.md as link text:
---
title: This is the page title defined in topic.md
---
should become
This is the page title defined in topic.md
How do I do that most easily?
Can I somehow access the folder name topic of the .md files and use this to read topic.md and output it's title and also generate a link to it?
My current manual "solution" (or workaround):
Add a parent entry to the frontmatter of all pages in /topic/ that contains the title and relative URL for the topic.md:
parent: ['Topic Title', '../topic']
In the template of the pages:
{% if page.parent %}
<p>« {{ page.parent[0] }}</p>
{% endif %}
Works, but of course duplicates this information n times and has to be maintained manually.
How about this (option 1)?
{% assign pageurl_array = page.url | split: "/" %}
{% assign path = pageurl_array[0] %}
{% assign topic = pageurl_array[1] %}
<p>« <a href="{{ path }}/{{ topic }}/{{ topic }}.html">
{{ topic | capitalize | replace: "-", " " }}
</a></p>
If you do not mind crazy build times, do this (option 2):
{% assign pageurl_array = page.url | split: "/" %}
{% assign path = pageurl_array[0] %}
{% assign topic = pageurl_array[1] %}
{% capture parent_url %}{{ path }}/{{ topic }}/{{ topic }}.html{% endcapture %}
<p>« <a href="{{ parent_url }}">
{% for i in site.pages %}
{% if i.url == parent_url %}
{{ i.title }}
{% endif %}
{% endfor %}
</a></p>
I would go for the first option (much faster) and use this javascript to get the capitals and special characters right:
$('a').each( function() {
var str = $(this).html();
str = str.replace('Topic from url', 'Topic from URL');
$(this).html(str);
});
I admit that the javascript solution is far from pretty, but it solves the build time problem pretty well.
Note that Jekyll is pretty slow. I would advice you to dig into Hugo if you require faster build times.
During discussion in the comments on my question and the other answers I noticed that what I wanted to build was actually a very common thing: A breadcrumb navigation! Just a very "small" one, with only one level.
With this newfound knowledge I could google "breadcrumb" plugins for Jekyll:
This solution uses the path of the page to extract the "crumbs":
https://www.mikestowe.com/blog/2017/08/adding-breadcrumbs-in-jekyll.php
It uses the folder name for the link text.
Another similar implementation:
https://stackoverflow.com/a/9633517/252627
Another one:
https://stackoverflow.com/a/37448941/252627
So no title link text in all of these.
This solution actually reads the page title, but can also read breadcrumb frontmatter from the pages, and uses these as link text:
https://github.com/comsysto/jekyll-breadcrumb-for-github-pages/
https://comsysto.com/blog-post/automatic-breadcrumb-for-jekyll-on-github-pages
https://gist.github.com/csgruenebe/8f7beef9858c1b8625d6
This one might be a valid solution.
There are also real plugins (that unfortunately don't work with Github Pages):
https://github.com/git-no/jekyll-breadcrumbs
My solution, based on JoostS code:
{% assign url = page.url | remove:'.html' | split: "/" %}
{% assign path = url | pop %}
{% if path.size == 1 %}
<a class="back" href="/home/">home</a>
{% else %}
<a class="back" href="/{% for dir in path offset: 1 %}{{ dir | append: "/" }}{% endfor %}">{{ path | last }}</a>
{% endif %}```

Dynamically add and filter images in Jekyll for github pages?

I am trying out Jekyll to help someone who's not all that technical maintain their own static site. I would like to be able to have a images directory in the app's root /images containing images following a naming convention:
post_one_1.jpg, post_one_2.jpg, post_two_1.jpg, post_two_2.jpg ... etc.
I would then like for the user to create a post (post_one) and dynamically grab all of the images pertaining to that post from the images directory.
This plugin (https://gist.github.com/jgatjens/8925165) does almost exactly what I need, but isn't compatible with github pages.
Is there a solution in which I can hand the site off to a user and they would only need to add images to the image directory following the naming convention and then create a post and have access to the images?
Given you have a post file _posts/2015-05-28-post_one.md
From inside this post you have :
page.id = /2015/05/29/post_one
page.dir = /2015/05/29
In order to extract post_one whe do :
{% assign imgNameStart = page.id | remove: page.dir | remove: "/" %}
We now generate the base path we search for :
{% assign imgBasePath = imgNameStart | prepend: "/images/" %}
in this case it will be imgBasePath = "/images/post_one"
Loop over all our static files (files that are not pages or posts).
{% for img in site.static_files %}
And print images that have /images/post_one in their path like /images/post_one-01.jpg or /images/post_one-wathever-you-want.jpg
{% if img.path contains imgBasePath %}
<img src="{{ site.baseurl }}{{ img.path }}">
{% endif %}
{% endfor %}
All together :
{% assign imgNameStart = page.id | remove: page.dir | remove: "/" %}
{% assign imgBasePath = imgNameStart | prepend: "/images/" %}
{% for img in site.static_files %}
{% if img.path contains imgBasePath %}
<img src="{{ site.baseurl }}{{ img.path }}">
{% endif %}
{% endfor %}
Beware of code indentation if your post is a markdown file, four space indentation can be transformed to code snippet.

Accessing posts via directory tree in Jekyll

Let's say I have a directory like the following:
|things
|---|animals
|---|---|dog
|---|---|cat
|---|---|other
|---|languages
|---|---|Afrikaans
|---|---|Latin
|---|---|Japanese
|---|---|other
and I want to access all of the posts under the "other" category that is under the "languages" category.
I want to be able to do
{% for post in site.categories.things.languages.other do %}
but that apparently doesn't work in Jekyll.
If I can avoid it, I'd like to not do
{% for post in site.categories.cobol do %}
{% if post.categories equals ["things", "languages", "other"] %}
but if I absolutely must, I will.
If you want to simply output a list of posts contained in a given path :
languages_other.html
---
path: "things/languages/other/"
---
{% include post_by_folder.html path=page.path %}
_includes/posts_by_folder.html
<h1>Posts in folder {{ include.path }}</h1>
<ul>
{% for post in site.posts %}
{% if post.path contains include.path %}
<li>
{{ post.title }}
</li>
{%endif %}
{% endfor %}
</ul>
Now any time you want to make a list of posts in a particular folder, you just have to create a page like languages_other.html.