Skip to content

Commit

Permalink
Using format_html
Browse files Browse the repository at this point in the history
  • Loading branch information
danjac committed May 12, 2021
1 parent b50a414 commit ecd8b7b
Show file tree
Hide file tree
Showing 13 changed files with 23 additions and 330 deletions.
4 changes: 1 addition & 3 deletions doc/source/main.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ Next update **INSTALLED_APPS**:
...
]
The turbo stream and frame rendering uses **turbo_response.renderers.DjangoTemplates** by default. If you want to change this default import string with the Django setting **TURBO_RESPONSE_RENDERER**. For example, if you want to render all templates through Jinja2 you can use **turbo_response.renderers.Jinja2**. In almost all cases however there is probably no need to change the default settings.

**Note**: This install does not include any client libraries (Turbo or Stimulus). You may wish to add these yourself using your preferred Javascript build tool, or use a CDN. Please refer to the Hotwire documentation on installing these libraries.
**Note**: This install does not include any client libraries (e.g. Turbo or Stimulus). You may wish to add these yourself using your preferred Javascript build tool, or use a CDN. Please refer to the Hotwire documentation on installing these libraries.


==========
Expand Down
1 change: 0 additions & 1 deletion src/turbo_response/jinja2/turbo_response/turbo_frame.html

This file was deleted.

1 change: 0 additions & 1 deletion src/turbo_response/jinja2/turbo_response/turbo_stream.html

This file was deleted.

15 changes: 3 additions & 12 deletions src/turbo_response/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from .constants import Action
from .frame import TurboFrame
from .renderers import BaseRenderer
from .response import HttpResponseSeeOther
from .stream import TurboStream, TurboStreamAction

Expand All @@ -19,9 +18,6 @@ class TurboStreamMixin:
turbo_stream_action: Optional[Action] = None
turbo_stream_target: Optional[str] = None

def get_turbo_stream_renderer(self) -> Optional[BaseRenderer]:
return None

def get_turbo_stream(self) -> TurboStreamAction:

target = self.get_turbo_stream_target()
Expand Down Expand Up @@ -58,9 +54,6 @@ def get_turbo_stream_target(self) -> Optional[str]:
class TurboFrameMixin:
turbo_frame_dom_id: Optional[str] = None

def get_turbo_frame_renderer(self) -> Optional[BaseRenderer]:
return None

def get_turbo_frame(self) -> TurboFrame:
dom_id = self.get_turbo_frame_dom_id()
if not dom_id:
Expand Down Expand Up @@ -94,7 +87,6 @@ def render_turbo_stream(self, **kwargs) -> HttpResponse:
return self.get_turbo_stream().response(
self.get_response_content(),
is_safe=self.is_turbo_stream_content_safe(),
renderer=self.get_turbo_stream_renderer(),
**kwargs,
)

Expand All @@ -115,7 +107,7 @@ def render_turbo_stream(self, context: Dict[str, Any], **kwargs) -> HttpResponse
return (
self.get_turbo_stream()
.template(self.get_template_names(), context, using=self.template_engine)
.response(self.request, renderer=self.get_turbo_stream_renderer(), **kwargs)
.response(self.request, **kwargs)
)


Expand Down Expand Up @@ -230,7 +222,7 @@ def render_turbo_stream_response(self, **context) -> HttpResponse:
context=self.get_context_data(**context),
using=self.template_engine,
)
.response(self.request, renderer=self.get_turbo_stream_renderer())
.response(self.request)
)

def form_invalid(self, form: forms.Form) -> HttpResponse:
Expand Down Expand Up @@ -276,7 +268,6 @@ def render_turbo_frame(self, **kwargs) -> HttpResponse:
return self.get_turbo_frame().response(
self.get_response_content(),
is_safe=self.is_turbo_frame_content_safe(),
renderer=self.get_turbo_frame_renderer(),
**kwargs,
)

Expand All @@ -296,5 +287,5 @@ def render_turbo_frame(self, context: Dict[str, Any], **kwargs) -> HttpResponse:
return (
self.get_turbo_frame()
.template(self.get_template_names(), context, using=self.template_engine)
.response(self.request, renderer=self.get_turbo_frame_renderer(), **kwargs)
.response(self.request, **kwargs)
)
114 changes: 11 additions & 103 deletions src/turbo_response/renderers.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,41 @@
import pathlib
from functools import lru_cache
from typing import Dict, Optional

from django.template import Template
from django.template.backends.django import DjangoTemplates as DjangoTemplatesBackend
from django.template.engine import Engine
from django.template.loader import get_template
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
from django.utils.html import format_html
from django.utils.safestring import mark_safe

from .constants import Action


class BaseRenderer:
"""This classes is based on django form widget renderer: we can determine
the template engine used to render the wrapper templates in settings or per instance."""

def get_template(self, template_name: str) -> Template:
raise NotImplementedError("subclasses must implement get_template()")

def render(self, template_name: str, context: Dict) -> str:
template = self.get_template(template_name)
return template.render(context).strip()


def render_turbo_stream(
action: Action,
target: str,
content: str = "",
is_safe: bool = False,
renderer: Optional[BaseRenderer] = None,
) -> str:
"""Wraps content in correct <turbo-stream> tags.
:param action: action type
:param target: the DOM ID target of the stream
:param content: content to be wrapped. Can be empty.
:param is_safe: mark content safe for HTML escaping.
:param renderer: template renderer class
:return: *<turbo-stream>* string
"""
return render(
"turbo_response/turbo_stream.html",

if is_safe:
content = mark_safe(content)

return format_html(
'<turbo-stream action="{}" target="{}">'
"<template>{}</template></turbo-stream>",
action.value,
target,
content,
is_safe,
renderer,
extra_context={"action": action.value, "target": target},
)


def render_turbo_frame(
dom_id: str,
content: str = "",
is_safe: bool = False,
renderer: Optional[BaseRenderer] = None,
) -> str:
"""
Expand All @@ -64,82 +44,10 @@ def render_turbo_frame(
:param dom_id: a DOM ID present in the content
:param content: content of the turbo-frame
:param is_safe: mark content safe for HTML escaping.
:param renderer: template renderer class
:return: *<turbo-frame>* string
"""
return render(
"turbo_response/turbo_frame.html",
content,
is_safe,
renderer,
extra_context={"dom_id": dom_id},
)


@lru_cache()
def get_default_renderer() -> BaseRenderer:
"""Get the default renderer class.
:return: renderer subclass: default DjangoTemplates
"""
from django.conf import settings

renderer_class_name = getattr(
settings, "TURBO_RESPONSE_RENDERER", "turbo_response.renderers.DjangoTemplates"
)

renderer_class = import_string(renderer_class_name)
return renderer_class()


def render(
template_name: str,
content: str,
is_safe: bool,
renderer: Optional[BaseRenderer] = None,
extra_context: Optional[Dict] = None,
) -> str:

renderer = renderer or get_default_renderer()

if is_safe:
content = mark_safe(content)

return renderer.render(template_name, {"content": content, **(extra_context or {})})


class EngineMixin:
backend: Engine

def get_template(self, template_name: str) -> Template:
return self.engine.get_template(template_name)

@cached_property
def engine(self) -> Engine:
return self.backend(
{
"APP_DIRS": True,
"DIRS": [pathlib.Path(__file__).parent / self.backend.app_dirname],
"NAME": "turbo_response",
"OPTIONS": {},
}
)


class DjangoTemplates(EngineMixin, BaseRenderer):
backend = DjangoTemplatesBackend


class Jinja2(EngineMixin, BaseRenderer):
@cached_property
def backend(self) -> Engine:
from django.template.backends.jinja2 import Jinja2

return Jinja2


class TemplatesSetting(BaseRenderer):
def get_template(self, template_name: str) -> Template:
return get_template(template_name)
return format_html('<turbo-frame id="{}">{}</turbo-frame>', dom_id, content)
20 changes: 7 additions & 13 deletions src/turbo_response/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from django.template.response import TemplateResponse

from .constants import TURBO_STREAM_MIME_TYPE, Action
from .renderers import BaseRenderer, render_turbo_frame, render_turbo_stream
from .renderers import render_turbo_frame, render_turbo_stream


class HttpResponseSeeOther(HttpResponseRedirect):
Expand Down Expand Up @@ -66,13 +66,10 @@ def __init__(
action: Optional[Action] = None,
target: Optional[str] = None,
is_safe: bool = False,
renderer: Optional[BaseRenderer] = None,
**response_kwargs,
):
if action and target and isinstance(content, str):
content = render_turbo_stream(
action, target, content, is_safe=is_safe, renderer=renderer
)
content = render_turbo_stream(action, target, content, is_safe=is_safe)
super().__init__(content, **response_kwargs)


Expand All @@ -97,7 +94,6 @@ def __init__(
*,
action: Action,
target: str,
renderer: Optional[BaseRenderer] = None,
**kwargs,
):

Expand All @@ -115,15 +111,13 @@ def __init__(

self._target = target
self._action = action
self._renderer = renderer

@property
def rendered_content(self) -> str:
return render_turbo_stream(
action=self._action,
target=self._target,
content=super().rendered_content,
renderer=self._renderer,
is_safe=True,
)

Expand All @@ -137,11 +131,14 @@ def __init__(
*,
dom_id: str,
is_safe: bool = False,
renderer: Optional[BaseRenderer] = None,
**response_kwargs,
):
super().__init__(
render_turbo_frame(dom_id, content, is_safe=is_safe, renderer=renderer),
render_turbo_frame(
dom_id,
content,
is_safe=is_safe,
),
**response_kwargs,
)

Expand All @@ -165,7 +162,6 @@ def __init__(
context: Optional[Mapping[str, Any]] = None,
*,
dom_id,
renderer: Optional[BaseRenderer] = None,
**kwargs,
):

Expand All @@ -177,13 +173,11 @@ def __init__(
)

self._dom_id = dom_id
self._renderer = renderer

@property
def rendered_content(self) -> str:
return render_turbo_frame(
self._dom_id,
super().rendered_content,
is_safe=True,
renderer=self._renderer,
)
8 changes: 1 addition & 7 deletions src/turbo_response/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.template.loader import render_to_string

from .constants import Action
from .renderers import BaseRenderer, render_turbo_frame, render_turbo_stream
from .renderers import render_turbo_frame, render_turbo_stream


def render_turbo_stream_template(
Expand All @@ -12,7 +12,6 @@ def render_turbo_stream_template(
*,
action: Action,
target: str,
renderer: Optional[BaseRenderer] = None,
**template_kwargs
) -> str:
"""Renders a *<turbo-stream>* template.
Expand All @@ -21,7 +20,6 @@ def render_turbo_stream_template(
:param context: template context
:param action: turbo-stream action
:param target: turbo-stream target
:param renderer: turbo-stream template renderer
"""
return render_turbo_stream(
action,
Expand All @@ -37,7 +35,6 @@ def render_turbo_stream_template(
**template_kwargs,
).strip(),
is_safe=True,
renderer=renderer,
)


Expand All @@ -46,15 +43,13 @@ def render_turbo_frame_template(
context: Optional[Dict[str, Any]] = None,
*,
dom_id: str,
renderer: Optional[BaseRenderer] = None,
**kwargs
) -> str:
"""Renders a *<turbo-frame>* template.
:param template: template name or names
:param context: template context
:param dom_id: turbo-frame DOM ID
:param renderer: turbo-frame template renderer
"""

return render_turbo_frame(
Expand All @@ -69,5 +64,4 @@ def render_turbo_frame_template(
**kwargs,
).strip(),
is_safe=True,
renderer=renderer,
)

This file was deleted.

This file was deleted.

Loading

0 comments on commit ecd8b7b

Please sign in to comment.