Skip to content

Commit fdd7ae7

Browse files
committed
fix custom component template
1 parent d4fd22f commit fdd7ae7

File tree

5 files changed

+75
-72
lines changed

5 files changed

+75
-72
lines changed

reflex/compiler/compiler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _compile_document_root(root: Component) -> str:
5353
"""
5454
document_root_imports = root._get_all_imports()
5555
_apply_common_imports(document_root_imports)
56-
return templates._document_root_template(
56+
return templates.document_root_template(
5757
imports=utils.compile_imports(document_root_imports),
5858
document=root.render(),
5959
)
@@ -93,7 +93,7 @@ def _compile_app(app_root: Component) -> str:
9393
app_root_imports = app_root._get_all_imports()
9494
_apply_common_imports(app_root_imports)
9595

96-
return templates._app_root_template(
96+
return templates.app_root_template(
9797
imports=utils.compile_imports(app_root_imports),
9898
custom_codes=app_root._get_all_custom_code(),
9999
hooks=app_root._get_all_hooks(),
@@ -112,7 +112,7 @@ def _compile_theme(theme: str) -> str:
112112
Returns:
113113
The compiled theme.
114114
"""
115-
return templates._theme_template(theme=theme)
115+
return templates.theme_template(theme=theme)
116116

117117

