From 2c0202a9a29ef5e4d892b4d98100bcc231337eab Mon Sep 17 00:00:00 2001 From: Michaelyin Date: Mon, 26 Aug 2024 22:54:51 +0800 Subject: [PATCH] chore --- pyproject.toml | 1 + src/turbo_helper/__init__.py | 3 +- src/turbo_helper/templatetags/turbo_helper.py | 136 +----------------- 3 files changed, 6 insertions(+), 134 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 635b918..d56e7b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ Changelog = "https://github.com/rails-inspire-django/django-turbo-helper/release python = ">=3.8" django = ">=3.0" django-actioncable = ">=1.0.4" +django-template-simplify = ">=1.0.2" [tool.poetry.dev-dependencies] diff --git a/src/turbo_helper/__init__.py b/src/turbo_helper/__init__.py index c8e88b8..9e5e050 100644 --- a/src/turbo_helper/__init__.py +++ b/src/turbo_helper/__init__.py @@ -1,9 +1,10 @@ +from template_simplify import dom_id + from .middleware import get_current_request from .response import HttpResponseSeeOther, TurboStreamResponse from .shortcuts import redirect_303, respond_to from .signals import after_create_commit, after_delete_commit, after_update_commit from .stream import register_turbo_stream_action, turbo_stream -from .templatetags.turbo_helper import dom_id # extend turbo_stream actions, inspired by https://github.com/marcoroth/turbo_power from .turbo_power import * # noqa diff --git a/src/turbo_helper/templatetags/turbo_helper.py b/src/turbo_helper/templatetags/turbo_helper.py index 0423ad9..0832233 100644 --- a/src/turbo_helper/templatetags/turbo_helper.py +++ b/src/turbo_helper/templatetags/turbo_helper.py @@ -1,145 +1,15 @@ -import re -from typing import Any, Optional - from django import template -from django.db.models.base import Model from django.template import Node, TemplateSyntaxError from django.template.base import token_kwargs +from template_simplify.templatetags.template_simplify import class_names, dom_id from turbo_helper.renderers import render_turbo_frame, render_turbo_stream_from from turbo_helper.stream import action_proxy register = template.Library() - -@register.simple_tag -def dom_id(instance: Any, prefix: Optional[str] = "") -> str: - """ - Generate a unique identifier for a Django model instance, class, or even Python object. - - Args: - instance (Any): The instance or class for which the identifier is generated. - prefix (Optional[str]): An optional prefix to prepend to the identifier. Defaults to an empty string. - - Returns: - str: The generated identifier. - - Raises: - Exception: If the model instance does not have either the `to_key` or `pk` attribute. - - Note: - - If `instance` is a Django model instance, the identifier is generated based on the `to_key` or `pk` attribute. - - If `instance` is a Django model class, the identifier is generated as `new_`. - - If `instance` is neither a model instance nor a model class, the identifier is generated based on the `to_key` - attribute if available, otherwise it uses the string representation of the instance. - - The `prefix` argument can be used to prepend a prefix to the generated identifier. - """ - if not isinstance(instance, type) and isinstance(instance, Model): - # Django model instance - if hasattr(instance, "to_key") and getattr(instance, "to_key"): # noqa: B009 - identifier = f"{instance.__class__.__name__.lower()}_{instance.to_key}" - elif hasattr(instance, "pk") and getattr(instance, "pk"): # noqa: B009 - identifier = f"{instance.__class__.__name__.lower()}_{instance.pk}" - else: - raise Exception( - f"Model instance must have either to_key or pk attribute {instance}" - ) - elif isinstance(instance, type) and issubclass(instance, Model): - # Django model class - identifier = f"new_{instance.__name__.lower()}" - else: - if hasattr(instance, "to_key") and getattr(instance, "to_key"): # noqa: B009 - # Developer can still use to_key property to generate the identifier - identifier = f"{instance.to_key}" - else: - # Use the string representation - identifier = str(instance) - - if prefix: - identifier = f"{prefix}_{identifier}" - - return identifier - - -ATTRIBUTE_RE = re.compile( - r""" - (?P - [@\w:_\.\/-]+ - ) - (?P - \+?= - ) - (?P - ['"]? # start quote - [^"']* - ['"]? # end quote - ) -""", - re.VERBOSE | re.UNICODE, -) - - -VALUE_RE = re.compile( - r""" - ['"] # start quote (required) - (?P - [^"']* # match any character except quotes - ) - ['"] # end quote (required) - """, - re.VERBOSE | re.UNICODE, -) - - -@register.tag -def class_names(parser, token): - error_msg = f"{token.split_contents()[0]!r} tag requires " "a list of css classes" - try: - bits = token.split_contents() - tag_name = bits[0] # noqa - attr_list = bits[1:] - except ValueError as exc: - raise TemplateSyntaxError(error_msg) from exc - - css_ls = [] - css_dict = {} - for pair in attr_list: - attribute_match = ATTRIBUTE_RE.match(pair) or VALUE_RE.match(pair) - - if attribute_match: - dct = attribute_match.groupdict() - attr = dct.get("attr", None) - # sign = dct.get("sign", None) - value = parser.compile_filter(dct["value"]) - if attr: - css_dict[attr] = value - else: - css_ls.append(value) - else: - raise TemplateSyntaxError("class_names found supported token: " + f"{pair}") - - return ClassNamesNode(css_ls=css_ls, css_dict=css_dict) - - -class ClassNamesNode(Node): - def __init__(self, css_ls, css_dict): - self.css_ls = css_ls - self.css_dict = css_dict - - def render(self, context): - final_css = [] - - # for common css classes - for value in self.css_ls: - final_css.append(value.token) - - # for conditionals - for attr, expression in self.css_dict.items(): - real_value = expression.resolve(context) - if real_value: - final_css.append(attr) - - return " ".join(final_css) +register.simple_tag(dom_id, name="dom_id") +register.tag(class_names) class TurboFrameTagNode(Node):