Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with passing variables of parent macro to child macro #912

Open
ArmorDarks opened this issue Nov 13, 2016 · 7 comments
Open

Issues with passing variables of parent macro to child macro #912

ArmorDarks opened this issue Nov 13, 2016 · 7 comments

Comments

@ArmorDarks
Copy link

This issues seems to be related to changes of #667. Since Carl has been original author of PR and knows about Jinja2 much more than I do, I kindly ask @carljm to take a look at this issue.

As for now, in Nunjucks 3.0.0 there is no way to pass parameters of parent macro to its child macro.

Take an example:

{% macro Nav(argumentFromParent = 'Im argument from parent!') %}

    {% set setFromParent = 'Im set from parent' %}

    {% macro Item(argumentFromChildwithParentArgument = argumentFromParent, argumentFromChildwithParentSet = setFromParent) %}
      argumentFromParent                  : {{ argumentFromParent }}
      setFromParent                       : {{ setFromParent }}
      argumentFromChildwithParentArgument : {{ argumentFromChildwithParentArgument }}
      argumentFromChildwithParentSet      : {{ argumentFromChildwithParentSet }}
    {% endmacro %}

    {{ Item() }}

{% endmacro %}

As you can see, here I'm trying 4 ways of passing values from parrent macro (Nav), to it's child (Item):

  1. Try read argument from parent directly (argumentFromParent)
  2. Try read set in parent context variable directly (setFromParent)
  3. Try to set argument from parent as default value of childs argument (argumentFromChildwithParentArgument )
  4. Try to set set from parent context as default value of child argument (argumentFromChildwithParentSet)

All those attempts will print follwoing:

argumentFromParent                  : undefined
setFromParent                       : undefined
argumentFromChildwithParentArgument : undefined
argumentFromChildwithParentSet      : undefined

In other words, all attempts to pass variable from parent to child macro will fail.

It seems to me that 3 and 4 methods should work in Jinja2, and thus in Nunjucks too. Otherwise, is it indeed impossible to share values between macros in Jinja2?

@carljm Would you have time to take a look into Jinja2 behavior closer?

@ArmorDarks
Copy link
Author

Hm, this seems to be duplicate of #906

But since my test case is slightly different, I will leave it open for now.

@carljm
Copy link
Contributor

carljm commented Nov 15, 2016

This and #912 are clearly bugs. Don't know if they date from #667 or #791, but either way it looks like just unintended consequences of another fix, due to not having test cases for these cases. Jinja2 behavior is easy to check. Next step would be a PR with at the very least failing test cases.

@ArmorDarks
Copy link
Author

Well, turned out that scope now is so strict, that even global variables won't get into macros.

This

{% set setFromLayout = 'Im set from parent' %}

{% macro NavTest(argumentFromParent = setFromLayout) %}

  setFromLayoutInMacro: {{ setFromLayout }}<br>
  argumentFromParent:   {{ argumentFromParent }}<br>

{% endmacro %}

{{ NavTest() }}

will yield

setFromLayoutInMacro: 
argumentFromParent: 

Which makes macros completely unusable :(

@fdintino
Copy link
Collaborator

@ArmorDarks I'm having a hard time reproducing that. Here's what I see:

var tmpl = [
    "{% set setFromLayout = 'Im set from parent' %}",
    "{% macro NavTest(argumentFromParent = setFromLayout) %}",
    "  setFromLayoutInMacro: {{ setFromLayout }}<br>",
    "  argumentFromParent:   {{ argumentFromParent }}<br>",
    "{% endmacro %}",
    "{{ NavTest() }}"
].join("\n");

console.log(nunjucks.renderString(tmpl));

outputs:




  setFromLayoutInMacro: Im set from parent<br>
  argumentFromParent:   Im set from parent<br>

@ArmorDarks
Copy link
Author

Ah, turned out that that #912 (comment) issue appears only if you do it within {% block %}

{% block name %}
  {% set setFromLayout = 'Im set from parent' %}

  {% macro NavTest(argumentFromParent = setFromLayout) %}

    setFromLayoutInMacro: {{ setFromLayout }}<br>
    argumentFromParent:   {{ argumentFromParent }}<br>

  {% endmacro %}

  {{ NavTest() }}
{% endblock %}

It doesn't work same way for example from my first post in this issue, so it seems to be completely another scopes issue.

@kevinmpowell
Copy link
Contributor

@ArmorDarks or @fdintino any update on this issue? I ran into it today. I can confirm @ArmorDarks clarification that It does only affect the {% block %} scope.

@flaviofl
Copy link

I am having the same issue when using nested for loop

On this example. 'team.players' fails on the child block, but the funny part, it can be used on the HTML inside of that block {{ team.players }}

{% for team in teams %}
    <div>
        <h1>team.title</h1>
        {% for player in team.players %} {# team.players does not work here #}
            <div class="{{ team.players }}"> {# team.players works here #}
                <p>{{ player.name }}</p>
            </div>
        {% endfor %}
    </div>
{% endfor %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants