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

Implement {{loop.cycle(…)}} similar to Jinja #517

Merged
merged 1 commit into from Nov 11, 2021
Merged

Conversation

Kijewski
Copy link
Collaborator

No description provided.

@djc
Copy link
Owner

djc commented Jul 19, 2021

When this was discussed before, I proposed we should make this loop.cycle([1, 2, 3]) to make this more like Rust (where we don't have arbitrary numbers of arguments. What do you think?

@Kijewski
Copy link
Collaborator Author

Sorry, I didn't see the prior discussions, I only saw that is was mentioned in #427. The braces it does look more like rust. The only problem I foresee is that someone might try to use the function like loop.cycle(self.array). What code would you generate in this case?

{
    // This moves the variables out of self:
    let _cycle = self.array;
    _cycle[_cycle.len() % index]
}

{
    // If the variable is used for printing, then this should be fine,
    // but it's used in e.g. an addition, it fails:
    let _cycle = &self.array;
    _cycle[_cycle.len() % index]
}

{
    // This must not be used for e.g. {{ loop.cycle([a(), b(), c()]) }},
    // but I guess you shouldn't use the function like that in any case:
    self.sequence[self.array.len() % index]
}

@djc
Copy link
Owner

djc commented Aug 5, 2021

We take a reference to the array and index into it?

@vallentin
Copy link
Collaborator

vallentin commented Aug 5, 2021

I was just wondering, what would/should happen if you moved loop.cycle into a macro, and called it multiple times in the loop.

Jinja:

{% macro foo() %}
    {{ loop.cycle("A", "B", "C") }}
{% endmacro %}

{% for v in values %}
    {{ foo() }} {{ foo() }} {{ foo() }}
{% endfor %}

I was wondering if it would output AAABBBCCC... or ABCABCABC.... I did a quick test using 2 online "Jinja live parsers". The first one froze, the second one said "'loop' is undefined".

Should Askama support this? If yes, should the output be the former or the latter?

@djc
Copy link
Owner

djc commented Aug 5, 2021

The output needs to be the former. The return value of cycle() only changes with iterations of the loop itself, not with every call of cycle().

@vallentin
Copy link
Collaborator

I only spent a couple of minutes searching, but I wasn't able to find a specific source stating the behavior, thus why I did a quick test. Both behaviors are possible using Jinja's cycler(), so if loop.cycle() is a shorthand for creating a cycler(...) before the loop, and then in the loop doing .next(). Then the output would be ABCABCABC... :)

i.e., if the previous Jinja code (using loop.cycle("A", "B", "C")) is a shorthand of this:

{% set abc = cycler("A", "B", "C") %}

{% macro foo() %}
    {{ abc.next() }}
{% endmacro %}

{% for v in values %}
    {{ foo() }} {{ foo() }} {{ foo() }}
{% endfor %}

@djc
Copy link
Owner

djc commented Aug 5, 2021

Oh, I didn't know that Jinja had that feature. Still, since we're specifically referring to the loop context here, I think we should stick with the semantics mentioned in my previous comment.

@vallentin
Copy link
Collaborator

Still, since we're specifically referring to the loop context here

I agree, with "given loop context". I was just posing the question, so we're all on the same page :)

@Kijewski
Copy link
Collaborator Author

Kijewski commented Aug 5, 2021

I'm not a 100% sure if I like the variant with brackets better, so I didn't squash the commit immediately.

@djc
Copy link
Owner

djc commented Nov 10, 2021

I think the variant with brackets is nice, especially if that means it can accept arbitrary slices.

Would you mind rebasing this (and ideally squashing it)?

@Kijewski
Copy link
Collaborator Author

Thank you! I added one more check if the slice is empty to prevent panics.

@djc djc merged commit cfe83bc into djc:main Nov 11, 2021
@djc
Copy link
Owner

djc commented Nov 11, 2021

Thanks! If anyone wants to follow up with some documentation in the book, that would be great.

@Kijewski Kijewski deleted the pr-loop-cycle branch November 11, 2021 14:37
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

Successfully merging this pull request may close these issues.

None yet

3 participants