-
-
Notifications
You must be signed in to change notification settings - Fork 493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collections as data only #546
Comments
Hi, I'd use JSON, if you need control over the order or some kind of batch processing (doing that with events/conferences/... on my website right now). On the other hand, dedicated files are easier to reason about separately. |
Thanks @Ryuno-Ki I'm currently using the collection technique. Although it does appear that the folder of collection items gets rendered out to the compiled _site folder. Since it is only data and won't require a front-facing end result outside of a listing I think I would prefer a data file... How would you recommend handling the Markdown "content" data in a JSON file? I'm going to need a content editor to be able to update that (using Netlify CMS). Thanks! |
Hi @babycourageous, I digged the last two hours into code. But let me start from the beginning. My first idea was to use Then I recalled, that you can adjust some overrides. For example, Okay, then maybe something else? I guess, you could go with JavaScript Template Literals, but you would still get an output. What about using a custom Nunjucks environment. The idea being, that it would have a Problem is, that the list of template formats is fix. If I comment the code in (locally), I can see error messages like this:
My const Nunjucks = require("nunjucks");
module.exports = function (eleventyConfig) {
const nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("_includes")
);
eleventyConfig.setLibrary("noop", nunjucksEnvironment);
eleventyConfig.addTemplateExtensionAlias("noop", "noop");
/* … */
}; Here I interrupted my work (took already quite a while). |
With a JSON ( [
{
"name": "Towel Day",
"start": "2019-05-25",
"end": "2019-05-25",
"url": "http://www.towelday.org/",
"location": null
},
{
"name": "E3",
"start": "2019-06-11",
"end": "2019-06-14",
"url": "https://www.e3expo.com/",
"location": {
"name": "Los Angeles Convention Center",
"address": "1201 S Figueroa Street",
"locality": "Los Angeles",
"country": "California",
"postalCode": "90015"
}
}
] I render it via a layout file ( ---
layout: h1
---
{% if events %}
<h2>Future events</h2>
{% set futureEvents = events | isFutureDate %}
<ol>
{% for futureEvent in futureEvents %}
{% set event = futureEvent | asEventObject %}
<li>
{% include "_partials/event.njk" %}
</li>
{% endfor %}
</ol>
<h2>Past events</h2>
{% set pastEvents = events | isPastDate | reverse %}
<ol>
{% for pastEvent in pastEvents %}
{% set event = pastEvent | asEventObject %}
<li>
{% include "_partials/event.njk" %}
</li>
{% endfor %}
</ol>
{% else %}
Currently none.
{% endif %} by referencing it in a Markdown file ( ---
layout: events
title: 'Interesting events'
---
Here are some events you might be interested in attending: |
Thanks @Ryuno-Ki Instead of trying to square peg a markdown list into the JSON round hole (or use collections as data items), what I might wind up doing is have each list item as an entry in the JSON object. Something like:
Then I can loop over the bullets and render each in an |
I've faced similar issues when keeping raw markdown in a JSON doc, and I've ended up trying a few different routes. There hasn't been a clear winner yet, for me at least. (subscribing here to stay in the loop on this one, curious how you get on with this over time.) You could compile markdown source files into the A bit of an aside: Your structure is starting to resemble portable text, which I just started consuming this morning from a sanity.io datastore. I used the portable-text-to-html package, but there's also one to convert to markdown. You can set up custom serializers to handle special tags or, say, convert |
Hey, on one of my sites, I use csv for the data, and I use a javascript file to read it, parse it, and feed it to 11ty - 11ty can use You could try pairing it with the fact that yaml supports multiple documents and use a filter in your template. So, yaml with structured data with markdown is parsed by JS file which is read by 11ty and then rendered out. |
I think, I had a similiar idea like adam: @adamkiss Could you share some code? Sounds interesting! |
@Ryuno-Ki Sure, here you go: https://github.com/adamkiss/11ty-yaml-data |
Thanks for all the suggestions! I'll try some stuff out and fiddle around with my use case. Sorry it's taken a while to respond! |
Ah, that reminds me, that I wanted to share my approach as well! Setup:
---
tags: feed
title: Zach Leatherman
xmlUrl: https://www.zachleat.com/web/feed/
---
const fs = require('fs')
const path = require('path')
const { promisify } = require('es6-promisify')
const yaml = require('js-yaml')
const readdir = promisify(fs.readdir)
const readFile = promisify(fs.readFile)
const feedPath = path.resolve(__dirname, '..', '..', 'feed')
async function getFeeds () {
let jsonContent
const fileNames = await readdir(feedPath)
const filePaths = fileNames.map((filename) => path.join(feedPath, filename))
const yamlContent = await Promise.all(filePaths.map(async (filePath) => {
return readFile(filePath, 'utf8')
}))
try {
jsonContent = await Promise.all(yamlContent.map(async (content) => {
return new Promise((resolve, reject) => {
try {
yaml.safeLoadAll(content, (parsed) => {
return resolve(parsed)
})
} catch (error) {
return reject(error)
}
})
}))
} catch (error) {
console.error('Oops', error)
return Promise.resolve([])
}
return jsonContent
}
module.exports = getFeeds
<ul>
{% for feed in feeds %}
{% set feedData = feed.xmlUrl | withFeedData %}
{% set latestEntry = feedData.items | first %}
{% if latestEntry %}
<li>
{% set entryLink = latestEntry.guid or latestEntry.id or latestEntry.link %}
{% set feedUrl = feedData.feedUrl or feed.xmlUrl %}
{{ feedData.title }}:
<a href="{{ entryLink }}">
{{ latestEntry.title }}
</a>
{% if latestEntry.creator %}
by {{ latestEntry.creator }}
{% endif %}
{% if latestEntry.pubDate %}
on {{ latestEntry.pubDate | dmyDate }}
{% endif %}
(<a href="{{ feedUrl }}">Subscribe</a>)
</li>
{% endif %}
{% endfor %}
</ul> Eleventy render call: Works fine for me :-) |
Hmm, lemme see if I can summarize the questions here? To the original post, @babycourageous: I think method 1 is if you’re using a CMS to generate the file (as I believe you stated). Method 2 is preferred if you’re editing the files yourself. How to prevent a directory of files from appearing in the output?Use Status of extension aliasingI wasn’t happy with it so it got punted. It’ll hopefully make it back in, eventually. Did I miss any other questions? Is this issue resolved? |
@zachleat thanks! Sorry - other projects took hold and i lost track of responding to the issue. Original QuestionI'm not pulling from a CMS so I will use method 2 since that will give me a little more control over the markdown content (they are basically pricing table style items). Trying to store lists and headings and paragraphs as a single JSON string is the pits, heheh. Output preventionClassic facepalm. Totally forgot about disabling permalinks (especially via collection/directory specific data files!) Those were my questions - solved! |
Belated thanks! |
example:
{
"tags": "pages",
"tags-pages-comment": "make files available in `collections.pages`",
"permalink": false,
"permalint-false-comment": "exclude files from output, only make them available in collections",
"permalint-false-docs": "https://www.11ty.dev/docs/permalinks/#permalink-false"
}
---
layout: layouts/base.njk
---
<div class="page-container">
{%- for page in collections.pages -%}
<div class="page">
{{ page.templateContent | safe }}
</div>
{%- endfor -%}
</div> use case: create single file apps with eleventy |
Hi there
Curious about a best practice to go about this. I have a section of content that would be iterated over on the front page but doesn't need to be rendered as individual pages and I'm debating between two ways of setting this up in 11ty -
The reason I'm thinking of option 2 is I need the main content of the service to be rendered as html (bold, lists, etc) which I haven't been able to accomplish in a JSON file...
Would it make the most sense to use collections in this way and just add that collection folder to the .eleventyignore file to prevent rendering of each service as a page? Or since it's just data is it preferred to keep it in a global data file and just store the markdown as a string?
Sorry if this has been asked before - i didn't find anything when i searched through the queue
The text was updated successfully, but these errors were encountered: