Open fusepilot opened 9 years ago
It would be difficult to implement this in practice, since if
is always translated to an if () {}
in runtime JS code, but blocks for extend
are interpreted at compile time.
This differs from mixins, which are literally wrapped JavaScript functions. When you +mixinName('adsf')
, you are actually calling a function at render time, so you can check if block
(→if (block)
) at render time.
Sure, I didn't mean to imply that the final syntax should be exactly as I wrote above. Whatever is appropriate to achieve the resulting functionallity.
And are you suggesting there's a clean way to do this with mixins? If so, I'm not seeing how without parsing the AST at runtime. Which seems a bit much to achieve this simple 'check'.
And are you suggesting there's a clean way to do this with mixins?
No. mixins are simply not suited for this purpose.
I also toyed with the idea of wrapping the extend block with a mixin (like this:
mixin related
if block
section.related
h2 Related Products
.content
block
html
body
+related
block related
but that didn't work out since block
is always defined in the mixin and no return code is emitted.
If so, I'm not seeing how without parsing the AST at runtime. Which seems a bit much to achieve this simple 'check'.
I agree.
Just for fun, I did finally get something extremely ugly and hacky working (DO NOT USE THIS):
//- layout.jade
doctype html
mixin optional(cl, desc)
//- replace proper buffer with a dummy one to test if block is empty or not
- var oldBuf = buf
- buf = []
block
- var blockContent = buf.join('').trim()
- buf = oldBuf
if blockContent
section(class=cl)
h2= desc
.content
block
html
body
+optional('features', 'Features')
block features
+optional('related', 'Related Products')
block related
//- extend.jade
extends layout.jade
block features
ul
li Supports Jade templating engine.
li Blazing-fast.
<!DOCTYPE html>
<html>
<body>
<section class="features">
<h2>Features</h2>
<div class="content">
<ul>
<li>Supports Jade templating engine.</li>
<li>Blazing-fast.</li>
</ul>
</div>
</section>
</body>
</html>
But it's subpar and uses knowledge of Jade internals, so do NOT use this.
So, Jade is extremely opinionated, which contributes to its prettiness in templates that fit its standards and extreme ugliness otherwise.
In real world, you might want to just put the headings and .content
into the block itself. It will save you a lot of hassle.
Interesting. Thank you for the insight.
Will 2.0 implement anything that would perhaps make this more conise/easier?
Also, just to ensure clairity, I'm only looking for an functional equivalent to Rail's content_for?
.
http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for-3F http://stackoverflow.com/questions/193838/rails-check-if-yield-area-is-defined-in-content-for
We could do something like this without too much difficulty. This is the reverse problem of dynamic include
. i.e. it is impossible to use a value that is only known at runtime and then use it to change behaviour at compile time. It is possible to take a value that is only known at compile time, and make that available at runtime though.
We could, for example, take a regexp like /\bblock ([a-zA-Z_0-9]+)\b/
which would never match any valid JavaScript code, and replace all occurrences of that with either true
or false
depending on the child templates. This could be done at compile time. This would certainly be a fun/interesting academic exercise.
What I'm less sure of is whether this is a good idea. We do support multiple inheritance, which seems like it should cover this use case quite nicely. i.e. instead of:
doctype html
html
if block features
section.features
h2 Features
.content
block features
if block related
section.related
h2 Related Products
.content
block related
just do:
doctype html
html
block content
extends ./layout.jade
block content
section.features
h2 Features
.content
block features
extends ./layout.jade
block content
section.related
h2 Related Products
.content
block related
Then just extend either layout-features.jade
or layout-related.jade
as appropriate.
Hey guys. I am new to Jade but this mixin/block combination worked out for me when trying to wrap a block only if it has contents:
// mixins.jade
mixin content
if block
.content-wrapper
block
// layout.jade
doctype
html
block content
// example.jade
extends layout
block content
+content
p This will be wrapped.
@fridays, no, we are talking about detecting inheritance blocks here (i.e. if block content
in your example, in layout.jade
).
any news on this? This would be so helpful. Would avoid a lot of file overhead
As temporary solution, maybe should use mixin like that :
mixin layout(isHeader, isContent, isFooter)
if isHeader
block header
if isContent
block content
if isFooter
block footer
+layout(true, true, false)
block header
h1 Hello
block content
p hi
I would like to be able to have defined blocks show only if they have content provided to them. Something like:
I'm currently working around this by using jade-lexer and jade-parser to find all defined NamedBlocks and provide them as locals in a object called blocks. I can use this like:
Not really ideal. It seems like you should be able to check if the blocks have been defined out of box.