mirror of
https://github.com/django-components/django-components.git
synced 2025-08-08 08:17:59 +00:00
refactor: apply Template patch at AppsConfig.ready() (#825)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
a5659691d0
commit
db4ca8b74f
2 changed files with 20 additions and 6 deletions
|
@ -3,6 +3,7 @@ from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.template import Template
|
||||||
from django.utils.autoreload import file_changed, trigger_reload
|
from django.utils.autoreload import file_changed, trigger_reload
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,9 +15,15 @@ class ComponentsConfig(AppConfig):
|
||||||
def ready(self) -> None:
|
def ready(self) -> None:
|
||||||
from django_components.app_settings import app_settings
|
from django_components.app_settings import app_settings
|
||||||
from django_components.autodiscovery import autodiscover, import_libraries
|
from django_components.autodiscovery import autodiscover, import_libraries
|
||||||
|
from django_components.component import monkeypatch_template
|
||||||
from django_components.component_registry import registry
|
from django_components.component_registry import registry
|
||||||
from django_components.components.dynamic import DynamicComponent
|
from django_components.components.dynamic import DynamicComponent
|
||||||
|
|
||||||
|
# NOTE: This monkeypatch is applied here, before Django processes any requests.
|
||||||
|
# To make django-components work with django-debug-toolbar-template-profiler
|
||||||
|
# See https://github.com/EmilStenstrom/django-components/discussions/819
|
||||||
|
monkeypatch_template(Template)
|
||||||
|
|
||||||
# Import modules set in `COMPONENTS.libraries` setting
|
# Import modules set in `COMPONENTS.libraries` setting
|
||||||
import_libraries()
|
import_libraries()
|
||||||
|
|
||||||
|
|
|
@ -968,7 +968,7 @@ class ComponentNode(BaseNode):
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def _monkeypatch_template(template: Template) -> None:
|
def monkeypatch_template(template_cls: Type[Template]) -> None:
|
||||||
# Modify `Template.render` to set `isolated_context` kwarg of `push_state`
|
# Modify `Template.render` to set `isolated_context` kwarg of `push_state`
|
||||||
# based on our custom `Template._dc_is_component_nested`.
|
# based on our custom `Template._dc_is_component_nested`.
|
||||||
#
|
#
|
||||||
|
@ -986,10 +986,10 @@ def _monkeypatch_template(template: Template) -> None:
|
||||||
# and can modify the rendering behavior by overriding the `_render` method.
|
# and can modify the rendering behavior by overriding the `_render` method.
|
||||||
#
|
#
|
||||||
# NOTE 2: Instead of setting `Template._dc_is_component_nested`, alternatively we could
|
# NOTE 2: Instead of setting `Template._dc_is_component_nested`, alternatively we could
|
||||||
# have passed the value to `_monkeypatch_template` directly. However, we intentionally
|
# have passed the value to `monkeypatch_template` directly. However, we intentionally
|
||||||
# did NOT do that, so the monkey-patched method is more robust, and can be e.g. copied
|
# did NOT do that, so the monkey-patched method is more robust, and can be e.g. copied
|
||||||
# to other.
|
# to other.
|
||||||
if hasattr(template, "_dc_patched"):
|
if hasattr(template_cls, "_dc_patched"):
|
||||||
# Do not patch if done so already. This helps us avoid RecursionError
|
# Do not patch if done so already. This helps us avoid RecursionError
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1012,8 +1012,8 @@ def _monkeypatch_template(template: Template) -> None:
|
||||||
else:
|
else:
|
||||||
return self._render(context, *args, **kwargs)
|
return self._render(context, *args, **kwargs)
|
||||||
|
|
||||||
# See https://stackoverflow.com/a/42154067/9788634
|
template_cls.render = _template_render
|
||||||
template.render = types.MethodType(_template_render, template)
|
template_cls._dc_patched = True
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
@ -1037,7 +1037,14 @@ def _prepare_template(
|
||||||
# See https://github.com/EmilStenstrom/django-components/issues/580
|
# See https://github.com/EmilStenstrom/django-components/issues/580
|
||||||
# And https://github.com/EmilStenstrom/django-components/issues/634
|
# And https://github.com/EmilStenstrom/django-components/issues/634
|
||||||
template = component._get_template(context)
|
template = component._get_template(context)
|
||||||
_monkeypatch_template(template)
|
|
||||||
|
if not getattr(template, "_dc_patched"):
|
||||||
|
raise RuntimeError(
|
||||||
|
"Django-components received a Template instance which was not patched."
|
||||||
|
"If you are using Django's Template class, check if you added django-components"
|
||||||
|
"to INSTALLED_APPS. If you are using a custom template class, then you need to"
|
||||||
|
"manually patch the class."
|
||||||
|
)
|
||||||
|
|
||||||
# Set `Template._dc_is_component_nested` based on whether we're currently INSIDE
|
# Set `Template._dc_is_component_nested` based on whether we're currently INSIDE
|
||||||
# the `{% extends %}` tag.
|
# the `{% extends %}` tag.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue