forked from markfinger/python-react
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.py
More file actions
121 lines (100 loc) · 3.91 KB
/
Copy pathrender.py
File metadata and controls
121 lines (100 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os
import json
from django.contrib.staticfiles import finders
from django.core.serializers.json import DjangoJSONEncoder
from django.utils.safestring import mark_safe
from optional_django import six
from .exceptions import ComponentSourceFileNotFound, ComponentWasNotBundled
from .services import RenderService
from .conf import settings
from .bundle import bundle_component
from .templates import MOUNT_JS
service = RenderService()
class RenderedComponent(object):
def __init__(self, markup, path_to_source, props, serialized_props, watch_source, bundle, to_static_markup):
self.markup = markup
self.path_to_source = path_to_source
self.props = props
self.serialized_props = serialized_props
self.watch_source = watch_source
self.bundle = bundle
self.to_static_markup = to_static_markup
def __str__(self):
return mark_safe(self.render_markup())
def __unicode__(self):
return mark_safe(unicode(self.render_markup()))
def render_markup(self):
markup = self.markup
if self.bundle and not self.to_static_markup:
template = '<span id="{id}">{markup}</span>'
if six.PY2:
template = unicode(template)
markup = template.format(
id=self.get_container_id(),
markup=markup,
)
return mark_safe(markup)
def render_props(self):
if self.serialized_props:
return mark_safe(self.serialized_props)
return ''
def get_bundle(self):
if not self.bundle:
raise ComponentWasNotBundled(
(
'The component "{path}" was not bundled during the rendering process. '
'Call render_component with `bundle`, `translate`, or `watch_source` '
'keyword arguments set to `True` to ensure that it is bundled.'
).format(path=self.path_to_source)
)
return self.bundle
def get_var(self):
return self.get_bundle().get_library()
def get_container_id(self):
return 'reactComponent-' + self.get_var()
def render_mount_js(self):
return mark_safe(
MOUNT_JS.format(
var=self.get_var(),
props=self.serialized_props or 'null',
container_id=self.get_container_id()
)
)
def render_js(self):
return mark_safe(
'\n{bundle}\n<script>\n{mount_js}\n</script>\n'.format(
bundle=self.get_bundle().render(),
mount_js=self.render_mount_js(),
)
)
def render_component(
# Rendering options
path_to_source, props=None, to_static_markup=None,
# Bundling options
bundle=None, translate=None, watch_source=None,
# Prop handling
json_encoder=None
):
if not os.path.isabs(path_to_source):
absolute_path_to_source = finders.find(path_to_source)
if not absolute_path_to_source:
raise ComponentSourceFileNotFound(path_to_source)
path_to_source = absolute_path_to_source
if not os.path.exists(path_to_source):
raise ComponentSourceFileNotFound(path_to_source)
if watch_source is None:
watch_source = settings.WATCH_SOURCE
bundled_component = None
if bundle or translate or watch_source:
bundled_component = bundle_component(path_to_source, translate=translate, watch_source=watch_source)
path_to_source = bundled_component.get_assets()[0]['path']
if json_encoder is None:
json_encoder = DjangoJSONEncoder
if props is not None:
serialized_props = json.dumps(props, cls=json_encoder)
else:
serialized_props = None
markup = service.render(path_to_source, serialized_props, to_static_markup)
return RenderedComponent(
markup, path_to_source, props, serialized_props, watch_source, bundled_component, to_static_markup
)