feat: list and dict literals in tags + fix tag parser #898
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Following up on #872, because, frankly, it was fun to solve 😄
This PR refactors the tag parser, which turns Django's template tag content of e.g.
{% component key=value key2="abc def" / %}
into an AST which can be worked with downstream.
This PR fixes the bug in In-template component input that has filter(s) with whitespace don't work #894 - after this PR, it will be possible to have whitespace around filters and translation syntax:
{% component key=_( "hello" ) key2="abc def" | lower / %}
I added support for defining list and dict literals as inputs, and allowing to spread variables into those literal lists and dicts.
I then took this idea to its logical conclusion, allowing nested lists, dicts, etc. So the syntax works as follows:
Supported syntax:
val
,key
key=val
,key2='val2 two'
"my string"
,'my string'
_("my string")
val|filter
,val|filter:arg
[value1, value2]
,key=[value1, [1, 2, 3]]
{"key1": value1, "key2": value2}
,key={"key1": value1, "key2": {"nested": "value"}}
[1, 2, 3,]
,{"key": "value", "key2": "value2",}
...
,*
,**
key=[1, *val, 3]
,key={"key": val, **kwargs, "key2": 3}
{**{"key": val2}, "key": val1}
,[ ...[val1], val2 ]
{% component ...[val1] %}
,{% component ...{"key" val1 } %}
Invalid syntax:
val|...filter
attr={...attrs: "value"}
attr={"key": ...val}
attr=[...val]
,attr={...val}
,attr=[**val]
,attr={*val}
...[1, 2, 3]
,...{"key": "value"}
This tag content is parsed into an AST that looks like this:
NOTE: I didn't make changes to documentation yet. For one, this is already a huge PR. For second, while I updated the parser, as of this PR, users cannot yet use the literal dicts and lists. Or rather, they can write it, but it will be treated as a string. So I plan to make a second PR to update that part and update documentation with it.
Closes #894