baryshev / ect

Fastest JavaScript template engine with embedded CoffeeScript syntax
http://ectjs.com
MIT License
626 stars 69 forks source link

Pushing to blocks from multiple children #84

Open danschumann opened 10 years ago

danschumann commented 10 years ago

Hello,

I've been using ect for a while and dig its features. For a while, as well, I've been doing <%- @_.unique(@headScripts).join('') %> within my <head />, where @_ is underscore, @headScripts is an array that ends up looking like (after every partial has pushed it's scripts to it [js / css])

// something like this
@headScripts == [
   '<script src="myscript.js"></script>',
   '<script src="other.js"></script>',
   '<link rel="stylesheet" type="text/css" href="/stylesheet.css" />',
];

You see, doing <% block 'head' %> doesn't work because its a gumby character, but moreover, it can only be overridden by one thing and not pushed to ( as far as i know ). PSUEDO CODE( but it probably works )

js.js

renderer.render('posts/index.ect', {headScripts: []});

posts/index.ect

<% extend 'layout' %>
<% @headScripts.push '<script src="/js/posts/index.js"></script>' %>
<% @posts.each (@post) => : %>
  <% include 'posts/index_item.ect' %>
<% end %>

posts/index_item.ect

<% @headScripts.push '<script src="/js/posts/index_item.js"></script>' %>
<%- @post.get('name') %>

layout

<html><head>
  <title><%- @title || 'My Site' %></title>
  <%- @_.unique(@headScripts).join('') %>
</head><body>
  <% content %>
</body></html>

So is there a way (if not--should there be), to have multiple items feeding into one block, such that I could have the same structure I am doing now, so that the main layout can have scripts pushed to it from all child templates?

For me, this functionality is necessary, though i'm a little tired of writing it how I am writing it, since the html needs to be a string. If template gets included into a page, for simplicities sake, I would like that template to include its own javascript, but if it is an index item, it should not include it multiple times, and it should be in the head. So the functionality of using it like this works fine, however the syntax is where I am not fully satisfied and that'd be a feature request of the compiler.

danschumann commented 10 years ago

For now, I've found a new syntax so that I can at least have syntax highlighted things being pushed

<% @headBlocks.push 'core_home_index' %>
<% block 'core_home_index' : %>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<% end %>

Then in the main layout

<% @_.each @headBlocks, (b) =>: %>
  <% content b %>
<% end %>

It seems that though 'core_home_index' looks like a string, it is required to be written out twice(WET), because if it is turned into a variable it does not work with block

The following does NOT work:

<% blockName = 'core_home_index' %>
<% @headBlocks.push blockName %>
<% block blockName : %>...<% end %>
danschumann commented 10 years ago

While it may be true that using requirejs would solve all of my problems, I still am not a huge fan of that library. I prefer all dependencies included in head at load time.