Is it possible to change the layouts such that eleventy generate a set of markdown format files?
I have a list of authors from a library catalogue which I want to continue edit them to make a single page for each of the author. So I want to generate a markdown template for each record first, then I will continue edit these one by one.
You can use Eleventy and templating to generate a variety of file types, including Markdown. Essentially, if you have text and want to use templating languages to generate it, Eleventy can do that.
For example, let's say you have a global data file containing fruit names. This could also be an array of objects, but for simplicity let's just use names for now. In your case, this could be an array of objects for each author.
// _data/fruits.js
module.exports = [
'Apples',
'Bananas',
'Oranges',
'Pears',
]
You want to create a Markdown page for each fruit with a little description. In this example, I'll be using Nunjucks but this could be adapted to any templating language supported by Eleventy.
In fruits.md.njk (name doesn't matter):
---
pagination:
data: fruits
size: 1
alias: fruit
permalink: 'fruits/{{ fruit | slug }}.md'
---
--- {# We can even define front-matter that will appear in the output #}
layout: content
---
# About {{ fruit }}
{# Use whatever markdown syntax you want #}
{{ fruit }} are _very_ **delicious**.
`Buy {{ fruit }} here!`
In this template, we are using pagination to create individual pages for each item in the fruits array (paging global data). We define a permalink to output a .md file, and the rest of the file is just normal Markdown, with added templating tags. You can use all of the regularly available Nunjucks/other templating tags, such as loops, macros, or inheritance.
You can extend these ideas to generate other things, like Javascript files, JSON files, YAML files, XML, or any file that's just text. Nothing is stopping you from templating things that aren't HTML.
The output of the above template is:
---
layout: content
---
# About Apples
Apples are _very_ **delicious**.
`Buy Apples here!`
Related
All the documentation I've found on Eleventy pagination has to do with a single level, and I've got that working pretty well.
Take a collection (ex. of tags) and create one page each
Take a collection of posts and put 10 on each page
and so on.
What I'd like to do now is combine them: loop over all the tags, and then paginate each tag's collection so if I use some tags a lot, they don't end up with 50 posts on the same page. Basically the way WordPress generates paginated views for each tag.
Something like this: (simplified, I know filters need to be in there)
pagination:
data: collections
size: 1
alias: tag
pagination:
data: tag
size: 10
alias: tagpost
Though that didn't seem to work.
Is there some way to do multi-level pagination, or would I need to take some other approach for the outer loop?
That has been the thorn in my side from the beginning. There is an issue post on 11ty's GitHub explaining how to flatten the data and then paginate using Javascript, but then you'll lose all the nice pagination features already built in 11ty.
Another big issue is how to get Tags dynamically from the API. If you need a single template file for each Tag, paginated or not, you have to do it manually for each tag. So if there's a new tag coming from CMS through API 11ty has no way to handle it automatically.
There are a zillion tutorials for 11ty and not a single one explaining how to do two things that literally every site needs to have.
Good luck with it.
BTW, that being said, I love 11ty, I really do.
You can build a custom collection
config.addCollection("tagpages", function(api) {
// Map over api.getAll() to build TagPage or TagGroup that contains
// an array of Pages
});
that has the format:
TagPage {
id: Number;
tag: string;
posts: post[];
}
Then the front matter:
---
Pagination:
Data: collections.tagpages
Size: 1
Alias:tagpage
Permalink: /{TagPage.tag}/{TagPage.id}
---
Display your tag and X posts.
You could have your config customize by tags and number of items per page.
config.addCollection("tagpages", buildTagPages(tag, numItems));
My site has a collection of research reports, which renders out as a page for each report that includes a link to a PDF, like a standard directory based Eleventy collection. For one of the reports, I'd like to add the full report as HTML pages, which each section, e.g. Methodology, as it's own sub page.
In other words, I'd like to have sub pages for a page in a collection.
Could anyone provide advice on how I might do this with Eleventy?
Thanks a million <3
You can use Pagination like so:
---
pagination:
data: page.subArray
size: 1
alias: subData
permalink: "subpage/{{ subdata.title | url }}/index.html"
---
You can then access the data for each sub page via the {{ subData }} alias
I want the users on my blogsite to be able to type in markdown text in a textarea to make a blogpost. This markdown text would then be converted with a tool like Redcarpet or kramdown. Now I also want the user to be able to call a partial view that lays out some pictures. So in other words, I want the user to be able to type in the following code anywhere in between his markdown text (and it being interpreted as erb code)
<%= render partial: "slider", locals: {imgs: ["image1.jpg", "image2.jpg"]} %>
Is this possible somehow? kramdown allows you to use block-level HTML tags (div, p, pre, …), so maybe this could be used to some advantage?
Do you really want your customers to be able to write ERB? That's extremely dangerous, they can use any Ruby function in ERB, including Kernel functionalities. What about allowing a simple templating system, either a custom one or an existing one. For example you can use Liquid (from Shopify), provide some custom tags so they won't need all the boilerplate but just something like {% dosomething 'partial', 'img1', 'img2' %}, then you first convert liquid into normal text, then you convert markdown to html, cache it and display that to the user. An example:
# get your customer text from somewhere, like params[:markdown_text]
template = params[:markdown_text]
markdown = Liquid::Template.parse(template).render
html_text = Redcarpet::Markdown.new(renderer, extensions = {}).render(markdown)
puts html_text.to_s # => text with html tags, ensure to use `html_safe` on it in views
And you have your text ready
I am aware you can add and use html page custom front matter fields using the {{ page.myField }} directive but this does not work for posts (i.e. when iterating site.posts in a for loop.
My problem, what I have done ...
I created a new post in _posts with a .md extension containing new custom front matter fields (it is published and refixed correctly with date) - Seems correct
I loop all the posts using {% for post in site.posts %} - This works
When I attempt to use these using a liquid tag {{ post.myNewField }} it is not available but does show in post.content as text not a useable field.
Surely this cannot be correct. I would assume anything in the markdown in the front matter section should be accessible, as it seems to say so in the Jekyll front matter instruction
http://jekyllrb.com/docs/frontmatter/#custom-variables
Please help.
cause of my issue was UTF-8-DOM encoding when it should have just been UTF-8 encoding for .md files
I want to have a template "_layouts/template1.html" extend (Django-style) a template _layouts/default.html.
I'm putting this as a YAML front matter in _layouts/template1.html
---
layout: default
---
{{page.content}}
but apparently it doesn't work the way I'd like it to work (all the additional markup that is present in template1.html but IS NOT in default.html does not render). It looks like the file that uses template1 layout purely extends default.html.
Is there any way to have layouts inheritance in Jekyll?
What you mean is simply {{ content }}.
Yes, layouts can be piped. In your case, if a page uses template1 layout, it is the content for template1. Then, the result of template1 is the content for default.
Jekyll's Liquid templates extend pretty easily, you just have to be sure you're extending and not overwriting your desired template.
You may actually want to extend page and not default.
So, in your template Front Matter:
---
layout:page
---
Try the Liquid Inheritance Gem: https://github.com/danwrong/liquid-inheritance
Reference: http://www.sameratiani.com/2011/10/22/get-jekyll-working-with-liquid-inheritance.html
template1.html from your example will extend default.html as long as the latter contains a {{ content }} block. See here for example. What it won't do is it won't overwrite anything that default.html already contains. For that you'll need the Liquid Inheritance Gem, as mentioned by #juddlyon.