118118
def _compile_contexts(state: type[BaseState] | None, theme: Component | None) -> str:
@@ -376,7 +376,7 @@ def _compile_components(
376376

377377
# Compile the components page.
378378
return (
379-
templates.COMPONENTS.render(
379+
templates.custom_component_template(
380380
imports=utils.compile_imports(imports),
381381
components=component_renders,
382382
dynamic_imports=dynamic_imports,

reflex/compiler/templates.py

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import json
6-
from collections.abc import Callable, Mapping
6+
from collections.abc import Callable, Iterable, Mapping
77
from typing import TYPE_CHECKING, Any
88

99
from reflex import constants
@@ -86,8 +86,6 @@ def __init__(self) -> None:
8686
"hook_position": constants.Hooks.HookPosition,
8787
}
8888

89-
self.sort_hooks = _sort_hooks
90-
9189

9290
class Template:
9391
"""Template class for f-string based rendering."""
@@ -113,7 +111,6 @@ def render(self, **kwargs) -> str:
113111
# Merge renderer utilities into context
114112
context = {
115113
"const": renderer.const,
116-
"sort_hooks": renderer.sort_hooks,
117114
**renderer.filters,
118115
**kwargs,
119116
}
@@ -212,7 +209,7 @@ def get_import(module: _ImportDict) -> str:
212209
return f'import "{module["lib"]}"'
213210

214211

215-
def _rxconfig_template(app_name: str):
212+
def rxconfig_template(app_name: str):
216213
"""Template for the Reflex config file.
217214
218215
Args:
@@ -232,9 +229,16 @@ def _rxconfig_template(app_name: str):
232229
)"""
233230

234231

235-
def _document_root_template(
236-
*, imports: list[_ImportDict], document: dict[str, Any], **kwargs
237-
):
232+
def document_root_template(*, imports: list[_ImportDict], document: dict[str, Any]):
233+
"""Template for the document root.
234+
235+
Args:
236+
imports: List of import statements.
237+
document: Document root component.
238+
239+
Returns:
240+
Rendered document root code as string.
241+
"""
238242
imports_rendered = "\n".join([_RenderUtils.get_import(mod) for mod in imports])
239243
return f"""{imports_rendered}
240244
@@ -245,7 +249,7 @@ def _document_root_template(
245249
}}"""
246250

247251

248-
def _app_root_template(
252+
def app_root_template(
249253
*,
250254
imports: list[_ImportDict],
251255
custom_codes: set[str],
@@ -335,7 +339,15 @@ def _app_root_template(
335339
"""
336340

337341

338-
def _theme_template(theme: str):
342+
def theme_template(theme: str):
343+
"""Template for the theme file.
344+
345+
Args:
346+
theme: The theme to render.
347+
348+
Returns:
349+
Rendered theme file content as string.
350+
"""
339351
return f"""export default {theme}"""
340352

341353

@@ -412,13 +424,12 @@ def _page_template(**kwargs):
412424
custom_codes = kwargs.get("custom_codes", [])
413425
hooks = kwargs.get("hooks", {})
414426
render_content = kwargs.get("render", "")
415-
sort_hooks = kwargs.get("sort_hooks", _sort_hooks)
416427

417428
custom_code_str = "\n".join(custom_codes)
418429
dynamic_imports_str = "\n".join(dynamic_imports)
419430

420431
# Render hooks
421-
sorted_hooks = sort_hooks(hooks)
432+
sorted_hooks = _sort_hooks(hooks)
422433
hooks_code = ""
423434
for hook_list in sorted_hooks.values():
424435
for hook, _ in hook_list:
@@ -438,11 +449,19 @@ def _page_template(**kwargs):
438449
}}"""
439450

440451

441-
def _package_json_template(**kwargs):
452+
def package_json_template(
453+
scripts: dict[str, str],
454+
dependencies: dict[str, str],
455+
dev_dependencies: dict[str, str],
456+
overrides: dict[str, str],
457+
):
442458
"""Template for package.json.
443459
444460
Args:
445-
**kwargs: Template context variables including dependencies, dev_dependencies, scripts.
461+
scripts: The scripts to include in the package.json file.
462+
dependencies: The dependencies to include in the package.json file.
463+
dev_dependencies: The devDependencies to include in the package.json file.
464+
overrides: The overrides to include in the package.json file.
446465
447466
Returns:
448467
Rendered package.json content as string.
@@ -451,25 +470,23 @@ def _package_json_template(**kwargs):
451470
{
452471
"name": "reflex",
453472
"type": "module",
454-
"scripts": kwargs.get("scripts", {}),
455-
"dependencies": kwargs.get("dependencies", {}),
456-
"devDependencies": kwargs.get("dev_dependencies", {}),
457-
"overrides": kwargs.get("overrides", {}),
473+
"scripts": scripts,
474+
"dependencies": dependencies,
475+
"devDependencies": dev_dependencies,
476+
"overrides": overrides,
458477
}
459478
)
460479

461480

462-
def _vite_config_template(**kwargs):
481+
def vite_config_template(base: str):
463482
"""Template for vite.config.js.
464483
465484
Args:
466-
**kwargs: Template context variables including base path.
485+
base: The base path for the Vite config.
467486
468487
Returns:
469488
Rendered vite.config.js content as string.
470489
"""
471-
base = kwargs.get("base", "/")
472-
473490
return rf"""import {{ fileURLToPath, URL }} from "url";
474491
import {{ reactRouter }} from "@react-router/dev/vite";
475492
import {{ defineConfig }} from "vite";
@@ -570,42 +587,45 @@ def _stateful_components_template(**kwargs) -> str:
570587
return kwargs.get("code", "")
571588

572589

573-
def _custom_component_template(**kwargs) -> str:
574-
"""Template for custom components.
590+
def custom_component_template(
591+
imports: list[_ImportDict],
592+
components: list[dict[str, Any]],
593+
dynamic_imports: Iterable[str],
594+
custom_codes: Iterable[str],
595+
) -> str:
596+
"""Template for custom component.
575597
576598
Args:
577-
**kwargs: Template context variables including custom_codes, components, etc.
599+
imports: List of import statements.
600+
components: List of component definitions.
601+
dynamic_imports: List of dynamic import statements.
602+
custom_codes: List of custom code snippets.
578603
579604
Returns:
580-
Rendered custom components code as string.
605+
Rendered custom component code as string.
581606
"""
582-
custom_codes = kwargs.get("custom_codes", [])
583-
components = kwargs.get("components", [])
584-
sort_hooks = kwargs.get("sort_hooks", _sort_hooks)
585-
607+
imports_str = "\n".join([_RenderUtils.get_import(imp) for imp in imports])
608+
dynamic_imports_str = "\n".join(dynamic_imports)
586609
custom_code_str = "\n".join(custom_codes)
587610

588611
components_code = ""
589612
for component in components:
590-
# Render hooks for each component
591-
hooks = component.get("hooks", {})
592-
sorted_hooks = sort_hooks(hooks)
593-
hooks_code = ""
594-
for hook_list in sorted_hooks.values():
595-
for hook, _ in hook_list:
596-
hooks_code += f" {hook}\n"
597-
598-
props_str = ", ".join(component.get("props", []))
599613
components_code += f"""
600-
export const {component["name"]} = memo({{ {props_str} }}) => {{
601-
{hooks_code}
614+
export const {component["name"]} = memo({{ {", ".join(component.get("props", []))} }}) => {{
615+
{_render_hooks(component.get("hooks", {}))}
602616
return(
603617
{_RenderUtils.render(component["render"])}
604-
)
618+
)
619+
}}
620+
"""
605621

606-
}}"""
622+
return f"""
623+
{imports_str}
624+
625+
{dynamic_imports_str}
626+
627+
{custom_code_str}
607628
608-
return f"""{custom_code_str}
609629
{components_code}"""
610630

611631

@@ -625,36 +645,29 @@ def _styles_template(**kwargs) -> str:
625645
return imports_code
626646

627647

628-
def _render_hooks(
629-
hooks: dict, sort_hooks_func: Callable = _sort_hooks, memo: list | None = None
630-
) -> str:
648+
def _render_hooks(hooks: dict, memo: list | None = None) -> str:
631649
"""Render hooks for macros.
632650
633651
Args:
634652
hooks: Dictionary of hooks to render.
635-
sort_hooks_func: Function to sort hooks by position.
636653
memo: Optional list of memo hooks.
637654
638655
Returns:
639656
Rendered hooks code as string.
640657
"""
641-
sorted_hooks = sort_hooks_func(hooks)
658+
sorted_hooks = _sort_hooks(hooks)
642659
hooks_code = ""
643660

644-
# Internal hooks
645661
for hook, _ in sorted_hooks.get(constants.Hooks.HookPosition.INTERNAL, []):
646662
hooks_code += f" {hook}\n"
647663

648-
# Pre-trigger hooks
649664
for hook, _ in sorted_hooks.get(constants.Hooks.HookPosition.PRE_TRIGGER, []):
650665
hooks_code += f" {hook}\n"
651666

652-
# Memo hooks if provided
653667
if memo:
654668
for hook in memo:
655669
hooks_code += f" {hook}\n"
656670

657-
# Post-trigger hooks
658671
for hook, _ in sorted_hooks.get(constants.Hooks.HookPosition.POST_TRIGGER, []):
659672
hooks_code += f" {hook}\n"
660673

@@ -694,9 +707,6 @@ def render(self, **kwargs) -> str:
694707
# Code to render a single react page.
695708
PAGE = TemplateFunction(_page_template)
696709

697-
# Code to render the custom components page.
698-
COMPONENTS = TemplateFunction(_custom_component_template)
699-
700710
# Code to render Component instances as part of StatefulComponent
701711
STATEFUL_COMPONENT = TemplateFunction(_stateful_component_template)
702712

@@ -709,17 +719,10 @@ def render(self, **kwargs) -> str:
709719
# Code to render the root stylesheet.
710720
STYLE = TemplateFunction(_styles_template)
711721

712-
# Code that generate the package json file
713-
PACKAGE_JSON = TemplateFunction(_package_json_template)
714-
715-
# Code that generate the vite.config.js file
716-
VITE_CONFIG = TemplateFunction(_vite_config_template)
717-
718722
# Template containing some macros used in the web pages.
719723
MACROS = TemplateFunction(
720724
lambda **kwargs: _render_hooks(
721725
kwargs.get("hooks", {}),
722-
kwargs.get("sort_hooks", _sort_hooks),
723726
kwargs.get("memo", None),
724727
)
725728
)

reflex/utils/frontend_skeleton.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def _update_react_router_config(config: Config, prerender_routes: bool = False):
169169

170170

171171
def _compile_package_json():
172-
return templates.PACKAGE_JSON.render(
172+
return templates.package_json_template(
173173
scripts={
174174
"dev": constants.PackageJson.Commands.DEV,
175175
"export": constants.PackageJson.Commands.EXPORT,
@@ -192,7 +192,7 @@ def _compile_vite_config(config: Config):
192192
base = "/"
193193
if frontend_path := config.frontend_path.strip("/"):
194194
base += frontend_path + "/"
195-
return templates.VITE_CONFIG.render(base=base)
195+
return templates.vite_config_template(base=base)
196196

197197

198198
def initialize_vite_config():

reflex/utils/templates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def create_config(app_name: str):
3333
from reflex.compiler import templates
3434

3535
console.debug(f"Creating {constants.Config.FILE}")
36-
constants.Config.FILE.write_text(templates._rxconfig_template(app_name=app_name))
36+
constants.Config.FILE.write_text(templates.rxconfig_template(app_name=app_name))
3737

3838

3939
def initialize_app_directory(

tests/units/utils/test_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,15 @@ def test_unsupported_literals(cls: type):
316316
],
317317
)
318318
def test_create_config(app_name: str, expected_config_name: str, mocker: MockerFixture):
319-
"""Test templates._rxconfig_template is formatted with correct app name and config class name.
319+
"""Test templates.rxconfig_template is formatted with correct app name and config class name.
320320
321321
Args:
322322
app_name: App name.
323323
expected_config_name: Expected config name.
324324
mocker: Mocker object.
325325
"""
326326
mocker.patch("pathlib.Path.write_text")
327-
tmpl_mock = mocker.patch("reflex.compiler.templates._rxconfig_template")
327+
tmpl_mock = mocker.patch("reflex.compiler.templates.rxconfig_template")
328328
templates.create_config(app_name)
329329
tmpl_mock.assert_called_with(app_name=app_name)
330330

0 commit comments

Comments
 (0)