From 6b4b3831313dbabb24797e071824cc6419cad42f Mon Sep 17 00:00:00 2001 From: Tal Hadad Date: Wed, 29 Sep 2021 16:55:20 +0300 Subject: [PATCH] Added support for manual resource scripts, with demo. This is the main part of #12 --- .../templates/reactive_example.html | 192 ++++++++++-------- .../templatetags/reactive.py | 40 ++-- 2 files changed, 136 insertions(+), 96 deletions(-) diff --git a/src/django_reactive_framework/templates/reactive_example.html b/src/django_reactive_framework/templates/reactive_example.html index f8bb18c..d6d85e9 100644 --- a/src/django_reactive_framework/templates/reactive_example.html +++ b/src/django_reactive_framework/templates/reactive_example.html @@ -165,12 +165,12 @@

@@ -182,9 +182,7 @@ {%/%} - - - {% #/def first_float=initial_first_float %} @@ -219,7 +224,7 @@
You may - @@ -232,31 +237,35 @@ - {%/%} - + {%#%} {% #/print float_operation==='add'?'+':(float_operation==='substruct'?'-':(float_operation==='multiply'?'*':(float_operation==='divide'?'/':'Error'))) %} {%/%} {%#%} - + {%/%} = {%#%}{% #/print float_operation==='add'?(first_float + second_float):(float_operation==='substruct'?(first_float - second_float):(float_operation==='multiply'?(first_float * second_float):(float_operation==='divide'?(first_float / second_float):(float_operation==='minus'?(-first_float):'Error')))) %}{%/%} -
+{%#%} +{%/%} + + {% #/def test_json={v1: '2', 'v7': '3', nested: {A: 1, B: 2}, arr: [{a:1, b:2}, {c: 3}]} %} @@ -348,11 +357,20 @@ }, 1500); +{% #block %} + {% #/def rand_color='rgb(0,0,255)' %} {% #/def changing_color=True %}
- + +{% #script %} +document.getElementById('toggle_color_button').onclick = function () { + {% #set changing_color %} + !{% #/get changing_color %} + {% /set %} +}; +{% /script %}
{% # %} @@ -366,13 +384,8 @@ {% / %} +{%#%} +{%/%} +{% /block %} + {% #tag div style="padding-top: 5px;" %} You can also have a keyed for loop: @@ -410,7 +426,7 @@ {%#%}
{%/%} {%#%} -
+ New person: {% comment%}An example for self enclosed tags{% endcomment %} {% #/tag input/ type = "text" id="first_name" %} @@ -418,67 +434,20 @@ {%#%}{%/%} {%#%}{%/%} - +
{%/%} -{% comment %} -We put this reactive div as a temporary fix, - since reactive if gets rerender too often, - and destroys the idea about keeping states in the keyed loop (TODO: fix it) -{% endcomment %} {%#%} -
-{% #if len(interactive_people_array)===0 %} -People list is empty! -{% :elif len(interactive_people_array)===1 %} -Exactly one person in the list: -{% :else %} -People list: -{% /if %} -
-{%/%} - - - - - - - - - -{% #for person in interactive_people_array by person.first %} -{% #tag tr %} -{% #tag td %}{% #/print person.first %}{% /tag %} -{% #tag td %}{% #/print person.last %}{% /tag %} -{% #tag td %}{% #/print person.age %}{% /tag %} - - -{% /tag %} -{% /for %} -
First NameLast NameAgeNotesActions
-
- -
-
-
- - -{%#%}{%/%} -{%#%}{%/%} -
-
-{% /tag %} - +{%/%} + +{% comment %} +We put this reactive div as a temporary fix, + since reactive if gets rerender too often, + and destroys the idea about keeping states in the keyed loop (TODO: fix it) +{% endcomment %} +{%#%} +
+{% #if len(interactive_people_array)===0 %} +People list is empty! +{% :elif len(interactive_people_array)===1 %} +Exactly one person in the list: +{% :else %} +People list: +{% /if %} +
+{%/%} + + + + + + + + + +{% #for person in interactive_people_array by person.first %} +{% #tag tr %} +{% #tag td %}{% #/print person.first %}{% /tag %} +{% #tag td %}{% #/print person.last %}{% /tag %} +{% #tag td %}{% #/print person.age %}{% /tag %} + + + +{%#%} + +{%/%} + +{% /tag %} +{% /for %} +
First NameLast NameAgeNotesActions
+
+ +
+
+
+{%#%}{%/%} +{%#%}{%/%} +{%#%}{%/%} +{%#%}{%/%} +
+
+{% /tag %} {% /block %} {% /block %} diff --git a/src/django_reactive_framework/templatetags/reactive.py b/src/django_reactive_framework/templatetags/reactive.py index a07c033..9b25285 100644 --- a/src/django_reactive_framework/templatetags/reactive.py +++ b/src/django_reactive_framework/templatetags/reactive.py @@ -480,19 +480,17 @@ def make_context(self, parent_context: Optional[ReactContext], template_context: @register.tag('#' + ReactScriptNode.tag_name) def do_reactscript(parser: template.base.Parser, token: template.base.Token): bits = tuple(smart_split(token.contents, whitespaces, common_delimiters)) - bits_after = bits[1:] - - var_def = tuple(split_kwargs(bits_after)) - if len(var_def) != 1 or (var_def[0][1] is None): + if len(bits) != 1: raise template.TemplateSyntaxError( - "%r tag requires exactly one aurgument in the form of {name}={val}" % token.contents.split()[0] + "%r tag requires no aurgument!" % token.contents.split()[0] ) # otherwise - var_name, var_val_expression = var_def[0] + nodelist = parser.parse(('/' + ReactScriptNode.tag_name,)) + parser.delete_first_token() - return ReactScriptNode(var_name, parse_expression(var_val_expression)) + return ReactScriptNode(nodelist) @register.tag('#') def do_reactgeneric(parser: template.base.Parser, token: template.base.Token): @@ -571,11 +569,6 @@ def do_reactgeneric(parser: template.base.Parser, token: template.base.Token): 'Found more than one slash (\'/\') which is not in the right place in start tag <..> ' + \ 'while parsimg a reactive generic block {% # %}...{% / %}' ) - - if html_tag == 'script': - raise template.TemplateSyntaxError( - 'Script interactive tag is not supported!' - ) start = start[len(start_parts[0])+1:] nodelist[0].s = start @@ -649,8 +642,23 @@ def do_reactgeneric(parser: template.base.Parser, token: template.base.Token): ) nodelist = None + + if html_tag == 'script': + if self_enclosed: + raise template.TemplateSyntaxError( + 'Script interactive tag cannot be self enclosing!' + ) + # otherwise - return parse_reacttag_internal(html_tag, bits_after, nodelist) + if len(bits) != 1: + raise template.TemplateSyntaxError( + 'Script interactive tag cannot have arguments!' + ) + # otherwise + + return ReactScriptNode(nodelist) + else: + return parse_reacttag_internal(html_tag, bits_after, nodelist) class ReactForNode(ReactNode): tag_name = 'for' @@ -1324,7 +1332,7 @@ class ReactGetNode(ReactNode): class Context(ReactRerenderableContext): def __init__(self, parent, expression: Expression): self.expression: Expression = expression - super().__init__(id='', parent=parent, fully_reactive=False) + super().__init__(id='', parent=parent, fully_reactive=True) def render_html(self, subtree: List) -> str: js_expression, hooks = self.expression.eval_js_and_hooks(self) @@ -1368,7 +1376,7 @@ class Context(ReactContext): def __init__(self, parent, settable_expression: SettableExpression, val_expression: Optional[Expression]): self.settable_expression: SettableExpression = settable_expression self.val_expression: Optional[Expression] = val_expression - super().__init__(id='', parent=parent, fully_reactive=False) + super().__init__(id='', parent=parent, fully_reactive=True) def render_html(self, subtree: List) -> str: if self.val_expression is None: @@ -1460,7 +1468,7 @@ class ReactNotifyNode(ReactNode): class Context(ReactContext): def __init__(self, parent, settable_expression: SettableExpression): self.settable_expression: SettableExpression = settable_expression - super().__init__(id='', parent=parent, fully_reactive=False) + super().__init__(id='', parent=parent, fully_reactive=True) def render_html(self, subtree: List) -> str: output = self.settable_expression.js_notify(self)