I have built a website based on the Jekyll code for the website for Apache Buildr. The Buildr website automatically generates a table of contents for each page based on the headers in the textile format files.
For example, you write a page using textile marking out the headings like so . .
h2(#why). Why are we doing this?
BLah blah balh etc ..
h2(#something). Some other header
BLah blah balh etc ..
Then in the default HTML you have some code that pipes the content into something called toc and then you put the contents afterward. For example ...
<div id='content'>
<h1 id='{{ page.title | downcase | replace(' ', '_') }}'>{{ page.title }}</h1>
{{ content | toc }}
{{ content }}
</div>
On the Apache site they get the desired results (the toc is shown followed by the contents). However, on my site, the contents are rendered twice. No table of contents is generated.
Furthermore, if I clone the Apache Buildr project directly from github and run jekyll --server in the doc folder of that project, then no table of contents is generated either.
What am I missing?
I emailed the Buildr developer mailing list and someone told me to look here for inspiration. Turns out that the relevant code snippet is ...
module TocFilter
def toc(input)
output = "<ol class=\"toc\">"
input.scan(/<(h2)(?:>|\s+(.*?)>)([^<]*)<\/\1\s*>/mi).each do |entry|
id = (entry[1][/^id=(['"])(.*)\1$/, 2] rescue nil)
title = entry[2].gsub(/<(\w*).*?>(.*?)<\/\1\s*>/m, '\2').strip
if id
output << %{<li>#{title}</li>}
else
output << %{<li>#{title}</li>}
end
end
output << '</ol>'
output
end
end
Liquid::Template.register_filter(TocFilter)
Make a folder in the source folder of your site called _plugins and then paste this code into a file called TocFilter.rb within that folder.
It works!!
Where is toc defined? It isn't listed as one of the standard liquid filters or jekyll extensions, so likely you are missing a plugin.
I've used ghiculescu's JS TOC on my Jekyll powered Github blog. It works very well.
Example.
jekyll-toc plugin does this for you out of the box.
Add the following to your GemFile
gem 'jekyll-toc'
Add the following to your _config.yml
plugins:
- jekyll-toc
Add the following liquid tag where you want the TOC to be generated.
{{ content | toc_only }}
And finally set toc: true in your post's front-matter.
I added this value as a default in my _config.yml so that TOC is applied to all my posts by default.
Related
I am building a hugo blog site and I have some front matter that I would like to get rendered in the layouts. When I view the results on my localhost:1313, I can see the front matter being populated, but when I host the site on Netlify, the front matter and partial files won't render.
I'm not sure what else to do. I've cleared the console of any errors, made sure my content files match the layout files etc.
Any help?
Here is the link to the live netlify site: https://stoic-meninsky-a5758a.netlify.app/
Here is my directory structure:
-content
-about
-_index.md
-blog
-_index.md
-post-1.md
-_index.md
-layouts
-_default
-baseOf.html
-about
-section.html
-blog
-section.html
-single.html
_index.html
This is a sample file that is pulled from one of my content markdown files:
---
title: "The Herman Show | Blog"
linktitle: "Blog"
draft: true
newsletter: "This is the newsletter"
---
This is how I call the front matter: <p>{{ .Params.newsletter }}</p>
This is how I loop over the section pages to get a navbar
{{ range .Site.Sections }}
<li>{{ .LinkTitle }}</li>
{{ end }}
Make sure your markdown files in the content directory are marked to: drafts:false
I'm starting to use jekyll, but when trying to customize a variable it does not work.
My code
---
layout: default
hello: "teste liquid"
---
<h1>{{ page.hello }}</h1>
but this don't work, it does not print anything in html, it leaves empty
do I need to do any additional configuration on jekyll?
I'm writing this because I had the same problem and I lost half a day trying to figure out what caused it.
When I installed jekyll and created a new site I got the following file by default: index.markdown with an empty front matter in it (two lines of three dashes each).
I also created an index.html file as the Jekyll tutorial suggested.
Apparently, if you have both files and you try to add front matter to the HTML file the whole site breaks and the default jekyll page is displayed instead of the index.html page.
The solution is to remove or rename the index.markdown file so the HTML file is the only index.
Note, that if you don't add front matter to the HTML page the HTML page is displayed normally (but, of course, the liquid tags {{ }} don't work)
Hope this help.
Thanks to virginiarcrz for pointing this solution out.
I had this issue. There was an extra space after toggling a comment '#' tag in the frontmatter of my index.md:
---
#title: index
title: index2
----
and I fixed it by removing the space:
---
#title: index
title: index2
----
I'm creating a website using Jekyll.
so far I have four pages which are created automatically from four md files which md files are in the root of the project.
index.md
about.md
login.md
register.md
Here is the content inside my login.md file
---
layout: layout-default
title: some login title
permalink: /login
theme: secondary-theme
nav:
menu-items:
- type: text
text: Don't have an account?
- type: link
text: SIGN UP
class: button
linkPath: /register
sections:
- type: 3
class: form-section
header-line-2: Login Section!
form:
api: http://127.0.0.1:8080/login
submit-text: LOG IN
form-controls:
- label-text: EMAIL ADDRESS
input-type: email
input-placeholder: Enter your email
input-name: email
- label-text: PASSWORD
label-link-text: Forgot password?
label-link-path: #
input-type: password
input-placeholder: Enter your password
input-name: password
---
What i do is iterating the sections and applying html attribute values depending on the variables inside each section. That way i can have as many sections rendered as i want on one page. And they can also be different depending on the classes and content i put in the md file.
The problem is that if the project gets too complicated with different styles for sections and so on. I would like to separate each section content. It would be nice if i could make a folder lets say login/sections folder
and then put md files inside and then inside login.md file include these section md files. This way the code would be much more organized.
Is there way to do that, and is my approach actually good.
Jekyll provides the ability to include files into another files. The magic directory for this is _includes. Example:
If you create a file named _includes/sections/s1.html, you can include that into any other file with the following tag:
{% include sections/s1.html %}
This approach works for:
including HTML file into HTML
including HTML file into Markdown (since Markdown can contain HTML code)
including Markdown into Markdown
If you want to include a Markdown file into a HTML, you have to use some trick:
{% capture m %}{% include sections/s1.md %}{% endcapture %}
{{ m | markdownify }}
Is it possible to add a post-processing step (in ruby) to run in Jekyll after it converts markup to HTML?
I'd like to add some html content, and can't see a way to do that in Jekyll files in general (though certain dialects of markup might support it), so I think it would have to be done by operating on the HTML after Jekyll converts it and before it writes it into _site/.
EDIT: Clarified that I'm looking to do this in Ruby and in arbitrary dialects of markup.
It looks like I may be able to do this by providing a Liquid filter that postprocess the html content, and changing {{ content }} to {{ content | my_postprocess }} in _layouts/post.html and _layouts/page.html.
Indeed, kramdown will not parse markdown in html element by default.
But, there is some configuration parameters that can be set to force kramdown to parse markdown in span or block elements.
Kramdown parameters in Jekyll documentation (look under the kramdown: key) but more interesting things in the kramdown documentation particularly here and here
In configuration
If you want to globally parse markdown in html, in _config.yml, add :
kramdown:
parse_block_html: true
parse_span_html: true
Or, in your markdown itself
{::options parse_block_html="true" /}
{::options parse_span_html="true" /}
<div>
## Some markdown here
**bold** and `code`
<cite>a **span** level element</cite>
</div>
You can also use markdown includes like this :
{% capture md %}{% include markdown_file.md %}{% endcapture %}
{{ md | markdownify }}
This will render any markdown as if it was in the original post/page.
Newer versions of Jekyll let you use hooks to do post-processing (and many other things).
For example, you could put a file like this in the _plugins/ directory, and it will modify the contents of posts after they've been converted to HTML but before they've been embedded in a layout file or written to disk:
Jekyll::Hooks.register :posts, :post_convert do |post|
post.content = post.content.gsub('old', 'new')
end
I have a Jekyll site that uses kramdown for markdown. In _config.yml I have the following setting that ensures that only <h2> and <h3> elements show up in the automatically generated table of contents:
kramdown:
toc_levels: "2,3"
This works fine, but on some pages I would like to include <h4> elements in the TOC as well, while retaining the existing <h2> and <h3> configuration on other pages. Is this possible?
On any page I can access the _config.yml definitions like this:
{{ site.kramdown.toc_levels }}
Is there a way to set the value of the toc_levels on a page?
I looked through the codes. It appears page-level settings are not possible for Kramdown at this moment. You are left with {:.no_toc} option to suppress unexpected tags.