I try to create a global variable in layout and call it in pages
E.g:
<!-- _layouts/post.html -->
{% assign filename = page.url | split: '/' | last | replace: '.html', '' %}
{{ content }}
in post page:
<!-- SomePage.html -->
<h1>Page Name: {{ filename }}</h1> //-> # Page Name: SomePage
The page name should be printed but I do not know how to do it
Any ideas?
I guess you are misusing Jekyll as it is not suppose to work like that. It should be used other way around. Templates are designed to show pages with variables, so that you follow many to one relation pages in templates.
The idea is to put repetitive part of your pages in your layout. So you should have your layout defined like this:
<!-- _layouts/post.html -->
{% assign filename = page.url | split: '/' | last | replace: '.html', '' %}
<h1>{{ filename }}</h1>
{{ content }}
Then you don't have to write that part in your every page, but it is handled automatically for you.
Related
I need to extract the filename portion of the page url, that is from a post saved in 2011-12-31-new-years-eve-is-awesome.md I would like to just the part new-years-eve-is-awesome .
Unfortunately post_url contains also the directory tree 2011/12/31/
This page https://jekyllrb.com/docs/permalinks/ seems to suggest that defining
---
shorttitle: :title
---
in the front matter should work but that produces an empty string from {{ post.shorttitle }}
Here is my solution so far. Perhaps there is a variable left in the code but it's not documented, therefore I just filter the post URL:
{% assign spliturl = post.url | split: '/' %}
{% assign postname = spliturl[4] | replace: '.html', '' %}
{{ postname }}
can anyone offer assistance on how I can alter a product page with individual tabs at the bottom (full description, delivery, returns info) In this case (size chart) is what i'm implementing. I need to get text from my product description which houses the size chart at the bottom of the description's paragraph.
presume i will need to use some type of html tag on my product description editor to signal where to split the text like a "!-- split -->" move. but i also need to add something into my custom tabs div? which is below
{% if section.settings.product_customtabs_1 %}
<div id="collapse-tab3" class="tab-pane fade">
{% include 'display_product_detail_description' %}
{% if settings.enable_multilang %}
<div class="lang1">{{ section.settings.product_customtabs_content_1 | split: '|' | first }}</div>
<div class="lang2">{{ section.settings.product_customtabs_content_1 | split: '|' | last }}</div>
{% else %}
{{ section.settings.product_customtabs_content_1 | split: '|' | first }}
{% endif %}
</div>
{% endif %}
am i going about this all wrong?
you can use the custom HTML tag like <!-- split --> between backend product description editor and then separate the content over product page easily using liquid code filters.
{% assign productDes = product.description | split:'<!-- split -->' %}
{% assign productDesPart1 = productDes[0] %}
{% assign productDesPart2 = productDes[1] %}
you can use the first]and last array filters first to get the values, but it works when there is a single <!-- split --> is used.
{% assign productDesPart1 = product.description | split:'<!-- split -->' | first %}
{% assign productDesPart2 = product.description | split:'<!-- split -->' | last %}
you can use something like this, but careful with the HTML tag into the backend editor and liquid code are some otherwise is not works.
I'm fairly new to Jekyll, and am currently trying to build a site to hold a bunch of pages containing course training material. I'm trying to use Jeykll collections to do this and have a site structure like this:
/
|
|_ "_course001"
|
|_ subdirs/subdocs
|_ "_course002"
|
|_ subdirs/subdocs
When rendering content for each course (setup as a collection) I would like a navbar to display the other documents in the current course/collection only (i.e. not in other courses).
Using something like this works:
{% for each coursedoc in site.course001 %}
[Create anchors and text]
{% endfor %}
However I want to have the collection name by dynamically assigned during the site build rather than hardcoded. I've tried doing something like this:
{% for each coursedoc in {{ page.collection | prepend: "site." }} %}
[Create anchors and text]
{% endfor %}
But this does not work, I guess because {{ page.collection | prepend: "site." }} returns a string.
Anyone have some suggestions on how I could do this?
And I think I just answered my own question:
{% assign collection = site.collections | where: "label", page.collection | first %}
{% for node in collection.docs %}
[Create anchors and text]
{% endfor %}
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 %}```
I'm trying to write a static site with Jekyll that has a few layers to it. What's the best way to generate links to all subpages within a section?
For example, if I have a site structure like this:
landing
- Topic A
- Content 1
- Content 2
- Content 3
- Topic B
- Content 1
- Content 2
- Content 3
What would be the best way to create links to each of the Content pages from its Topic page? And, is there a simple way to link to all the Topic pages from the landing?
These are not posts, just static pages. It would be really great if I could just do {% for topic.each %} ...etc. and print the links out.
I would not use posts for this purpose (as yaitloutou suggests). I would read the hierarchy from the directory structure (solution 1) or create two seperate collections (solution 2). You can let the collections from solution 2 share the same layout if you want that.
1. Using pages
Create a directory structure with index.md pages and loop over the Jekyll veriable called 'site.pages' to create the menu.
index.md
topic-a/index.md
content-1/index.md
content-2/index.md
content-3/index.md
topic-b/index.md
content-1/index.md
content-2/index.md
content-3/index.md
And loop over all pages like this:
<ul>
{% assign sitepages = site.pages | sort: 'order' %}
{% for sitepage in sitepages %}
<li {% if page.url == sitepage.url %} class="active"{% endif %}>
{{ sitepage.title }}
</li>
{% endfor %}
</ul>
If you want the nested structure, you can do something like this. Or if you want only the results for Topic A, you can do this:
<ul>
{% assign sitepages = site.pages | sort: 'order' %}
{% for sitepage in sitepages %}
{% if sitepage.url contains 'topic-a' %}
<li {% if page.url == sitepage.url %} class="active"{% endif %}>
{{ sitepage.title }}
</li>
{% endif %}
{% endfor %}
</ul>
2. Using collections (simplest solution and quickest build)
Create a collection Topic A and create another collection Topic B. Your config file should look like this:
collections:
topic-a:
output: true
permalink: /topic-a/:path/
topic-b:
output: true
permalink: /topic-b/:path/
Outputting the items of one topic goes like this:
{% assign atopics = site.topic-a | sort: 'order' %}
{% for atopic in atopics %}
<li {% if page.url == atopic.url %} class="active"{% endif %}>
{{ atopic.title }}
</li>
{% endfor %}
</ul>
You should create a _topic-a and a _topic-b directory with your content-1.md, content-2.md, etc. files.
Note that both solutions have YML variables called 'order', to determine the order of appearance of the items/pages. This looks like this:
---
title: mytitle
layout: mylayout
order: 50
---
mycontent
I'll propose here 2 ways, you can determine the "best" according to your specific needs/situation, and which one sound more adapted to them.
first of all, "posts" and "pages" are basically just collections of md/html files. with some variables associated to each one.
to generate files with this structure, you can:
1. Using _posts and page.categories
put all the sub-files in _posts (the 2017-01-01- is just a place holder)
_posts/
- 2017-01-01-content-a-1.md
- 2017-01-01-content-a-2.md
- 2017-01-01-content-a-3.md
- 2017-01-01-content-b-1.md
- 2017-01-01-content-b-2.md
- 2017-01-01-content-b-3.md
add appropriate categories to each file:
2.1. for posts caontent-a-* add category: topic-a (in this order) by adding this line in the yaml front matter at top of each of them:
---
layout: page # or any appropriate layout
category: topic-a
---
2.2. for posts caontent-b-* add category: topic-b
set a premalink to ignore the date, and create the desired structure, by adding the following line to _config.yml:
defaults:
-
scope:
path: "_posts" # to all the file in posts
values:
permalink: /landing/:categories/:title.html # set this as default permalink value
you still can specify a permalinks per post in its front matter, or just add the permalink line to each md folder front matter.
the above will generate the desired structure.
loop through all the
{% for entry in site.posts %}
{% if entry.category == type-a %}
<!-- do A stuff -->
{% elsif entry.category == type-b %}
<!-- do B stuff -->
{% endif %}
{% endfor %}
2. Using collections:
it's similar to the above, but instead of using the already existent _postscollection you'll start by creating a new collection (one advantage is that you'll not need to add a date )
any of the approaches above will generate this structure inside _site
landing/
type-a/
content-a-1/
index.html
content-a-2/
index.html
...
type-b/
...