diff --git a/django_unicorn/templatetags/unicorn.py b/django_unicorn/templatetags/unicorn.py index 4ef4dd25..04e9c442 100644 --- a/django_unicorn/templatetags/unicorn.py +++ b/django_unicorn/templatetags/unicorn.py @@ -52,17 +52,21 @@ def unicorn(parser, token): args = [] kwargs = {} + unparseable_kwargs = {} for arg in contents[2:]: try: - parsed_kwarg = parse_kwarg(arg) + parsed_kwarg = parse_kwarg(arg, raise_if_unparseable=True) kwargs.update(parsed_kwarg) except InvalidKwargError: # Assume it's an arg if invalid kwarg and kwargs is empty if not kwargs: args.append(arg) + except ValueError: + parsed_kwarg = parse_kwarg(arg, raise_if_unparseable=False) + unparseable_kwargs.update(parsed_kwarg) - return UnicornNode(component_name, args, kwargs) + return UnicornNode(component_name, args, kwargs, unparseable_kwargs) class UnicornNode(template.Node): @@ -71,10 +75,12 @@ def __init__( component_name: FilterExpression, args: Optional[List] = None, kwargs: Optional[Dict] = None, + unparseable_kwargs: Optional[Dict] = None, ): self.component_name = component_name self.args = args if args is not None else [] self.kwargs = kwargs if kwargs is not None else {} + self.unparseable_kwargs = unparseable_kwargs if unparseable_kwargs is not None else {} self.component_key = "" self.parent = None @@ -92,9 +98,9 @@ def render(self, context): resolved_arg = template.Variable(value).resolve(context) resolved_args.append(resolved_arg) - resolved_kwargs = {} + resolved_kwargs = self.kwargs.copy() - for key, value in self.kwargs.items(): + for key, value in self.unparseable_kwargs.items(): try: resolved_value = template.Variable(value).resolve(context) @@ -113,8 +119,6 @@ def render(self, context): except TypeError: resolved_kwargs.update({key: value}) except template.VariableDoesNotExist: - resolved_kwargs.update({key: value}) - if value.endswith(".id"): pk_val = value.replace(".id", ".pk") @@ -123,7 +127,7 @@ def render(self, context): except TypeError: resolved_kwargs.update({key: value}) except template.VariableDoesNotExist: - resolved_kwargs.update({key: value}) + pass if "key" in resolved_kwargs: self.component_key = resolved_kwargs.pop("key") diff --git a/django_unicorn/views/__init__.py b/django_unicorn/views/__init__.py index 79efa408..823cd314 100644 --- a/django_unicorn/views/__init__.py +++ b/django_unicorn/views/__init__.py @@ -256,6 +256,7 @@ def _process_component_request(request: HttpRequest, component_request: Componen partial_found = True break + # Sort data so it's stable component_request.data = {key: component_request.data[key] for key in sorted(component_request.data)} result = { diff --git a/example/www/templates/www/index.html b/example/www/templates/www/index.html index 69566ad0..c0c27f75 100644 --- a/example/www/templates/www/index.html +++ b/example/www/templates/www/index.html @@ -5,10 +5,15 @@

Index

- + - + -{% unicorn 'unicorn.components.hello_world.HelloWorldView' %} + +{% unicorn 'unicorn.components.hello_world.HelloWorldView' name=abcdf %} {% endblock content %} diff --git a/tests/templatetags/test_unicorn_render.py b/tests/templatetags/test_unicorn_render.py index 16ecdec0..b84254a7 100644 --- a/tests/templatetags/test_unicorn_render.py +++ b/tests/templatetags/test_unicorn_render.py @@ -165,6 +165,18 @@ def test_unicorn_render_kwarg(): assert "tested!" in actual +def test_unicorn_render_invalid_kwarg(): + token = Token( + TokenType.TEXT, + "unicorn 'tests.templatetags.test_unicorn_render.FakeComponentKwargs' test_kwarg=tested", + ) + unicorn_node = unicorn(Parser([]), token) + context = {} + actual = unicorn_node.render(Context(context)) + + assert "None" in actual + + def test_unicorn_render_context_variable(): token = Token( TokenType.TEXT,