Skip to content

Commit a1f3c03

Browse files
author
Andres Vargas
committed
refactor rewire
1 parent d28fdde commit a1f3c03

File tree

6 files changed

+213
-84
lines changed

6 files changed

+213
-84
lines changed

bs-config.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
2+
/*
3+
|--------------------------------------------------------------------------
4+
| Browser-sync config file
5+
|--------------------------------------------------------------------------
6+
|
7+
| For up-to-date information about the options:
8+
| http://www.browsersync.io/docs/options/
9+
|
10+
| There are more options than you see here, these are just the ones that are
11+
| set internally. See the website for more info.
12+
|
13+
|
14+
*/
15+
module.exports = {
16+
"ui": {
17+
"port": 3001
18+
},
19+
"files": [
20+
"**/*.html",
21+
],
22+
"watchEvents": [
23+
"change", "add"
24+
],
25+
"watch": true,
26+
"ignore": [],
27+
"single": false,
28+
"watchOptions": {
29+
"ignoreInitial": true
30+
},
31+
"server": false,
32+
"proxy": "localhost:8000",
33+
"port": 3000,
34+
"middleware": false,
35+
"serveStatic": [],
36+
"ghostMode": {
37+
"clicks": true,
38+
"scroll": true,
39+
"location": true,
40+
"forms": {
41+
"submit": true,
42+
"inputs": true,
43+
"toggles": true
44+
}
45+
},
46+
"logLevel": "info",
47+
"logPrefix": "Browsersync",
48+
"logConnections": false,
49+
"logFileChanges": true,
50+
"logSnippet": true,
51+
"rewriteRules": [],
52+
"open": "local",
53+
"browser": "default",
54+
"cors": false,
55+
"xip": false,
56+
"hostnameSuffix": false,
57+
"reloadOnRestart": false,
58+
"notify": true,
59+
"scrollProportionally": true,
60+
"scrollThrottle": 0,
61+
"scrollRestoreTechnique": "window.name",
62+
"scrollElements": [],
63+
"scrollElementMapping": [],
64+
"reloadDelay": 0,
65+
"reloadDebounce": 500,
66+
"reloadThrottle": 0,
67+
"plugins": [],
68+
"injectChanges": true,
69+
"startPath": null,
70+
"minify": true,
71+
"host": null,
72+
"localOnly": false,
73+
"codeSync": true,
74+
"timestamps": true,
75+
"clientEvents": [
76+
"scroll",
77+
"scroll:element",
78+
"input:text",
79+
"input:toggles",
80+
"form:submit",
81+
"form:reset",
82+
"click"
83+
],
84+
"socket": {
85+
"socketIoOptions": {
86+
"log": false
87+
},
88+
"socketIoClientConfig": {
89+
"reconnectionAttempts": 50
90+
},
91+
"path": "/browser-sync/socket.io",
92+
"clientPath": "/browser-sync",
93+
"namespace": "/browser-sync",
94+
"clients": {
95+
"heartbeatTimeout": 5000
96+
}
97+
},
98+
"tagNames": {
99+
"less": "link",
100+
"scss": "link",
101+
"css": "link",
102+
"jpg": "img",
103+
"jpeg": "img",
104+
"png": "img",
105+
"svg": "img",
106+
"gif": "img",
107+
"js": "script"
108+
},
109+
"injectNotification": false
110+
};

core/templates/counter.livewire.html

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
<div style="text-align: center">
2-
3-
4-
52
<button class="button is-primary is-light is-large" wire:click="increment">+</button>
63
<h1 class="title" >{{ count }}</h1>
74
<button class="button is-primary is-light is-large" wire:click="decrement">-</button>

core/views.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def mount(self, **kwargs):
2424

2525

2626
class CounterLivewire(LivewireComponent):
27+
template_name="counter.livewire.html"
2728
count = 2
2829

2930
def decrement(self, *args):
@@ -33,6 +34,7 @@ def increment(self, *args):
3334
self.count += 1
3435

3536

37+
3638
class HelloworldLivewire(LivewireComponent):
3739
message = "Hellowwwww mundo!"
3840

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from django import template
22
from livewire.views import LivewireComponent
33
from livewire.utils import instance_class
4+
45
register = template.Library()
56

7+
68
@register.inclusion_tag("livewire_scripts.html", takes_context=True)
79
def livewire_scripts(context):
810
return context
911

12+
1013
@register.simple_tag(takes_context=True)
11-
def livewire(context, component,**kwargs):
14+
def livewire(context, component, **kwargs):
1215
livewire_component = instance_class(component, **kwargs)
13-
return livewire_component.render_initial()
16+
return livewire_component.render_to_templatetag()

livewire/utils.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@
66
from django.conf import settings
77
import random
88
import string
9-
import json
109
import importlib
11-
import htmlement
12-
import xml.etree.ElementTree as ET
1310
import re
1411

1512

13+
IGNORE = ("id", "template_name", "request")
14+
15+
1616
def get_vars(instance):
1717
props = set()
1818
for prop in dir(instance):
19-
if not callable(getattr(instance, prop)) and not prop.startswith("__") \
19+
if not callable(getattr(instance, prop)) and \
20+
not "__" in prop and \
21+
not prop in IGNORE \
2022
and not prop.startswith("_LivewireComponent"):
2123
props.add(prop)
2224
return props

livewire/views.py

Lines changed: 90 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,76 +20,47 @@ def livewire_message(request, component_name):
2020
inst = instance_class(component_name)
2121
if request.method == "POST":
2222
inst.parser_payload(request)
23-
return JsonResponse(inst.render(request), safe=False)
23+
return JsonResponse(inst.render(), safe=False)
2424

2525

26-
class LivewireComponent(object):
27-
__id = None
28-
__request = None
2926

