Open dillonbheadley opened 8 years ago
Right now there's no functionality for namespacing metadata under a single key like that. I guess I could build in a function similar to the namespace
option in metalsmith-matters
. Then you'd be able to accomplish that by using multiple copies of this plugin in succession, like so:
{
"frontmatter": false,
"plugins": [
{"metalsmith-metafiles": {}},
{"metalsmith-metafiles": {
"postfix": ".books.meta",
"namespace": "books"
}},
// Other plugins...
]
}
Hmmm interesting... I don't like how you would have to manually declare each namespace though. I had thrown together a simple plugin to do something similar with a markdown file:
var metaMarkdown = function(files, metalsmith, done) {
// works like: target.metaname.meta.md
Object.keys(files).forEach(function(file){
var basename = path.basename(file);
var dirname = path.dirname(file);
if (basename.indexOf('.meta.') > -1) {
var metaFile = files[file];
var targetFile = basename.split('.meta.')[0];
var metaName = targetFile.split('.')[1] || '';
targetFile = targetFile.split('.')[0];
dirname == "." ? dirname = "" : '';
var hostFile = files[dirname+targetFile+".jade"];
if (hostFile) {
hostFile.page = hostFile.page || {};
for (set in metaFile) {
if (metaName) {
hostFile.page[metaName] = hostFile.page[metaName] || {};
hostFile.page[metaName][set] = metaFile[set]
} else {
hostFile.page[set] = metaFile[set]
}
}
delete files[file];
Object.assign(files[dirname+targetFile+".jade"], hostFile)
}
}
});
done();
};
this looks for a matching base name and adds the parsed file as a key. So in index.html
, index.meta.md
:
---
title: This is a test
---
# Some content
would be available as page.title
and page.content
. And index.hero.meta.md
:
---
title: I'm the hero
---
## Hero content
Is available as page.hero.title
and page.hero.content
.
Kind of makes a Markdown CMS of sorts...
I've set it up just to work with .jade files via markdown-in-place. Could be fleshed out a bit. Thoughts?
Actually now that I think about it, you could do this with a custom parser:
var metafiles = require('metalsmith-metafiles');
var yaml = require('js-yaml');
Metalsmith(__dirname)
.frontmatter(false)
.use(metafiles({
parsers: {
".json": false, // Disable using JSON metadata files
".yaml": function(content, options) { // Custom parser
let metadata = yaml.safeLoad(content, {filename: options.path});
// Find namespace based on `options.path`
return {[namespace]: metadata}
},
}
}))
.use(/* Other plugin */)
.build(function(err) {
if (err) throw err;
});
That's great! Could I also use Markdown files with a custom parser like that?
In theory, yes. Note though that metalsmith-metafiles
parsers can't access metadata added to the meta files, only their contents, so if you want to include attributes from frontmatter you'd have to run metalsmith-metafiles
before parsing the frontmatter (e.g. disable the built-in frontmatter parsing) and have your custom parser parse the frontmatter itself.
Ah I see. Ok good to know.
I've started testing this out and I'm getting this error:
Could not find main file index.jade.hero for metadata file index.jade.hero.meta.md
Seems like it won't take a file with another name segment in it.
Oh, darn. Yeah you're right; I should have realized that would happen. Not sure why I didn't. The names of the metadata files are fixed...
To be honest, your use case seems to be a bit outside the scope of what metalsmith-metafiles
was originally intended to do. I can't really see myself adding functionality to support this natively, but I am open to adding options to expand the flexibility of metalsmith-metafiles
to make it possible for you to use metalsmith-metafiles
to do this yourself.
My current thought is to add support for some kind of custom matcher object for metadata files, so you could then implement this functionality yourself. Basically I'd be letting you specify your own MetafileMatcher
class (with some changes to simplify the API). Does that sound reasonable to you?
Hi there! Is it possible to have multiple metafiles pointing to a single file? For example:
index.html
is the "host file".index.html.meta.json
is generic metadata.index.html.books.meta.json
would be found under thebooks
key for theindex.html
file. Does that make sense?