Skip to content

Commit 937244c

Browse files
committed
switch to decorator collection method
1 parent a05d0ef commit 937244c

File tree

12 files changed

+84
-102
lines changed

12 files changed

+84
-102
lines changed

src/django_idom/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from .app_paths import idom_web_modules_path, idom_websocket_path
1+
from .components import register_component
2+
from .paths import idom_web_modules_path, idom_websocket_path
23

34

45
__version__ = "0.0.1"
5-
__all__ = ["idom_websocket_path", "idom_web_modules_path"]
6+
__all__ = ["idom_websocket_path", "idom_web_modules_path", "register_component"]

src/django_idom/app_components.py

-70
This file was deleted.

src/django_idom/components.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import inspect
2+
from typing import Any, Optional
3+
4+
from idom.core.component import component as component_deco
5+
6+
from .config import IDOM_REGISTERED_COMPONENTS
7+
8+
9+
def register_component(
10+
component: Optional[Any] = None,
11+
is_render_function: bool = True,
12+
module_name: Optional[str] = None,
13+
) -> Any:
14+
module_name = module_name or _get_outer_frame_module_name()
15+
if module_name is None:
16+
raise ValueError("Could not infer module name - provide it explicitely")
17+
18+
def setup(component: Any) -> Any:
19+
if is_render_function:
20+
component = component_deco(component)
21+
22+
try:
23+
component_name = component.__name__
24+
except AttributeError:
25+
raise AttributeError("Component constructor must have a __name__ attribute")
26+
27+
IDOM_REGISTERED_COMPONENTS[f"{module_name}.{component_name}"] = component
28+
29+
return component
30+
31+
if component is not None:
32+
return setup(component)
33+
else:
34+
return setup
35+
36+
37+
def _get_outer_frame_module_name() -> Optional[str]:
38+
frame = inspect.currentframe()
39+
40+
if frame is None:
41+
return None
42+
43+
for i in range(2):
44+
frame = frame.f_back
45+
if frame is None:
46+
return None
47+
48+
return frame.f_globals.get("__name__")

src/django_idom/app_settings.py renamed to src/django_idom/config.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
from typing import Dict
2+
13
from django.conf import settings
4+
from idom.core.proto import ComponentConstructor
25

36

4-
IDOM_IGNORE_INSTALLED_APPS = set(getattr(settings, "IDOM_IGNORE_INSTALLED_APPS", []))
7+
IDOM_REGISTERED_COMPONENTS: Dict[str, ComponentConstructor] = {}
58

69
IDOM_BASE_URL = getattr(settings, "IDOM_BASE_URL", "_idom/")
710
IDOM_WEBSOCKET_URL = IDOM_BASE_URL + "websocket/"

src/django_idom/app_paths.py renamed to src/django_idom/paths.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.urls import path
22

33
from . import views
4-
from .app_settings import IDOM_WEB_MODULES_URL, IDOM_WEBSOCKET_URL
4+
from .config import IDOM_WEB_MODULES_URL, IDOM_WEBSOCKET_URL
55
from .websocket_consumer import IdomAsyncWebSocketConsumer
66

77

src/django_idom/templatetags/idom.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44

55
from django import template
66

7-
from django_idom.app_settings import IDOM_WEB_MODULES_URL, IDOM_WEBSOCKET_URL
8-
9-
from ..app_components import has_component
7+
from django_idom.config import (
8+
IDOM_REGISTERED_COMPONENTS,
9+
IDOM_WEB_MODULES_URL,
10+
IDOM_WEBSOCKET_URL,
11+
)
1012

1113

1214
register = template.Library()
1315

1416

1517
@register.inclusion_tag("idom/view.html")
1618
def idom_view(_component_id_, **kwargs):
17-
if not has_component(_component_id_):
19+
if _component_id_ not in IDOM_REGISTERED_COMPONENTS:
20+
print(list(IDOM_REGISTERED_COMPONENTS))
1821
raise ValueError(f"No component {_component_id_!r} exists")
1922

