Comments (16)
Hi @kylepaulsen - if you haven't already, you may want to go through this pretty carefully: http://www.robinthrift.com/posts/getting-to-know-metalsmith/
from metalsmith.
So I have been going through that tutorial and it has been helpful. However it doesn't have any examples of putting handlebars in a markdown file. Instead, it puts it in a template or partial file. I also tried downloading your source and putting in some handlebars inside one of your markdown files and it was just copied over like plain text instead of being compiled. I don't think I can put handlebars in templates or partials because I want to do something like:
My main template file:
<html>
<head>
...
</head>
<body>
{{{contents}}}
</body>
</html>
Where contents would compile to something like:
<div>
other page specific content here.
</div>
{{#each collections.posts}}
<li>
<h3>{{this.title}}</h3>
<article>{{this.contents}}</article>
</li>
{{/each}}
<div>
some more page specific content.
</div>
And then it would be compiled again to get the final result.
I can edit the source of metalsmith-collections to have it double compile and that works great! But obviously I would prefer to not have to do that. What's the best way to do this?
Thanks a lot for your help!
from metalsmith.
What you are looking for is partials.Handlebars partials docs here http://handlebarsjs.com/reference.html
metalsmith-templates supports partials for handlebars and (I think) all the other supported languages but it isn 't mentioned in the docs. If you have a property in your template data (metadata, page metadata, etc) called 'partials '. It will load them automatically.
Usually you denote a file is a partial by prefixing it with _ , but it is not required.
/src/whatever.md
---
title: Whatever
date: 2012-08-20
template: page.html
topContent: this is the top content
bottomContent: this is the bottom content
---
Whatever body content
/templates/page.html
<html>
<head>
</head>
<body>
{{> _contents}}
</body>
</html>
/templates/_content.html
<div>
{{topContent}}
</div>
<div>
{{{contents}}}
</div>
<div>
{{bottomContent}}
</div>
/build.js
var Metalsmith = require('metalsmith');
var markdown = require("metalsmith-markdown");
var templates = require('metalsmith-templates');
Metalsmith(__dirname)
.clean(true)
.metadata({
partials: {
_contents: '_contents',
}
})
.use(markdown())
.use(templates({engine: 'handlebars'}))
.build();
from metalsmith.
I think what @kylepaulsen was possibly after is doing something like:
---
title: my test
hello_name: World
template: post.html
block: content
---
Hello {{hello_name}}!
I used this a lot when I used Hyde to render my site. The use case above is trivial, but it can be very useful tool with larger files or when rendering html files. The way Hyde dealt with it is rendering the file from markdown to html, and then treated the html as a template itself, and then passing it to the parent template, etc. This implied that file contents would be rendered in a template block rather than variable, which potentially limits the template languages that are available (and consequently, there was a 'default_block' metadata value for this).
Expanding following the example above, the template would be:
<html>
<body>
{% block content %}{% end block %}
</body>
</html>
i.e. The md file contents no longer comes as a {{{ contents }}}
variable because it itself is treated as a template, so the parent template is extended via inheritance. In the case of the source being a html file, this gives you the ability to override or append blocks in parent templates, avoiding article-specific templates. (Eg: parent template defines css block, and contents block. The source file can append it's own css, and generate some content, without extraneous template/partial with css specific to the source file).
from metalsmith.
@mayo That is a much more powerful technique. The only template language I have used with blocks and inheritance is smarty for php. For js i have mostly used handlebars. What other js template languages have blocks and inheritance?
from metalsmith.
@unstoppablecarl I know swig and jade do (and both are supported in consolidate.js, therefore metalsmith-templates), but there were at least two others I ran across when I was looking for templating language to use with Metalsmith.
from metalsmith.
Just out of interest I skimmed through the list of consolidate.js supported templating languages, and the following support block-style inheritance: atpl, dust, ect, Hogan, just, nunjucks, swig and potentially liquor.
from metalsmith.
@kylepaulsen I was looking at the metalsmith-templates code, and you can have access to file's own metadata via the 'inPlace' option passed to the plugin. See metalsmith-templates/test/fixtures/in-place
and the should accept an inPlace option test case.
from metalsmith.
@unstoppablecarl I wrote a sample implementation in mayo/metalsmith-stencils@43a2d0d. It's a bit rough around the corners, but works. I started a discussion at segment-boneyard/metalsmith-templates#22.
from metalsmith.
Hi, I also needed this functionality while developing my website. My plugins are not published or tested yet, however, I feel like this might be useful for the exact scenario @kylepaulsen was posting in the first place so I created a gist here.
szenario:
---
title: HandlebarsCombiMarkdown
customWorld: Universe
---
Hallo {{customWorld}}!
compiles to
<p>Hallo Universe!</p>
from metalsmith.
Hey, @majodev, you can already do that by using inPlace: true
when setting up your template plugin:
var metalsmith = Metalsmith(__dirname);
metalsmith
.use(templates({
"engine": "handlebars",
"inPlace": true
}))
.build();
or check out the 'in-place' test case in metalsmith-templates/test/fixtures/in-place
from metalsmith.
I finally got some more time to work on this. I was able to get what I wanted using partials and templates a lot. I still wish I could just have 1 or 2 "master" templates and have 0 partials and just be able to write handlebars or jade in my content files.
Also @mayo, I tried using inPlace and it worked... except it didn't render through my template anymore. Any idea how to get around that? I started using jade to take advantage of block inheritance however I haven't had much luck.
content file: (projects is a global object in the global metalsmith metadata created from the collections plugin)
---
template: main.html
---
!= projects
main template:
doctype html
html(lang="en")
head
title Metalsmith Test
body
p something
// this prints: != projects
// != contents
// this prints nothing:
block contents
from metalsmith.
(Edit: oops, I confused couple of people that posted comments above, so updating the answer...)
@kylepaulsen inPlace
makes the metadata from front matter available in your template. I wasn't sure about your original question, but interpreted it to mean the same as majodev asked in #75 (comment).
metalsmith-templates does not expose template language specific features (like blocks), so it does not create a contents
block for you. The data from original template will always only be available as a template variable (the lowest common denominator between all the templating libraries).
As for your last question with blocks, if you need the contents to be a block, check my #75 (comment) above. Although this may be handy, it's not always necessary. You can have a single (or couple of) "master" template, and have more sub-templates that live on top of it (both swig and jade support inheritance via extends
). Your content page doesn't necessarily need to be rendered as block, because the template it's using can inherit the master template. There are no partials (as per the strict definition) involved here, because when you extend a template (at least in the above mentioned templating libraries) the template doing the extending can affect and change blocks in the template that's being inherited. For eg. see https://github.com/mayo/oyam.ca/tree/master/templates, base.html
, grid.html
, contents.html
, and/or index.html
- that's plain metalsmith-templates functionality without my mods.
from metalsmith.
Thanks for your example links, @mayo. It got me motivated to really dig into the code to get what I want. I ended up just modifying the template module to do what I want: segment-boneyard/metalsmith-templates#26 . I don't expect it to get merged, but if it does, it might merge conflict with your stuff (which also looks good).
from metalsmith.
@kylepaulsen No worries, although you don't need to modify metalsmith-templates to do what the test case does - see my comment on the push request. My modifications provide somewhat different functionality than yours do - mine wrap the source file in a block, so you can override template blocks within the source file.
from metalsmith.
Closing since it's related to metalsmith-templates
and not core.
from metalsmith.
Related Issues (20)
- MS files should not depend on Object prototype
- Debug not working as expected? HOT 2
- Don't crash on broken symlinks that are ignored HOT 4
- Proposal for metalsmith.get/set() helpers HOT 1
- Metalsmith 2.6 Roadmap HOT 3
- Ordinary html file not recognized as utf-8 encoded, stopping gray-matter to parse YAML HOT 3
- Launch procedure to deprecate @types/metalsmith HOT 2
- Build callback not fired with `watch()` + async plugins HOT 13
- Feature: add encoding: utf-8 property to `File` HOT 1
- Feature: provide metalsmith.on('built')
- Unhandled rejection when using callbacks (i.e. with `.watch(spec)`) HOT 2
- CLI: parse metalsmith.json as front-matter
- UnhandledPromiseRejection when plugins callback with failure HOT 8
- Remove metalsmith.concurrency?
- Feature: metalsmith.run() getter HOT 1
- Reduce ambiguity in config options
- Add Metalsmith.imports method
- Add a new signature to metalsmith.metadata, reading it from a file or directory
- Metalsmith 2.7 roadmap
- metalsmith.use/ match enhancement
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from metalsmith.