eleventy
eleventy copied to clipboard
Is there an attribute for a collection item's generated HTML for one or more njk layouts?
Based on https://www.11ty.dev/docs/layout-chaining/. If I understand correctly:
- Markdown has "content"
- It gets rendered in the markdown's layout.
- If that layout is chained then its content is finally rendered in the last one in the chain.
Example
my-markdown.md
---
layout: layouts/myLayout1.njk
title: My Markdown
---
# Hello from {{title}}
layouts/myLayout1.njk
Note: This layout adds it's Global Data to its own content
---
layout: layouts/myLayout2.njk
title: My Layout 1
---
<h2> {{ title }} in Layout 1</h2>
{{ content | safe }}
<h3>My Data</h3>
<pre>
{
myData.myKey: {{ myData.myKey }}
}
</pre>
layouts/myLayout2.njk
---
title: My Layout 2
---
<h3> {{ title }} in Layout 2</h3>
{{ content | safe }}
Generated HTML
<h3> My Markdown in Layout 2</h3>
<h2> My Markdown in Layout 1</h2>
<h1>Hello from My Markdown</h1>
<h4>My Data</h4>
<pre>
{
myData.myKey: My Value
}
</pre>
Everything works as designed.
my-markdown.md console.log
{
template: Template {
inputPath: './src/ocas/my-markdown.md',
inputDir: './src',
parsed: {
root: '',
dir: './src/ocas',
base: 'my-markdown.md',
ext: '.md',
name: 'my-markdown',
extname: '.md',
basename: 'my-markdown.md',
dirname: './src/ocas',
stem: 'my-markdown',
path: './src/ocas/my-markdown.md',
absolute: [Getter/Setter],
isAbsolute: [Getter/Setter]
},
extraOutputSubdirectory: '',
outputDir: './_site',
_extensionMap: EleventyExtensionMap {
formatKeys: [Array],
unfilteredFormatKeys: [Array],
_extensionToKeyMap: [Object],
validTemplateLanguageKeys: [Array],
passthroughCopyKeys: [],
configOverride: [Object],
_engineManager: [TemplateEngineManager]
},
linters: [],
transforms: [],
plugins: {},
templateData: TemplateData {
config: [Object],
dataTemplateEngine: 'liquid',
inputDirNeedsCheck: true,
inputDir: './src',
dataDir: 'src/_data',
rawImports: [Object],
globalData: [Object],
_extensionMap: [EleventyExtensionMap],
pathCache: [Array]
},
paginationData: {},
isVerbose: true,
isDryRun: false,
writeCount: 0,
skippedCount: 0,
wrapWithLayouts: true,
fileSlug: TemplateFileSlug {
inputPath: 'ocas/my-markdown.md',
cleanInputPath: 'ocas/my-markdown.md',
dirs: [Array],
parsed: [Object],
filenameNoExt: 'my-markdown'
},
fileSlugStr: 'my-markdown',
filePathStem: '/ocas/my-markdown',
_templateRender: TemplateRender {
engineNameOrPath: './src/ocas/my-markdown.md',
inputDir: './src',
_config: [Object],
includesDir: 'src/_includes',
parseMarkdownWith: 'njk',
parseHtmlWith: 'liquid',
_extensionMap: [EleventyExtensionMap],
_engineName: 'md',
_engine: [Markdown],
useMarkdown: true
},
inputContent: '---\n' +
'layout: layouts/myLayout1.njk\n' +
'title: My Markdown\n' +
'---\n' +
'\n' +
'# Hello from {{title}}\n',
_config: {
templateFormats: [Array],
pathPrefix: '/',
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'liquid',
dataTemplateEngine: 'liquid',
passthroughFileCopy: true,
htmlOutputSuffix: '-o',
jsDataFileSuffix: '.11tydata',
keys: [Object],
dir: [Object],
filters: {},
handlebarsHelpers: [Object],
nunjucksFilters: [Object],
linters: {},
layoutAliases: {},
passthroughCopies: [Object],
liquidOptions: {},
liquidTags: {},
liquidFilters: [Object],
liquidShortcodes: [Object],
liquidPairedShortcodes: [Object],
nunjucksAsyncFilters: [Object],
nunjucksTags: {},
nunjucksAsyncShortcodes: [Object],
nunjucksShortcodes: [Object],
nunjucksAsyncPairedShortcodes: [Object],
nunjucksPairedShortcodes: [Object],
handlebarsShortcodes: [Object],
handlebarsPairedShortcodes: [Object],
javascriptFunctions: [Object],
pugOptions: {},
ejsOptions: {},
markdownHighlighter: null,
libraryOverrides: {},
dynamicPermalinks: true,
useGitIgnore: true,
dataDeepMerge: true,
watchJavaScriptDependencies: true,
additionalWatchTargets: [],
browserSyncConfig: {},
chokidarConfig: {},
watchThrottleWaitTime: 0,
frontMatterParsingOptions: undefined,
dataExtensions: Map {},
extensionMap: Set {},
quietMode: false,
events: [EventEmitter],
inputDir: './src'
},
frontMatter: {
content: '\n# Hello from {{title}}\n',
data: [Object],
isEmpty: false,
excerpt: ''
},
_layoutKey: 'layouts/myLayout1.njk',
_layout: TemplateLayout {
inputPath: './src/_includes/layouts/myLayout1.njk',
inputDir: './src',
_extensionMap: [EleventyExtensionMap],
dataKeyLayoutPath: 'layouts/myLayout1.njk',
_config: [Object],
_templateRender: [TemplateRender],
inputContent: '---\n' +
'layout: layouts/myLayout2.njk\n' +
'title: My Layout 1\n' +
'---\n' +
'\n' +
'<h2> {{ title }} in Layout 1</h2>\n' +
'\n' +
'{{ content | safe }}\n' +
'\n' +
'<h3>My Data</h3>\n' +
'<pre>\n' +
'{\n' +
' myData.myKey: {{ myData.myKey }}\n' +
'}\n' +
'</pre>',
frontMatter: [Object],
mapCache: [Array],
layoutChain: [Array],
dataCache: [Object]
},
dataCache: {
...
title: 'My Markdown',
page: [Object]
},
computedData: ComputedData {
computed: [Object],
templateStringKeyLookup: [Object],
computedKeys: [Set],
declaredDependencies: [Object],
queue: [ComputedDataQueue]
}
},
inputPath: './src/ocas/my-markdown.md',
fileSlug: 'my-markdown',
filePathStem: '/ocas/my-markdown',
data: {
myData: { myKey: 'My Value' },
...
},
...
layout: 'layouts/myLayout1.njk',
tags: [ 'ocas' ],
parent: 'OCAs',
stage: 'concept',
state: 'open',
type: 'component',
date: 'Last Modified',
eleventyComputed: { eleventyNavigation: [Object] },
title: 'My Markdown',
page: {
date: 2020-12-10T23:28:08.018Z,
inputPath: './src/ocas/my-markdown.md',
fileSlug: 'my-markdown',
filePathStem: '/ocas/my-markdown',
url: '/ocas/my-markdown/',
outputPath: './_site/ocas/my-markdown/index.html'
},
collections: {
...
},
eleventyNavigation: { key: 'My Markdown', parent: 'OCAs' }
},
date: 2020-12-10T23:28:08.018Z,
outputPath: './_site/ocas/my-markdown/index.html',
url: '/ocas/my-markdown/',
templateContent: [Getter/Setter]
}
Question: Is it possible to get the collection item's rendered content (generated output) of each or, any of these:
- my-markdown.md
- my-layout1.njk
- my-layout2.njk
In my case, there's one more final layout for the base page navigation, headers, footers, etc. So looking in _site may not be the best answer since I'd prefer to capture the "content" after a layout is processed.
Thanks in advance for any insight!
@stevenmilstein Hmm. What are you planning on doing with the captured content?
@binyamin I use/embed it in other Content.
Here's what I found.
- yes, use
templateContent - Not sure. I did some peeking around. It's possible that there's something buried in
template._layout. - Same as above
Pay attention, that variables starting with _ (such as _layout) are usually an indicator, that it should be considered „private”.
As in: it can change without any prior notice.
Perhaps worth to fill an issue (like here) if you feel the need for a defined API to that.
@binyamin Yup! That's what I found too. I was hoping there was some hidden attribute [object] that could be parsed.
Thanks for looking
@Ryuno-Ki I suspected the underscore had some special meaning and use _templateContent as a fallback sometimes when it's there. Thanks for the heads-up!
I'm not it's worth creating an Issue for defining an API since I haven't been able to find any remotely related Issues. I created this one hoping there was something like a built-in filter or, eleventyConfig option I was missing out on.
Thanks for your input
@stevenmilstein Hmm. What are you planning on doing with the captured content?
This would also be useful for passing generated HTML to our RSS feeds when part of that HTML generation comes from plugins like eleventy-plugin-embed-everything.
Currently, things like lines with YouTube URLs are transformed into YouTube embed HTML in _site, but that transformation is not reflected in collection.item.templateContent, so an RSS feed that uses that property still shows the unprocessed YouTube URL.
It would be handy to be able to be able to access something like collection.item.generatedHTML instead so the RSS feed content HTML could match the _site HTML exactly.