I'm using jekyll-sitemap plugin for Jekyll.
Is there a way to exclude .html files within the assets folder?
Some of them contain some HTML examples and I end up having things like the following in my sitemaps.xml, which doesn't make sense:
<url>
<loc>https://example.com/blog/assets/vanilla-lazyload/demos/with_picture.html</loc>
<lastmod>2017-11-18T15:05:22+01:00</lastmod>
</url>
Where with_picture.html is a demo file of a Javascript library, that comes with it when using npm install (and I can't be bother to remove those every time for every library)
According to the docs, using sitemap: false in our front matter should solve it, but it doesn't seem to be working at all.
Because I do not have any front matter in those vendor files, I'm using the Jekyll's Front Matter defaults method to do so, but without success.
# in my _config.yml
defaults:
- scope:
path: 'assets/'
values:
sitemap: false
I also tried the following path without luck:
path: "assets"
Might it be that path: 'assets' wont' take into account subfolders?
If your Jekyll version is v3.7.2 or higher and your jekyll-sitemap version is v1.2.0 or higher, this should work:
defaults:
-
scope:
path: 'assets/**'
values:
sitemap: false
The ** will match any file in the assets directory or in any of its subdirectories.
Here's the relevant section in the docs.
You can easily create your own sitemap without the plugin: Create a file called ‘sitemap.xml’ in your main jekyll folder, as in next to _post, _pages, and _includes.
All the file needs to contain is the following:
---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for post in site.posts %}
<url>
<loc>{{ site.url }}{{ post.url }}</loc>
{% if post.lastmod == null %}
<lastmod>{{ post.date | date_to_xmlschema }}</lastmod>
{% else %}
<lastmod>{{ post.lastmod | date_to_xmlschema }}</lastmod>
{% endif %}
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
{% endfor %}
{% for page in site.pages %}
{% if page.sitemap != null and page.sitemap != empty %}
<url>
<loc>{{ site.url }}{{ page.url }}</loc>
<lastmod>{{ page.sitemap.lastmod | date_to_xmlschema }}</lastmod>
<changefreq>{{ page.sitemap.changefreq }}</changefreq>
<priority>{{ page.sitemap.priority }}</priority>
</url>
{% endif %}
{% endfor %}
</urlset>
In your _config.yml file, add :
exclude :
- assets/vanilla-lazyload/demos
Related
when I create the port on Jekyll admin
title: layout:
page comments: true
social-share: true
show-avatar:true
use_math: true
I want to create this as default how should I do it?
Copy paste into your new post. Most CMS editors do that for you (like CloudCannon).
The real solution would be to transform them into site variables, by adding them to _config.yml and calling them using {{ site.social-share }} instead of {{ page.social-share }}.
An advanced solution would be to check if there are page variables, like this:
{% if page.social-share != nil %}
{{ page.social-share }}
{% else %}
{{ site.social-share }}
{% endif %}
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/
...
I'm building a magazine site with Jekyll (v2.5.3). The docs on the Jekyll site led me to believe that I could list all the collections on my site, and embed YAML data for each collection in my _config.yml.
_config.yml:
collections:
issue_001:
output: true
permalink: /:title/:path
title: Rebirth
date: 2015-07-01
issue_002:
output: true
permalink: /:title/:path
title: Talking Heads
date: 2015-08-01
index.html:
{% for issue in site.collections %}
<li>
<h6 class="post-meta">Issue {{ issue.name }} — {{ issue.date | date: "%b %-d, %Y" }}</h6>
<h2>
{{ issue.title }}
</h2>
</li>
{% endfor %}
I get two issues appearing on the homepage, but none of the data I'm accessing for each issue (name, date, title etc.) is appearing. I appreciate this is a beta feature, so just wanted to ask is this broken, or am I doing it wrong?
In case for someone still has this request here's how it works in latest Jekyll (v3.8.3):
Update: tested it still works in v4.2.0
{% for collection in site.collections %}
<h2>Items from {{ collection.label }}</h2>
<ul>
{% for item in site[collection.label] %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
In {% for issue in site.collections %}, issue is an array that contains :
0 => "issue_001",
1 => Hash
{"output"=>true,
"permalink"=>"/:title/:path",
"title"=>"Rebirth",
"date"=>#,
"label"=>"issue_001",
"docs"=>[#],
"files"=>[],
"directory"=>"/home/djacquel/www/test.dev/jekyll/wat/_issue_001",
"relative_directory"=>"_issue_001"}
The right way to access datas is :
{% for issue in site.collections %}
<li>
<h6 class="post-meta">
Issue {{ issue[1].label }}
—
{{ issue[1].date | date: "%b %-d, %Y" }}
</h6>
<h2>
{{ issue[1].title }}
</h2>
</li>
{% endfor %}
Second first; that answer from #sparanoid is fantastic! And between that and the source code from the default Jekyll Theme (Minima), I was able to bodge some of what follows together.
First second; excellent question and how both are not up-voted more is a bit baffling.
And third of many other related points; I'm not on a identical path as the question's poster but the following code may be of use to readers. My use case was wanting a way of listing the continence of a collection similar to the default Jekyll home layout.
_layouts/named_collection.html
Note the source links are downloadable via, clicking on the Raw link/button then Ctrl s to save as a regular text file, however, these links have been frozen in time so be sure to check the gh-pages branch for updates. And output examples are intended in this case to be just examples of possible content, eg. it could be Lorem strings for all that it matters to demonstrate what's to follow.
---
layout: default
---
{% comment %}
License note from S0AndS0; an editor in this context.
Minima (where the following code is sourced from), is shared under the
MIT Lisense, https://github.com/jekyll/minima/blob/master/LICENSE.txt
Thus any alterations to Minima source code is re-shared under the MIT Lisense
{% endcomment %}
{% capture workspace_collections %}
{% assign collection_name = page.collection_name | default: include.collection_name | default: nil %}
{% assign target_collection = site[collection_name] %}
<div class="home">
{%- if page.title -%}
<h1 class="page-heading">{{ page.title }}</h1>
{%- endif -%}
{{ content }}
{% assign has_output = False %}
{%- if target_collection.size > 0 -%}
{% capture workspace_collection %}
<h2 class="post-list-heading">{{ page.list_title | default: "Posts" }}</h2>
<ul class="post-list">
{%- for post in target_collection -%}
{%- if page.relative_path == post.relative_path -%}
{%- continue -%}
{%- else -%}
{% assign has_output = True %}
{%- endif -%}
<li>
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
<span class="post-meta">{{ post.date | date: date_format }}</span>
<h3>
<a class="post-link" href="{{ post.url | relative_url }}">
{{ post.title | escape }}
</a>
</h3>
{%- if site.show_excerpts -%}
{{ post.excerpt | markdownify | remove: '<p>' | remove: '</p>' }}
{%- endif -%}
</li>
{%- endfor -%}
</ul>
{% endcapture %}
{%- if has_output == True -%}
{{- workspace_collection -}}{% assign workspace_collection = nil %}
{%- endif -%}
{%- endif -%}
</div>
{% endcapture %}{{ workspace_collections | strip }}{% assign workspace_collections = nil %}
Side note, I can't remember where I picked up that capture some workspace_ trick, but it's pretty sweat for stripping new lines and other formatting shenanigans. If a reader figures out who started such fanciness, please edit or leave a comment.
Usage of this layout is much like the usage of Minima's home.html layout.
administration.md
... Front-Matter selecting from the _administration collection looks like...
layout: named_collection
collection_name: administration
title: Administration
list_title: Usage Examples
permalink: /admin/
... resulting in a <base-url>/admin/ collection listing being output.
git_shell_commands.md
... Front-Matter selecting from the _git_shell_commands collection looks like...
layout: named_collection
collection_name: git_shell_commands
title: Git Shell Commands
list_title: Usage Examples
permalink: /git_shell_commands/
... resulting in a <base-url>/git_shell_commands/ collection listing being output.
Even more notes on collections
If I'm reading the latest Jekyll Collections documentation correctly, as of version 3.7.0 it could be possible to have a custom collections directory, in the case of this question that might look like...
ls ~/git/magazine-name/
# ... other files and/or directories
# issues/
# ... other files and/or directories
# _config.yml
... where the issues/ directory contains sub-directories such as...
ls ~/git/magazine-name/issues/
# _001/
# _002/
# _003/
# ...
... and the _config.yml file has...
collections_dir: issues
collections:
001:
output: True
# ...
... the magic sauce was collections_dir and not using an under-scored prefixed base directory. The documentation was loud about that last bit, eg. _issues/ would make for a bad time.
I'm not sure if there'd be any other adjustments needed to the previously posted Liquid code (I don't think so, but probably); so maybe try'em out individually first.
Warning/Update
Jekyll does not take kindly to numbered collections, eg. _000 will cause errors!
To mitigate such issues be sure to trick Jekyll into treating collection names as strings, eg. _i000
The reason I suggest using a collections_dir, is because in the case of #James Dinsdale's question it may help in organizing things a bit more. Personally I wanted my gh-pages branch collection to mirror some of the same paths as my project's master branch, so didn't pursue testing collections_dir suggestions.
Notes about my Liquid coding choices
Because I'm using the Minima theme I placed the files that used the named_collection theme in my project's root directory; default behavior is to link to such pages at the top of every page. Cheap navigation.
Because readers might place pages that use the named_collection within the same directory as what is being listed, eg...
ls Jekyll_Admin/_administration/
# _administration/administration.md
# ...
... I've written the Liquid for some of the edge-cases, but may not have covered all of'em. Be sure to test privately before unleashing something like it on production.
Updates
After some testing with collections_dir it looks like when used the _posts directory must be moved to that directory too, eg...
_config.yml (Snip)
collections_dir: misc
Bash commands
mkdir misc
mv _posts misc/
... though that's only applicable if using a _posts directory.
Between the time of the last edit and when you're now reading this I've published liquid-utilities/collection-home on GitHub; might be of use to those that want a version tracked solution and is what I'm currently using in any projects that require this feature.
I am very new to writing websites and jekyll so I apologize if my terminology is unclear or wrong.
I have a bunch of saved files (foo1, foo2, etc) in a subdirectory called 'savedfiles' of my root jekyll folder. Suppose I am editing index.md which is in a sub folder called 'subfolder" and want to link to each of these. One way I can do this is to use
{{ site.url }}/savedfiles/foo1
{{ site.url }}/savedfiles/foo2
etc
Is there a way of saving the file path in a variable say pathfoo so that I could write
{{ pathfoo }}/foo1
etc
And sort of related to this can I get the file path of the subfolder that index.md is in? I know that
{{ page.path }}
will give me {{ site.url }}/subfolder/index.md but I want {{ site.url }}/subfolder. Is this possible?
Saving a path in a variable
{% capture path %}{{ site.url }}{{ site.baseurl}}/savedfiles/{% endcapture %}
you can now use this variable like this :
Link to foo
Getting file path from a file
It is a little bit tricky. But here is a way :
{% assign pathParts = page.path | split: "/" %}
{% assign length = pathParts.size | minus: 2 %}
{% assign path = "" %}
{% for c in (0..length) %}
{% capture path %}{{ path }}/{{pathParts[c]}}{% endcapture %}
{% endfor %}
You now have a path variable like /folder/subfolder. This could be simplest with pop or shift filters, but they are not working as expected and will change in Jekyll 3.0.