In a Jekyll powered page, I have a set of files located in:
_includes/stuff/
I put those files there so that I can include them in other Markdown pages using:
{% include stuff/example.txt %}
This works as expected.
However, I also want to copy those files to the generated page so that I can link to them and that people can follow those links to download them. But by definition, stuff stored in directories starting with an underscore are not copied by Jekyll.
Another approach also didn't work. I put the files in an own top folder called stuff. This copies the folder to the final site. However, I'm not able to include a file from this folder. It seems include_relative only allows including files below the current one. For example, the following don't work:
{% include_relative stuff/example.txt %}
{% include_relative /stuff/example.txt %}
{% include_relative ../stuff/example.txt %}
Any ideas how I can achieve including and copying at the same time?
This works from index.html
{% include_relative example.txt %} for example.txt
{% include_relative stuff/example.txt %} for stuff/example.txt
{% include_relative /stuff/example.txt %} for stuff/example.txt
stuff/example.txt
class Toto
def dototo
myvar = "toto"
end
end
index.html
{% assign codeurl = "stuff/example.txt" %}
{% highlight ruby %}
{% include_relative {{codeurl}} %}
{% endhighlight %}
link to code
if codeurl == "/stuff/example.txt" this generates a link relative to site root
this may need {{site.baseurl}} prepended if your site is not at the root
of a domain (eg: user.github.io/repository)
link to code
For security reasons, this will not work :
{% include_relative ../stuff/example.txt %}
Just to avoid directory traversal
{% include_relative ../../../../../../../../../../../../etc/pwd %}
If you want to put you files in _includes/stuff you will need to do an include: [ /_includes ] in _config.yml, that will include all files in _includes as static files. Not very clean as you cannot filter subdiretories like include: [ /_includes/stuff ] to import only your stuff files.
Note : a dirty trick allows you to import only _includes/stuff/*.txt but I think it's really dirty.
# _config.yml
include:
- "_includes"
- "stuff"
- "*.txt"
exclude:
- "_includes/*.*"
Related
I'm currently trying to loop over a subfolder in Jekyll but I don't know whether this is possible.
My folder structure looks like this:
_includes
_layouts
_pages
folder_1
folder_2
index.html
For example, I want to reach folder_1 by a loop how can I do this?
{% for page in pages.folder_1 %}
//xyz
{% endfor %}
What I want is that I've a static page and on this page I want to display the title and the description of each page in one of the subfolders.
Could you please help me?
Avoid naming main folder with an underscore unless you are using the _posts folder.
Then filter posts or pages checking their path:
{% assign folder1 = site.pages | where_exp: "item" , "item.path contains 'folder1'"%}
{% for item in folder1 %}
{{item.title}}
{% endfor %}
Im my Jekyll website I need to create an documentation section similar to Original website. However I am not sure how the Docs sections renders. For example, the docs folder, which is located in site root, is filled with documentation .md files. This folder doesn't inculde any index.html file responsible for Layouting of website. The link to that folder is
Doc<span class="show-on-mobiles">s</span><span class="hide-on-mobiles">Documentation</span>
Could someone shed a light on how this section is rendering?
The docs folder includes an index.md, which is rendered as index.html in the final site.
If you look at the YAML front matter of index.md, you'll see this:
---
layout: docs
title: Welcome
next_section: quickstart
permalink: /docs/home/
---
The permalink: /docs/home/ line sets the final URL to {{ site.url }}/docs/home/, even though the actual file is in the /docs folder and the /docs/home folder doesn't even exist.
(for more info about the permalink setting, see Predefined Global Variables in the docs)
So that's where the URL comes from.
Concerning the list of documentation topics (the sidebar on the right):
The YAML front matter of index.md (see above), also contains the line layout: docs.
This refers to /_layouts/docs.html, a layout file.
Inside the layout file, there's the line {% include docs_contents.html %}, which refers to _includes/docs_contents.html, an include file, which contains the following code:
{% for section in site.data.docs %}
<h4>{{ section.title }}</h4>
{% include docs_ul.html items=section.docs %}
{% endfor %}
site.data.docs (in the first line) refers to /_data/docs.yml, a YAML data file.
It looks like this (shortened):
- title: Getting Started
docs:
- home
- quickstart
- installation
- usage
- structure
- configuration
- title: Your Content
docs:
- frontmatter
- posts
- drafts
- pages
- variables
- datafiles
- assets
- migrations
The code inside docs_contents.html loops through the items in the data file, displays the title values ("Getting Started", "Your Content"...) and then includes another include file /_includes/docs_ul.html, passing the list of docs from the data file.
This second include file loops through the list of docs, and does the following for each one:
Step 1:
{% assign item_url = item | prepend:'/docs/' | append:'/' %}
This builds the URL of the page based on the list item. For example, quickstart becomes /docs/quickstart/.
Step 2:
{% if item_url == page.url %}
{% assign c = 'current' %}
{% else %}
{% assign c = '' %}
{% endif %}
This marks the current page (used in the next step) by checking if the URL created in the previous step is equal to the URL of the current page.
Step 3:
{% for p in site.pages %}
{% if p.url == item_url %}
<li class="{{ c }}">{{ p.title }}</li>
{% endif %}
{% endfor %}
This loops all pages in the whole site, until it finds the page with the URL created in the first step.
(to make sure that the URL is equal, all Markdown files in the docs folder have set a permalink in the front-matter, for example permalink: /docs/quickstart/ in quickstart.md)
Then, it outputs a <li> with a link to the page, using the title from the respective Markdown file as the link text.
Plus, the class of the <li> is set to current if it's the current page (see step 2), so the current pae is highlighted in the list:
I use GitHub Pages for my blog, and am running into a problem with Jekyll. My post.html has a block like this:
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
The part in the middle doesn't matter. The important part is the end of the line which is outside of the {% %} markup, and is therefore rendered into the html. Since this is in a loop, it's putting about 1000 blank lines into the middle of by HTML page. It doesn't affect the display, but it make a View/Source troublesome.
Any ideas on how to avoid those extra blank lines?
Since Liquid v4 (included in Jekyll from v3.5) there is a Whitespace control, which finally resolved case with blank line, white space, etc.
Link to documentation: https://shopify.github.io/liquid/basics/whitespace/
There's a nice workaround, that I found out in https://github.com/plusjade/jekyll-bootstrap/blob/master/_includes/JB/setup, and which is compatible with github pages.
Just enclose your loop in a capture statement, and assign nil to the resulting var.
{% capture cache %}
{% for p in site.posts %}
do stuff here
{% endfor %}
{% endcapture %}{% assign cache = nil %}
How about
{{ page.content | escape | strip_newlines }}
There is Jekyll plugin that strips the whitespace.
Jekyll plugins by Aucor: Plugins for eg. trimming unwanted
newlines/whitespace and sorting pages by weight attribute.
You can get it directly from its Github repository. So basically you wrap your code with {% strip %}{% endstrip %}. Even if this doesn't suit you needs, you can easily change the ruby script.
For example:
{% strip %}
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
{% endstrip %}
However, please remember the nature of Jekyll plugins, you can't run them on the Github Pages server.
Quote from Jekyll Doccumentation:
GitHub Pages is powered by Jekyll, however all Pages sites are generated using the --safe option to disable custom plugins for security reasons. Unfortunately, this means your plugins won’t work if you’re deploying to GitHub Pages.
You can still use GitHub Pages to publish your site, but you'll need to convert the site locally and push the generated static files to your GitHub repository instead of the Jekyll source files.
Actually there is a new solution for this problem which works without any plugin.
A Jekyll layout that compresses HTML. At a glance:
removes unnecessary whitespace;
removes optional end tags;
removes optional start tags;
removes comments;
preserves whitespace within <pre>;
GitHub Pages compatible;
ignores development environments;
configurable affected elements;
profile mode;
automatically tested.
http://jch.penibelst.de/
If you - for some reason - do not want to use this here is a nice article, which describes some workarounds:
Compressing Liquid generated code - sylvain durand
I use GitHub Pages and created some pages in a sub folder. It seems to be not generating pages I created in sub folder. All other pages work fine. The directory structure is like this:
/
/index.html
/_config.yaml
/_includes
/_layouts
/_posts
/tag
/tag/personal.html
/tag/videos.html
The pages inside the /tag directory are not generated by Jekyll. Also, usually GitHub sends an email if Jekyll build fails, but did not, in this case. Also, if I do any other changes it works, so the build is apparently not failing.
The /tag/personal.html is here:
---
layout: default
title: Tag-personal
permalink: /tag/personal/index.html
tagspec: personal
---
<div id="tagpage">
<h1>Posts tagged personal</h1>
{% include tags.html %}
</div>
and /_includes/tags.html is here:
{% for tag in post.tags %}
{% if tag == page.tagspec %}
{% assign ispostviable = true %}
{% endif %}
{% endfor %}
<ul class="posts">
{% for post in site.posts %}
{% if ispostviable == true %}
<li><a href="{{ post.url }}"></li>
{% endif %}
{% endfor %}
</ul>
PS: I use GitHub Pages and have no access to a Jekyll instance at my development machine (Windows).
Joshua Powell provided step-by-step directions in reply to a similar question on Github.
Edit _config.yml to add the following line (or expand the array, if it exists)
include: ['_pages']
where _pages is the name of the folder in which you wish to keep your files. (This also works for nested folders if you explicitly add them, e.g., ['_pages', '_pages/foo'].)
Move your pages into that folder. (These pages may be HTML, Markdown, or whatever else Jekyll renders when it’s placed in the root folder.)
Give them front matter with an appropiate permalink including a trailing slash, e.g., permalink: "/about/".
I found the culprit. It was that In Jekyll v1.0, absolute permalinks for pages in subdirectories were introduced. Until v1.1, it is opt-in. Starting with v1.1, however, absolute permalinks became opt-out, meaning Jekyll defaults to using absolute permalinks instead of relative permalinks.
The pages were being generated at /tag/tag/personal.html and so on.
There were two solutions:
Specify relative_permalinks: false in _config.yaml
Make permalinks relative to the subdirectory.
I chose the first option.
The Jekyll Bootstrap project has a sample blog post in the directory _posts/core-samples/ .
I assume, posts (files) in sub directories are handled the same way as posts in the root directory. Is this correct?
If so, I will add a "stage" sub directory, exclude it, so I can park posts and publish them by moving them.
Accidentally found it in the post - yaml section:
Instead of placing posts inside of folders, you can specify one or
more categories that the post belongs to. When the site is generated
the post will act as though it had been set with these categories
normally. Categories (plural key) can be specified as a YAML list or a
space-separated string.
So sub directories == categories
As the different is only on post.path so I would agree to your statement:
posts(files) in sub directores are handled the same way as posts in
the root diretory
You can park your posts in the directory _posts/core-samples/ and publish them like this:
{% for post in site.posts %}
{% if post.path contains 'core-samples' %}
..your code
{% endif %}
{% endfor %}
As a working sample you may see how this code publish these parked posts in their section.
I ended up here because I wanted to create the following structure:
index.html
_animals
cats
my-cat.html
...
dogs
my-dog.html
...
I created that structure, then in _config.yml:
collections:
animals:
output: true
permalink: /animal/:title.html
Finally, to get just the dogs in index.html:
<div id='dogs'>
{% for a in site.animals %}
{% if a.path contains 'dogs' %}
<a href='{{ a.url }}'>{{ a.title }}</a>
{% endif %}
{% endfor %}
</div>
NB: that this approach requires that the directory containing all the records (_animals in my example) can't be named _posts, as the latter is a special name in Jekyll.
Actually what that statement says is to put _posts folder inside a sub directory.
And then that sub directory will be treated as category.