Open cmawhorter opened 8 years ago
The workaround here is to wrap any code that directly depends on the result of a uses()
with an if that relies on an undocumented internal:
uses('id', 'home').as('homePage')
var thePage = homePage;
if (!__usesResolved) {
thePage = [ { } ]; // prevents undefined in this pre-render phase (in most cases)
}
Without that wrap, the following throws a render error:
<%= thePage[0].title %>
This also impacts partials because a template only gets re-rendered if it contains uses()
calls. This means if a worked-around template -> layout has a partial that depends on the thePage
value (above), it never gets re-rendered and then never gets the resolved data.
Workaround:
In this situation, wrapping partial like so works around the issue:
<%- __usesResolved ? partial('shared/blog-author', { thePage: thePage }) : '' %>
Removing the double render would eliminate the ability to do dynamic including of data though... which is a pretty significant feature if other content creates render-time references (e.g. yield
).
It's probably possible to keep it as-is with a few improvements to how ejs and partials work. Only rendering a child when it's parent uses
are resolved, for example.
In order to eval the
uses()
calls, template need to be rendered. This means that templates with uses calls are rendered once to interpret those calls, and then re-rendered (with the resolved uses) in order to actually render the content.This means that attempting to access property values of a uses-resolved object directly will result in undefined errors during this initial pre-render even though
<%- print() %>
will display correct output.The errors mentioned in #3 are actually because of this issue.
Instead of building uses into ejs, it might be better to create a new feature here that would eliminate the need to double-render.
Instead of this in the ejs template:
It might be better to invent new markup like:
And then we can just grep for those values and resolve them ahead of the initial render.
This would also allow for a tweak in the signature a bit since I hate this
as()
which is pretty much always required. This is way nicer and easier to immediately understand:<$ homePage = uses('id', 'home') $>