30-
def __init__(self, **kwargs):
31-
self.__kwargs = kwargs
32-
33-
def get_component_name(self):
34-
name = self.__class__.__name__.replace("Livewire", "")
35-
name = snakecase(name)
36-
return name
37-
38-
def get_dom(self):
39-
context = self.get_context()
40-
log.debug(context)
41-
return self._render_component(context)
42-
43-
def fill(
44-
self, context
45-
): # Livewire Compatility https://laravel-livewire.com/docs/properties
46-
self.update_context(context)
47-
48-
def get_context(self):
49-
kwargs = self.__kwargs
50-
mount_result = {}
51-
# call mount if exists
52-
if hasattr(self, "mount") and callable(self.mount): # Livewire Compatility
53-
mount_result = self.mount(**kwargs)
54-
55-
params = get_vars(self)
56-
for property in params:
57-
mount_result[property] = getattr(self, property)
58-
return mount_result
59-
60-
def get_response(self): # TODO: chnge to use render method on component view
61-
dom = self.get_dom()
62-
json_response = {
63-
"id": self.__id,
64-
"name": self.get_component_name(),
65-
"dom": dom,
66-
"fromPrefetch": "",
67-
"redirectTo": "",
68-
"children": [],
69-
"dirtyInputs": [],
70-
"data": self.get_context(),
27+
class LivewireTemplateTag:
28+
def render_to_templatetag(self):
29+
self.id = get_id()
30+
component = self.get_component_name()
31+
context = self.get_context_data()
32+
initial_data = {
33+
"id": self.id,
34+
"name": component,
35+
"redirectTo": False,
36+
"events": [],
7137
"eventQueue": [],
7238
"dispatchQueue": [],
73-
"events": [],
74-
"checksum": "c24",
39+
"data": context,
40+
"children": {},
41+
"checksum": "9e4c194bb6aabf5f1", # TODO: checksum
7542
}
76-
if hasattr(self, "updates_query_string"):
77-
json_response.update({'updatesQueryString': self.updates_query_string})
78-
return json_response
43+
context["initial_data"] = initial_data
44+
component_template = self.get_template_name()
45+
return self.render_component(component_template, context)
46+
47+
class LivewireProcessData:
48+
49+
def fill(self, context): # Livewire Compatility https://laravel-livewire.com/docs/properties
50+
self.update_context(context)
7951

8052
def update_context(self, data_context):
8153
for key, value in data_context.items():
8254
setattr(self, key, value)
83-
84-
context = self.get_context()
55+
context = self.get_context_data()
8556
if data_context:
8657
context.update(data_context)
8758
return context
8859

8960
def parser_payload(self, request):
90-
self.__request = request
61+
self.request = request
9162
payload = json.loads(request.body)
92-
self.__id = payload.get("id")
63+
self.id = payload.get("id")
9364
action_queue = payload.get("actionQueue", [])
9465
for action in action_queue:
9566
action_type = action.get("type")
@@ -111,36 +82,80 @@ def parser_payload(self, request):
11182
data[action_payload["name"]] = action_payload["value"]
11283
self.update_context(data)
11384

114-
# TODO: chnge to use render method on component view
115-
def render(self, request):
116-
response = self.get_response()
117-
return response
11885

119-
def _render_component(self, context, initial_data={}):
120-
component_name = self.get_component_name()
86+
class LivewireComponent(LivewireTemplateTag, LivewireProcessData):
87+
id = None
88+
89+
def __init__(self, **kwargs):
90+
for key, value in kwargs.items():
91+
setattr(self, key, value)
92+
93+
def get_component_name(self):
94+
name = self.__class__.__name__.replace("Livewire", "")
95+
name = snakecase(name)
96+
return name
97+
98+
def get_template_name(self):
99+
return self.template_name
100+
101+
102+
def get_context_data(self):
103+
mount_result = {}
104+
# call mount if exists
105+
if hasattr(self, "mount") and callable(self.mount): # Livewire Compatility
106+
mount_result = self.mount()
107+
108+
params = get_vars(self)
109+
for property in params:
110+
mount_result[property] = getattr(self, property)
111+
return mount_result
112+
113+
def get_dom(self):
114+
context = self.get_context_data()
115+
template_name = self.get_template_name()
116+
return self.render_component(template_name, context)
117+
118+
def render(self, context={}):
119+
"""
120+
A Livewire component's render method gets called on the initial page load AND every subsequent component update.
121+
122+
"""
123+
template_name = self.get_template_name()
124+
return self.view(template_name, context)
125+
126+
def view(self, template_name, context):
127+
dom = self.get_dom()
128+
return self.render_to_response(template_name, dom)
129+
130+
def render_component(self, component_template, context={}):
131+
initial_data = context.get("initial_data")
132+
if initial_data:
133+
del context["initial_data"]
121134
component_render = render_to_string(
122-
f"{component_name}.livewire.html", context=context
135+
component_template, context=context
123136
)
124137
root = htmlement.fromstring(component_render).find("div")
125-
root.set("wire:id", self.__id)
138+
root.set("wire:id", self.id)
126139
if initial_data:
127140
root.set("wire:initial-data", json.dumps(initial_data))
128141
res = ET.tostring(root)
129142
return mark_safe(smart_str(res))
130143

131-
def render_initial(self):
132-
self.__id = get_id()
133-
component = self.get_component_name()
134-
context = self.get_context()
135-
initial_data = {
136-
"id": self.__id,
137-
"name": component,
138-
"redirectTo": False,
139-
"events": [],
144+
def render_to_response(self, template_name, dom): # TODO: chnge to use render method on component view
145+
json_response = {
146+
"id": self.id,
147+
"name": self.get_component_name(),
148+
"dom": dom,
149+
"fromPrefetch": "",
150+
"redirectTo": "",
151+
"children": [],
152+
"dirtyInputs": [],
153+
"data": self.get_context_data(),
140154
"eventQueue": [],
141155
"dispatchQueue": [],
142-
"data": context,
143-
"children": {},
144-
"checksum": "9e4c194bb6aabf5f1", # TODO: checksum
156+
"events": [],
157+
"checksum": "c24",
145158
}
146-
return self._render_component(context, initial_data=initial_data)
159+
if hasattr(self, "updates_query_string"):
160+
json_response.update({'updatesQueryString': self.updates_query_string})
161+
return json_response

0 commit comments

Comments
 (0)