kalamuna / metalsmith-jstransformer

Metalsmith JSTransformers Plugin
http://npm.im/metalsmith-jstransformer
MIT License
7 stars 9 forks source link

Layouts location meaning #17

Closed ycherniavskyi closed 7 years ago

ycherniavskyi commented 7 years ago

In #9 I read that process layouts from src/layouts is design concept. Could you please explain what is the reason of this decision? What advantages does it give?

RobLoach commented 7 years ago

Just in Metalsmith's src/layouts directory. You can change it. Any other good default that would be good?

https://github.com/RobLoach/metalsmith-jstransformer#configuration

ycherniavskyi commented 7 years ago

I am migrating form metalsmith-layouts to metalsmith-jstransformer. So for metalsmith-layouts my layouts currently located outside src folder, but for metalsmith-layouts I need to move them into src folder, because your plugin grub layouts from metalsmith files array. And as result with .layoutPattern configuration I can change directory only within src folder.

That is why, it's interesting, what is the reason of this decision? Why don't your plugin read layouts separate from metalsmith files read?

ycherniavskyi commented 7 years ago

Just now was hit by this behavior and default configuration of .pattern = '**' and .layoutPattern = 'layouts/**'. With next example, you always get error: src/layouts/test.pug

= date.format()
!= contents

src/index.md

---
layout: layouts/test.pug
data: <Moment.js object initialized by some metalsmith plugin>
---
Some text.

Error

[16:36:14] TypeError: metalsmith_test/src/layouts/test.pug:1
  > 1| p= date.format()
    2| != contents

Cannot read property 'format' of undefined
    at Object.eval (eval at wrap (metalsmith_test/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:6:61)
    at Object.template [as fn] (eval at wrap (metalsmith_test/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:8:77)
    at metalsmith_test/node_modules/jstransformer/index.js:314:30
    at tryCallOne (metalsmith_test/node_modules/promise/lib/core.js:37:12)
    at metalsmith_test/node_modules/promise/lib/core.js:123:15
    at flush (metalsmith_test/node_modules/asap/raw.js:50:29)
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickDomainCallback (internal/process/next_tick.js:122:9)

With default configuration during 'Render all individual content' phase, current implementation also tries to render src/layouts/test.pug and gets error because this file doesn't have date metadata.

RobLoach commented 7 years ago

That is why, it's interesting, what is the reason of this decision? Why don't your plugin read layouts separate from metalsmith files read?

I think this is a design decision. I think everything that's processed by metalsmith should be in the src directory. The benefits out of this are that you can use YAML front-matter in the layouts, pre-compile them for better performance, and even mix them in with the content, if you really wanted.

This isn't stopping you from using something like metalsmith-assets to copy the assets in to have them process with metalsmith-jstransformer though. They just need to become part of the files array before it goes through. Means the plugin doesn't have to read them twice.

gets error because this file doesn't have date metadata.

Did you move the Moment.js metalsmith plugin before metalsmith-jstransformer? The object isn't there, leads me to believe it wasn't created yet. In your layout, you're using data rather then date. Intentional?

ycherniavskyi commented 7 years ago

Thank you for detailed explanation. It is clear now.

As for my error. First yes data is typo in my comment, in code it is date. The reason of this error is trying to compile layout file as content in processFile function and because it isn't have date property in metadata, pug throws error. I fix it by set more strict .pattern configuration parameter.

RobLoach commented 7 years ago

Very cool :+1:

What was the new pattern that you used? Out of curiosity.

ycherniavskyi commented 7 years ago

Because I consider metalsmith-jstransformer convention my contest file name pattern is <name>.html.<transformer> and layout file name pattern is <name>.<transformer>, so for .pattern configuration parameter currently I use **.html*.