Skip to content

Utility function: get_component() #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/features/utilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Get Component

You can fetch any of your IDOM components from other files by using `get_component`.

```python title="components.py"
from idom import component
from django_idom.utils import get_component

@component
def MyComponent():
hello_world = get_component("example_project.my_app.components.HelloWorld")
return hello_world(recipient="World")
```

??? question "Should I use this instead of `#!python import`?"

TBD
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ nav:
- Exclusive Features:
- Hooks: features/hooks.md
- Template Tag: features/templatetag.md
- Utilities: features/utilities.md
- Contribute:
- Code: contribute/django-idom.md
- Docs: contribute/docs.md
Expand Down
2 changes: 1 addition & 1 deletion requirements/test-env.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
django
selenium
selenium <= 4.2.0
twisted
4 changes: 2 additions & 2 deletions src/django_idom/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from . import hooks
from . import hooks, utils
from .websocket.consumer import IdomWebsocket
from .websocket.paths import IDOM_WEBSOCKET_PATH


__version__ = "1.0.0"
__all__ = ["IDOM_WEBSOCKET_PATH", "IdomWebsocket", "hooks"]
__all__ = ["IDOM_WEBSOCKET_PATH", "IdomWebsocket", "hooks", "utils"]
4 changes: 2 additions & 2 deletions src/django_idom/apps.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from django.apps import AppConfig

from django_idom.utils import ComponentPreloader
from django_idom.utils import _ComponentPreloader


class DjangoIdomConfig(AppConfig):
name = "django_idom"

def ready(self):
# Populate the IDOM component registry when Django is ready
ComponentPreloader().register_all()
_ComponentPreloader().register_all()
4 changes: 2 additions & 2 deletions src/django_idom/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from django.conf import settings
from django.core.cache import DEFAULT_CACHE_ALIAS, caches
from idom.core.types import ComponentConstructor
from idom.core.types import ComponentType


IDOM_REGISTERED_COMPONENTS: Dict[str, ComponentConstructor] = {}
IDOM_REGISTERED_COMPONENTS: Dict[str, ComponentType] = {}

IDOM_WEBSOCKET_URL = getattr(settings, "IDOM_WEBSOCKET_URL", "idom/")
IDOM_WS_MAX_RECONNECT_TIMEOUT = getattr(
Expand Down
4 changes: 2 additions & 2 deletions src/django_idom/templatetags/idom.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.urls import reverse

from django_idom.config import IDOM_WEBSOCKET_URL, IDOM_WS_MAX_RECONNECT_TIMEOUT
from django_idom.utils import _register_component
from django_idom.utils import register_component


IDOM_WEB_MODULES_URL = reverse("idom:web_modules", args=["x"])[:-1][1:]
Expand All @@ -15,7 +15,7 @@

@register.inclusion_tag("idom/component.html")
def component(_component_id_, **kwargs):
_register_component(_component_id_)
register_component(_component_id_)

class_ = kwargs.pop("class", "")
json_kwargs = json.dumps(kwargs, separators=(",", ":"))
Expand Down
26 changes: 18 additions & 8 deletions src/django_idom/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import re
from fnmatch import fnmatch
from importlib import import_module
from typing import Set
from typing import Set, Union

from django.template import engines
from django.utils.encoding import smart_str
from idom.types import ComponentType

from django_idom.config import IDOM_REGISTERED_COMPONENTS

Expand All @@ -16,11 +17,20 @@
_logger = logging.getLogger(__name__)


def _register_component(full_component_name: str) -> None:
if full_component_name in IDOM_REGISTERED_COMPONENTS:
def get_component(dotted_path: str) -> Union[ComponentType, None]:
"""Fetches a component given it's Python dotted path, if it exists."""
try:
return IDOM_REGISTERED_COMPONENTS[dotted_path]
except KeyError:
_logger.info("A component named %s was never registered!", dotted_path)


def register_component(dotted_path: str) -> None:
"""Registers a component given it's Python dotted path."""
if dotted_path in IDOM_REGISTERED_COMPONENTS:
return

module_name, component_name = full_component_name.rsplit(".", 1)
module_name, component_name = dotted_path.rsplit(".", 1)

try:
module = import_module(module_name)
Expand All @@ -36,11 +46,11 @@ def _register_component(full_component_name: str) -> None:
f"Module {module_name!r} has no component named {component_name!r}"
) from error

IDOM_REGISTERED_COMPONENTS[full_component_name] = component
_logger.debug("IDOM has registered component %s", full_component_name)
IDOM_REGISTERED_COMPONENTS[dotted_path] = component
_logger.debug("IDOM has registered component %s", dotted_path)


class ComponentPreloader:
class _ComponentPreloader:
def register_all(self):
"""Registers all IDOM components found within Django templates."""
# Get all template folder paths
Expand Down Expand Up @@ -123,7 +133,7 @@ def _register_components(self, components: Set) -> None:
for component in components:
try:
_logger.info("IDOM preloader has detected component %s", component)
_register_component(component)
register_component(component)
except Exception:
_logger.error(
"\033[91m"
Expand Down
13 changes: 13 additions & 0 deletions tests/test_app/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.test import TestCase

from django_idom.utils import get_component


class RegexTests(TestCase):
def test_get_component(self):
real_component = get_component("test_app.components.HelloWorld")
self.assertIsNotNone(real_component)
self.assertEqual(getattr(real_component, "__name__", None), "HelloWorld")

fake_component = get_component("test_app.components.FakeComponent")
self.assertIsNone(fake_component)