Skip to content

view_to_iframe component #188

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

Merged
merged 29 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7938867
`view_to_iframe` component
Archmonger Sep 19, 2023
0ab5822
add changelog
Archmonger Sep 19, 2023
40b846f
Merge remote-tracking branch 'upstream/main' into view-to-iframe
Archmonger Sep 21, 2023
79462f9
functional view_to_iframe
Archmonger Sep 22, 2023
68e15a0
ViewToIframeConstructor type
Archmonger Sep 22, 2023
46dc39e
temporarily remove section index plugin
Archmonger Sep 22, 2023
b508589
better API
Archmonger Sep 23, 2023
afe31ac
update docs
Archmonger Sep 23, 2023
1b46664
Auto height and width
Archmonger Sep 23, 2023
38799ce
interface docs
Archmonger Sep 23, 2023
b45f7a9
register_iframe function
Archmonger Sep 24, 2023
8ac3415
move error tests to their own URL
Archmonger Sep 24, 2023
89af32d
reorganize and fix type hints
Archmonger Sep 24, 2023
b296774
update component docs
Archmonger Sep 24, 2023
e8e8455
misc docs tweaks
Archmonger Sep 24, 2023
614b863
add test for ComponentNotRegisteredError
Archmonger Sep 24, 2023
b3f2548
misc doc tweaks
Archmonger Sep 24, 2023
9bb8dda
Register Iframe docs
Archmonger Sep 24, 2023
c55ee3b
add interface utils.md
Archmonger Sep 24, 2023
63e6c98
more obvious error
Archmonger Sep 24, 2023
39171d0
ViewNotRegisteredError and ViewDoesNotExistError
Archmonger Sep 24, 2023
2b66156
clean up register component example
Archmonger Sep 24, 2023
376f7b7
remove dead types
Archmonger Sep 24, 2023
0eb6e90
misc docs tweaks
Archmonger Sep 24, 2023
b52a400
remove thread sensitive
Archmonger Sep 24, 2023
ea067e0
Use .as_view() for CBVs
Archmonger Sep 24, 2023
cad5720
update changelog
Archmonger Sep 24, 2023
b702eea
fix broken example
Archmonger Sep 25, 2023
bf768e0
revert proper docs tests while `reactpy.html` type hints suck
Archmonger Sep 25, 2023
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
Prev Previous commit
Next Next commit
ViewNotRegisteredError and ViewDoesNotExistError
  • Loading branch information
Archmonger committed Sep 24, 2023
commit 39171d063833af29ca0c0340dd78ac3b3a9f6c56
11 changes: 4 additions & 7 deletions src/reactpy_django/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from reactpy import component, hooks, html, utils
from reactpy.types import Key, VdomDict

from reactpy_django.exceptions import ComponentNotRegisteredError
from reactpy_django.exceptions import ViewNotRegisteredError
from reactpy_django.utils import generate_obj_name, import_module, render_view


Expand Down Expand Up @@ -220,15 +220,12 @@ def _view_to_iframe(
"""The actual component. Used to prevent pollution of acceptable kwargs keys."""
from reactpy_django.config import REACTPY_REGISTERED_IFRAME_VIEWS

if isinstance(view, str):
dotted_path = view
else:
dotted_path = generate_obj_name(view).replace("<", "").replace(">", "")
dotted_path = view if isinstance(view, str) else generate_obj_name(view)
registered_view = REACTPY_REGISTERED_IFRAME_VIEWS.get(dotted_path)

if not registered_view:
raise ComponentNotRegisteredError(
f"'{dotted_path}' has not been registered as an iframe component! "
raise ViewNotRegisteredError(
f"'{dotted_path}' has not been registered as an iframe! "
"Are you sure you called `register_iframe` within a Django `AppConfig.ready` method?"
)

Expand Down
6 changes: 5 additions & 1 deletion src/reactpy_django/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ class ComponentCarrierError(ValueError):
...


class ComponentNotRegisteredError(ComponentDoesNotExistError):
class ViewNotRegisteredError(AttributeError):
...


class ViewDoesNotExistError(AttributeError):
...
44 changes: 27 additions & 17 deletions src/reactpy_django/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
from reactpy.core.layout import Layout
from reactpy.types import ComponentConstructor

from reactpy_django.exceptions import ComponentDoesNotExistError, ComponentParamError
from reactpy_django.exceptions import (
ComponentDoesNotExistError,
ComponentParamError,
ViewDoesNotExistError,
)

_logger = logging.getLogger(__name__)
_component_tag = r"(?P<tag>component)"
Expand Down Expand Up @@ -85,39 +89,45 @@ async def render_view(
return response


def register_component(dotted_path: str) -> ComponentConstructor:
"""Adds a component to the list of known registered components."""
def register_component(component: ComponentConstructor | str):
"""Adds a component to the list of known registered components.

Args:
component: The component to register. Can be a component function or dotted path to a component.

"""
from reactpy_django.config import (
REACTPY_FAILED_COMPONENTS,
REACTPY_REGISTERED_COMPONENTS,
)

if dotted_path in REACTPY_REGISTERED_COMPONENTS:
return REACTPY_REGISTERED_COMPONENTS[dotted_path]

dotted_path = (
component if isinstance(component, str) else generate_obj_name(component)
)
try:
REACTPY_REGISTERED_COMPONENTS[dotted_path] = import_dotted_path(dotted_path)
except AttributeError as e:
REACTPY_FAILED_COMPONENTS.add(dotted_path)
raise ComponentDoesNotExistError(
f"Error while fetching '{dotted_path}'. {(str(e).capitalize())}."
) from e
return REACTPY_REGISTERED_COMPONENTS[dotted_path]


def register_iframe(view: Callable | View | str):
"""Registers a view to be used as an iframe component."""
from reactpy_django.config import REACTPY_REGISTERED_IFRAME_VIEWS
"""Registers a view to be used as an iframe component.

resolved_view: Callable | View
if isinstance(view, str):
resolved_view = import_dotted_path(view)
dotted_path = view
else:
resolved_view = view
dotted_path = generate_obj_name(view).replace("<", "").replace(">", "")
Args:
view: The view to register. Can be a function or class based view, or a dotted path to a view.
"""
from reactpy_django.config import REACTPY_REGISTERED_IFRAME_VIEWS

REACTPY_REGISTERED_IFRAME_VIEWS[dotted_path] = resolved_view
dotted_path = view if isinstance(view, str) else generate_obj_name(view)
try:
REACTPY_REGISTERED_IFRAME_VIEWS[dotted_path] = import_dotted_path(dotted_path)
except AttributeError as e:
raise ViewDoesNotExistError(
f"Error while fetching '{dotted_path}'. {(str(e).capitalize())}."
) from e


def import_dotted_path(dotted_path: str) -> Callable:
Expand Down
6 changes: 2 additions & 4 deletions tests/test_app/tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,11 +419,9 @@ def test_component_errors(self):
broken_component.wait_for()
self.assertIn("SynchronousOnlyOperation:", broken_component.text_content())

# ComponentNotRegisteredError
# ViewNotRegisteredError
broken_component = new_page.locator("#view_to_iframe_not_registered pre")
broken_component.wait_for()
self.assertIn(
"ComponentNotRegisteredError:", broken_component.text_content()
)
self.assertIn("ViewNotRegisteredError:", broken_component.text_content())
finally:
new_page.close()