Skip to content

Commit 1778d1c

Browse files
committed
render_reactpy_template func
1 parent 7650f13 commit 1778d1c

File tree

5 files changed

+36
-78
lines changed

5 files changed

+36
-78
lines changed

src/reactpy/asgi/standalone.py

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import hashlib
2-
import os
32
import re
43
from collections.abc import Coroutine
54
from dataclasses import dataclass
5+
from datetime import datetime
66
from email.utils import formatdate
77
from logging import getLogger
88
from pathlib import Path
@@ -12,13 +12,9 @@
1212

1313
from reactpy import html
1414
from reactpy.asgi.middleware import ReactPyMiddleware
15-
from reactpy.asgi.utils import (
16-
dict_to_byte_list,
17-
http_response,
18-
replace_many,
19-
vdom_head_to_html,
20-
)
15+
from reactpy.asgi.utils import dict_to_byte_list, http_response, vdom_head_to_html
2116
from reactpy.types import ReactPyConfig, RootComponentConstructor, VdomDict
17+
from reactpy.utils import render_reactpy_template
2218

2319
_logger = getLogger(__name__)
2420

@@ -129,24 +125,16 @@ def match_dispatch_path(self, scope: dict) -> bool:
129125

130126
def process_index_html(self) -> None:
131127
"""Process the index.html and store the results in memory."""
132-
with open(self._index_html_path, encoding="utf-8") as file_handle:
133-
cached_index_html = file_handle.read()
134-
135-
self._cached_index_html = replace_many(
136-
cached_index_html,
137-
{
138-
'from "index.ts"': f'from "{self.parent.static_path}index.js"',
139-
'<html lang="en">': f'<html lang="{self.parent.html_lang}">',
140-
"<head></head>": vdom_head_to_html(self.parent.html_head),
141-
"{path_prefix}": self.parent.path_prefix,
142-
"{reconnect_interval}": "750",
143-
"{reconnect_max_interval}": "60000",
144-
"{reconnect_max_retries}": "150",
145-
"{reconnect_backoff_multiplier}": "1.25",
146-
},
128+
self._cached_index_html = (
129+
"<!doctype html>"
130+
f'<html lang="{self.parent.html_lang}">'
131+
f"{vdom_head_to_html(self.parent.html_head)}"
132+
"<body>"
133+
f'<div id="app"></div>'
134+
f"{render_reactpy_template('app', '', '')}"
135+
"</body>"
136+
"</html>"
147137
)
148138

149139
self._etag = f'"{hashlib.md5(self._cached_index_html.encode(), usedforsecurity=False).hexdigest()}"'
150-
self._last_modified = formatdate(
151-
os.stat(self._index_html_path).st_mtime, usegmt=True
152-
)
140+
self._last_modified = formatdate(datetime.now().timestamp(), usegmt=True)

src/reactpy/asgi/utils.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,6 @@ def check_path(url_path: str) -> str:
4646
return ""
4747

4848

49-
def replace_many(content: str, replacements: dict[str, str]) -> str:
50-
"""Find and replace several key-values, and throw and error if the substring is not found."""
51-
for key, value in replacements.items():
52-
if key not in content:
53-
raise ValueError(f"Could not find {key} in content")
54-
content = content.replace(key, value)
55-
return content
56-
57-
5849
def dict_to_byte_list(
5950
data: dict[str, str | int],
6051
) -> list[tuple[bytes, bytes]]:

src/reactpy/jinja.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@
55

66
from jinja2_simple_tags import StandaloneTag
77

8-
from reactpy.config import (
9-
REACTPY_PATH_PREFIX,
10-
REACTPY_RECONNECT_BACKOFF_MULTIPLIER,
11-
REACTPY_RECONNECT_INTERVAL,
12-
REACTPY_RECONNECT_MAX_INTERVAL,
13-
REACTPY_RECONNECT_MAX_RETRIES,
14-
)
8+
from reactpy.utils import render_reactpy_template
159

1610
try:
1711
import_module("jinja2")
@@ -43,19 +37,4 @@ def render(self, dotted_path: str, *args, **kwargs):
4337
if kwargs:
4438
append_component_path += f"?{urllib.parse.urlencode(kwargs)}"
4539

46-
# TODO: Turn this into a util function and maybe use it for the standalone version too?
47-
return (
48-
f'<div id="{uuid}" class="{class_}"></div>'
49-
'<script type="module" crossorigin="anonymous">'
50-
f'import {{ mountReactPy }} from "{REACTPY_PATH_PREFIX.current}static/index.js";'
51-
"mountReactPy({"
52-
f' mountElement: document.getElementById("{uuid}"),'
53-
f' pathPrefix: "{REACTPY_PATH_PREFIX.current}",'
54-
f' appendComponentPath: "{append_component_path}",'
55-
f" reconnectInterval: {REACTPY_RECONNECT_INTERVAL.current},"
56-
f" reconnectMaxInterval: {REACTPY_RECONNECT_MAX_INTERVAL.current},"
57-
f" reconnectMaxRetries: {REACTPY_RECONNECT_MAX_RETRIES.current},"
58-
f" reconnectBackoffMultiplier: {REACTPY_RECONNECT_BACKOFF_MULTIPLIER.current},"
59-
"});"
60-
"</script>"
61-
)
40+
return render_reactpy_template(uuid, class_, append_component_path)

src/reactpy/templates/index.html

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/reactpy/utils.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from lxml import etree
99
from lxml.html import fromstring, tostring
1010

11+
from reactpy import config
1112
from reactpy.core.vdom import vdom as make_vdom
1213
from reactpy.types import ComponentType, VdomDict
1314

@@ -313,3 +314,23 @@ def _vdom_attr_to_html_str(key: str, value: Any) -> tuple[str, str]:
313314

314315
# Pattern for delimitting camelCase names (e.g. camelCase to camel-case)
315316
_CAMEL_CASE_SUB_PATTERN = re.compile(r"(?<!^)(?=[A-Z])")
317+
318+
319+
def render_reactpy_template(
320+
element_id: str, class_: str, append_component_path: str
321+
) -> str:
322+
return (
323+
f'<div id="{element_id}" class="{class_}"></div>'
324+
'<script type="module" crossorigin="anonymous">'
325+
f'import {{ mountReactPy }} from "{config.REACTPY_PATH_PREFIX.current}static/index.js";'
326+
"mountReactPy({"
327+
f' mountElement: document.getElementById("{element_id}"),'
328+
f' pathPrefix: "{config.REACTPY_PATH_PREFIX.current}",'
329+
f' appendComponentPath: "{append_component_path}",'
330+
f" reconnectInterval: {config.REACTPY_RECONNECT_INTERVAL.current},"
331+
f" reconnectMaxInterval: {config.REACTPY_RECONNECT_MAX_INTERVAL.current},"
332+
f" reconnectMaxRetries: {config.REACTPY_RECONNECT_MAX_RETRIES.current},"
333+
f" reconnectBackoffMultiplier: {config.REACTPY_RECONNECT_BACKOFF_MULTIPLIER.current},"
334+
"});"
335+
"</script>"
336+
)

0 commit comments

Comments
 (0)