2023
json_kwargs = json.dumps(kwargs, separators=(",", ":"))

src/django_idom/views.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from django.http import HttpResponse
1+
from django.http import HttpRequest, HttpResponse
22
from idom.config import IDOM_WED_MODULES_DIR
33

44

5-
def web_modules_file(request, file: str) -> HttpResponse:
5+
def web_modules_file(request: HttpRequest, file: str) -> HttpResponse:
66
file_path = IDOM_WED_MODULES_DIR.current.joinpath(*file.split("/"))
77
return HttpResponse(file_path.read_text(), content_type="text/javascript")

src/django_idom/websocket_consumer.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from idom.core.dispatcher import dispatch_single_view
1010
from idom.core.layout import Layout, LayoutEvent
1111

12-
from .app_components import get_component, has_component
12+
from .config import IDOM_REGISTERED_COMPONENTS
1313

1414

1515
_logger = logging.getLogger(__name__)
@@ -38,12 +38,12 @@ async def receive_json(self, content: Any, **kwargs: Any) -> None:
3838
async def _run_dispatch_loop(self):
3939
view_id = self.scope["url_route"]["kwargs"]["view_id"]
4040

41-
if not has_component(view_id):
41+
try:
42+
component_constructor = IDOM_REGISTERED_COMPONENTS[view_id]
43+
except KeyError:
4244
_logger.warning(f"Uknown IDOM view ID {view_id!r}")
4345
return
4446

45-
component_constructor = get_component(view_id)
46-
4747
query_dict = dict(parse_qsl(self.scope["query_string"].decode()))
4848
component_kwargs = json.loads(query_dict.get("kwargs", "{}"))
4949

tests/test_app/components.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import idom
22

3+
from django_idom import register_component
34

4-
@idom.component
5+
6+
@register_component
57
def HelloWorld():
68
return idom.html.h1({"id": "hello-world"}, "Hello World!")
79

810

9-
@idom.component
11+
@register_component
1012
def Button():
1113
count, set_count = idom.hooks.use_state(0)
1214
return idom.html.div(
@@ -21,16 +23,16 @@ def Button():
2123
)
2224

2325

24-
@idom.component
26+
@register_component
2527
def ParametrizedComponent(x, y):
2628
total = x + y
2729
return idom.html.h1({"id": "parametrized-component", "data-value": total}, total)
2830

2931

30-
victory = idom.web.module_from_template("react", "victory", fallback="...")
32+
victory = idom.web.module_from_template("react", "victory-line", fallback="...")
3133
VictoryBar = idom.web.export(victory, "VictoryBar")
3234

3335

34-
@idom.component
36+
@register_component
3537
def SimpleBarChart():
3638
return VictoryBar()

tests/test_app/idom.py

-9
This file was deleted.

tests/test_app/templates/base.html

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515

1616
<body>
1717
<h1>IDOM Test Page</h1>
18-
<div>{% idom_view "test_app.HelloWorld" %}</div>
19-
<div>{% idom_view "test_app.Button" %}</div>
20-
<div>{% idom_view "test_app.ParametrizedComponent" x=123 y=456 %}</div>
21-
<div>{% idom_view "test_app.SimpleBarChart" %}</div>
18+
<div>{% idom_view "test_app.views.HelloWorld" %}</div>
19+
<div>{% idom_view "test_app.views.Button" %}</div>
20+
<div>
21+
{% idom_view "test_app.views.ParametrizedComponent" x=123 y=456 %}
22+
</div>
23+
<div>{% idom_view "test_app.views.SimpleBarChart" %}</div>
2224
</body>
2325
</html>

tests/test_app/views.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from django.http import HttpResponse
22
from django.template import loader
33

4+
import test_app.components
5+
46

57
def base_template(request):
68
context = {}

0 commit comments

Comments
 (0)