Closed seffw closed 9 years ago
I must add that I just found this: http://blog.krawaller.se/posts/using-master-templates-with-metalsmith/
Excellent addition to the plugin. It does not solve the above issue, but may present an alternative way to get around it.
EDIT: Actually couldn't get this to work (it would not build with this and a master template). Still, potential here.
If I understand what you're looking for, it's a limitation of the templating engine, not the Metalsmith plugin. Have a look a Swig, which has template inheritance out of the box, though I think you can extend hbs to do what you want. http://paularmstrong.github.io/swig/docs/#inheritance
Thanks for the link. I had no success with the modification of the plugin I tried above, so this could be an alternative.
However, the issue i described is not about the particular template. It is that the plugin is not looking in all directories, only the 'template' directory (or any other single directory).
@simplyeffectiveweb The master template functionality described in the blogpost you mentioned is implemented in #21. Did you try that code, or did you recreate it from the blogpost?
Either way, feel free to give a shout if you need help to get it to work!
EDIT: Just reread the blogpost & realised I didn't put any source code in there, so of course you went with the PR code. Sorry, fuzzy memory. :) But as said, would love to help out!
@krawaller Thanks for the info. I'll give this another go. I'm really on-board with what you said:
"With this in place I could get rid of all "header" and "footer" partial invocations throughout my various > Handlebars templates in my static site, which was really nice!"
I'm quickly getting used to metalsmith, node and git (the use of these was all new to me 5 days ago, so bear in mind that I might be doing something wrong).
With the code changes listed in #21, are they included in your master-templates fork? Or do I need to patch these? (if so, I will learn how to patch on Windows).
Yes, #21 contains everything from my fork, no need to patch anything else!
If it is helpful, feel free to peruse the source code for the krawaller blog.
The test cases included in #21 might also give some pointers.
So I think my knowledge of how to do this is lacking. Apologies as it probably a lack of git and metalsmith knowledge.
I've cloned your fork into a 'metalsmith-templates' directory in my source dir.
I did npm intall here (not sure if that is needed).
I've got a master.hbt in the templates folder and
templates = require('../metalsmith-templates'),
.use(templates({
engine: 'handlebars',
directory: './templates',
master:'master.hbt',
pattern: ["*/*/*html","*html"]
}))
in my build.js.
My master.hbt:
{{> start}}
{{{ contents }}}
{{> end}}
Start and End are partials in the default partial location.
The built site is only the markdown, not any templates.
Can't spot anything immediately wrong, but there are numerous opportunities to shoot yourself in the foot. :)
If you push your code to a repo I can help you easier (and without polluting the issue discussion here)!
I have not idea how to do that. Sorry, probably I should learn about git first (I'm not a fan at all, but I guess resistance is futile!)
To add, what I have noticed is changing the directoty: './templates' in build,js to anything makes no difference. So it is therefore not getting that far.
Found a solution I think. Still testing, but seems to work fine with this setting in build.js:
.use(templates({
engine: 'handlebars',
directory: 'templates',
master:'master.hbt'
//pattern: ["*/*/*html","*html"]
}))
For clarification, two differences from your blog post, 'templates' rather than './templates' (this may have been misunderstanding on my part) and commenting out 'pattern: ["//_html","_html"]'.
If the pattern
setting exists, ONLY files matching that will be templated, otherwise all files will (this goes for both master template and individual templates). So by excluding the pattern
setting you will template all files, which likely isn't what you want (since even CSS-files etc will get templated).
What the pattern should be of course depends on how your files are structured. In my case I had an index.html
file in the root which I wanted to template, and then all blogpost and other pages where two levels down (authors/david.md
, tags/react.md
, post/usingmetalsmith.md
, etc). Hence the two patterns in my array, matching all html files in the root as well as all html files two levels down.
That makes perfect sense. Now I get it and have put it back successfully.
My mistake was having .use(markdown()) after .use(templates({
Of course, therefore I could also (assuming only markdown, with native html is not used) pattern: ["/_/_md","md"] with .use(markdown()), I think. Any reason why it should be after markdown has been parsed?
Krawaller, I think I've hit an issue with your template hack.
It appears to have stopped working after an npm upgrade.
I had this error which I thought was due to Metalsmith:
"[TypeError: Object #
(Above does not display correctly here. After '#' is 'Metalsmith' within tags)
But it goes away when I overwrite you template hack with Segmento's original files.
The forked project has no issue queue, so this why I have posted here.
I have to say, this whole metalsmith template situation is a bit of a mess. As a programmer from before github, this fork system, which uses the same same project name and same README below is really confusing.
There are a number of forked metalsmith-templates, and it's not clear why (other then Krawaller's) what the purpose of the fork was.
I miss the Joomla / Drupal clarity of insisting that modules are unique, both in name and purpose.
In theory, you should be able to keep templates along with your content. Just point the templates
option at your source directory, and it will be so. You'll have to work around getting markdown and other plugins to ignore your templates (you don't want your templates processed by content plugins, right?) and probably keep your content files from being processed by the template engine (whichever you choose). You could most likely use the branch
plugin for this, although the result will be quite messy, imho.
Btw, having to create page-specific templates is a shortcoming of the templating engine, rather than the plugin. Have a look at templating engines like Swig or Jade that support inheritance. Although I do agree that treating content files as templates has its benefits and is useful on its own, keeping actual layout templates in separate location has it's merits. (See #22 and mayo/metalsmith-templates.)
Every fork links to its origin, so it's relatively simple to track things back. Unless you have a specific need or instructions to use a fork of a Metalsmith plugin, you should use the original. When you do need to use a fork, you don't need to install the plugins separately/system wide. You can specify the github repo in your package.json
file and npm install
will take care of things in your module/project.
@mayo Thanks for the various bits of info you've provided here and in other related threads.
I've come to the conclusion that half my battle is because of Handlebars and it's attempt to be logic-less. I should have read the background to it first. Personally, for me a bringing in the results of a function (Handlebars) compared to a for loop in the template (jade, eco, swig, etc) is not more or less logic based.
Probably Handlebars would shine within a multi-language system, But I now see that all I was doing was populating my build.js (or any other js helper file, with template specific code). So I would rather that went in the template (especially a template for a static site generator, which by nature is the source of the actual template).
Thanks for the info whcih led to my push towards swig.
Hey thanks for this sorry for the delay. Now that https://github.com/superwolff has split out this plugin into two separate plugins—layouts and in-place—I'm going to deprecate the metalsmith-templates
plugin, so that we can use the simpler ones instead. I'm going to close this PR, but feel free to re-open there!
Added a deprecation notice to the readme.
An advantage of Metalsmith is that it looks at every file, and the developer is free with structure.
However, this plugin does not make that possible (and therefore limits Metalsmith) because it only looks in a single defined directory. In some case the user is forced to make a template per page in the 'templates' folder, rather than a genral layout template and further page templates in an 'src' folder (and including markdown as partials). So far this seems standard in other static site generators I've tried.
I don't really see the point in having the directory option. Why not enable the user to put templates wherever, and continue the Metalsmith trend of freedom with structure? (and I realise this plugin is developed by the Metalsmith developer, which makes this a surprising choice of function)
Shame as this just brought my use of Metalsmith to a stop, and all was going great before that.