Skip to content

Helpers cannot be used with other helpers #213

Closed
rragan opened this Issue Dec 28, 2012 · 1 comment

1 participant

@rragan
rragan commented Dec 28, 2012

Currently we have a number of useful helpers (math, size, if, etc.). However since a parameter value cannot be a helper, I can't use @if to test the result of @size for example. Allowing helpers to be used as parameter values leads to some really ugly appearing syntax that I'd rather not write and I'm sure the compiler would rather not digest.

Borrowing from the JSP playbook for something similar (e.g. complex values for a param), we could go two ways:

1) Controlled and limited introduction of variables with very local scope.

{# p1="" p2=""}
{@paramDef key="p1"}
{@size key="array"/}
{/paramDef}
{@paramDef key="p2"}
{@math key="16" method="add" operand="4"/}
{/paramDef}
{@if cond="'{p1}' == '{p2'" }
Equal values
{/if}

The {#} ..{/} is a made up syntax that specifies a local un-named context scope with parameters p1 and p2 available. The use of the empty quotes is purely an example, real values could be supplied. The paramDef helper evaluates its body and assigns the value to the "local" variable named by the parameter. Checking could prevent assigning to any name other than those declared. The values of p1 and p2 can be referenced within the {#} block but cease to exist after exiting the block. In this sense they are exactly like parameter values being passed into a normal section with the exception that the parameter values represent things that are more complex than just a name or a string or a {xx} reference.

By using an existing simple object with one array element, e.g. {#oneElt} ... {/oneElt} I have prototyped this and it works fine, therefore, strictly speaking a syntax change for {#} is not mandatory but it would make the usage clearer. I also tried a variant with a custom helper named {@scope p1=""} in lieu of the custom syntax and that would also suffice.

2) Allow complex parameter values (e.g. more than name, number, ref) to be specified wherever parameters are allowed (sections, partials, helpers). New syntax and compiler support would be needed. This is made up syntax for now.

{@if cond="{mathVal} == '20'}
{mathVal=}
{@math key="16" method="add" operand="4"/}
{/mathVal}
{/if}

{>myPartial p1="abc" p2=user.name}
{p3=}
{@size key=list/}
{/p3}
{/myPartial}

This would invoke myPartial with p1, p2, p3 on the stack. The compiler would extract all {name=} parameter defining code from the body of the partial, evaluate it in the current context (not the context after the partial is invoked though this is debatable) and put it on the stack.

I would like to see this work for partials, helpers and sections but it would require allowing partials to have bodies -- a matter which I think would prove very helpful in other regards.

There may be yet other approaches but the current situation is such that partials really are not very useful except for limited cases, e.g using @size I can print out "You have n purchases" but I can't pass the length of the purchases array to anything else.

@rragan
rragan commented Oct 26, 2013

I'm satisfied with a helper-based solution I have for this.

@rragan rragan closed this Oct 26, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.