Moar utilities

This commit is contained in:
László Károlyi 2023-10-05 19:12:06 +02:00
parent ae60459e62
commit 0aabbd7f95
Signed by: karolyi
GPG key ID: 2DCAF25E55735BFE
4 changed files with 194 additions and 205 deletions

View file

@ -1,6 +1,7 @@
from types import FunctionType
from django.conf import settings
from django.contrib import messages
from django.utils.html import strip_spaces_between_tags
from django.utils.translation import (
get_language_from_request, get_language_info)
@ -101,3 +102,4 @@ class KToolsDjangoExtension(Extension):
def __init__(self, environment: Environment):
super().__init__(environment=environment)
environment.globals['dash_case_convert'] = dash_case_convert
environment.globals['messages'] = messages

View file

@ -1,205 +0,0 @@
{% macro render_form_simple(form, wrapper_class) -%}
<section class="{{ PROJECT_NAMESPACE }}-form-simple-wrapper {{ wrapper_class }}">
{% if form.errors.__all__ -%}
<div class="global-error alert alert-danger" role="alert">
{% for error in form.errors.__all__ -%}
<p class="error-item-wrapper">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
<span class="error-item">
{{- error -}}
</span>
</p>
{%- endfor %}
</div>
{%- endif %}
{% for widget in form -%}
{{ render_widget(widget=widget, form=form) }}
{%- endfor %}
</section>
{%- endmacro %}
{% macro render_widget(widget, form) -%}
{% if form.is_translated|default(False) -%}
{% if widget.name in form.fields_to_override -%}
<!-- Nav tabs -->
<ul class="nav nav-tabs" data-for-field="{{ widget.name }}" role="tablist">
{% for field_name in form.fields_to_override[widget.name] -%}
<li class="nav-item">
<a class="nav-link {% spaceless %}
{% if loop.first %}
active
{% endif %}
{% endspaceless %}" href="#tab_{{ field_name }}" data-bs-toggle="tab" role="tab">
{{ form.field_languages[field_name]}}
{% if field_name in form.errors %}
<span class="attention-indicator text-danger">
<span class="fa fa-fw fa-exclamation-circle" aria-hidden="true"></span>
</span>
{% endif %}
</a>
</li>
{%- endfor %}
</ul>
<!-- Tab panes -->
<div class="tab-content">
{% for field_name in form.fields_to_override[widget.name] -%}
<div id="tab_{{ field_name }}" class="tab-pane {% spaceless %}
{% if loop.first %}
active
{% endif %}
{% endspaceless %}">
{{ render_widget_inner(widget=form[field_name]) }}
</div>
{%- endfor %}
</div>
{%- elif widget.name not in form.translated_fields -%}
{{ render_widget_inner(widget=widget) }}
{%- endif %}
{%- else -%}
{{ render_widget_inner(widget=widget) }}
{%- endif %}
{%- endmacro %}
{% macro render_widget_inner(widget) -%}
{%- set widget_class = widget.field.widget.__class__.__name__ -%}
{% if widget_class == 'HiddenInput' -%}
{{ widget }}
{%- else -%}
<div class="widget-wrapper form-group {% spaceless %}
{% if widget.errors %}
is-invalid
{% endif %}
{% endspaceless %}" data-field-name="{{ widget.html_name }}" data-field-type="{{ dash_case_convert(widget_class) }}"
{{- widget.field.widget.attrs.hidden|yesno(' hidden,') -}}>
<div class="row errors-wrapper">
{% if widget.errors -%}
<div class="text-danger widget-error col-form-label-sm col" role="alert">
{% for error in widget.errors -%}
<div class='item-{{ loop.index0 }}'>
<i class="fa fa-exclamation-circle" aria-hidden="true"></i>
<span class="error-text">
{{- error -}}
</span>
</div>
{%- endfor %}
</div>
{%- else -%}
{# <div class="col error-placeholder">&nbsp;</div> #}
{%- endif %}
</div>
<div class="row">
{% if widget_class == 'CheckboxInput' -%}
<div class="col-sm-3 hidden-xs-down"></div>
<div class="col-sm-9 abc-checkbox">
{{ widget }}
<label class="form-check-label col-form-label" for="{{ widget.auto_id }}">
<span class="label-wrapper">
{{- widget.label|escape -}}
</span>
</label>
{% if widget.help_text -%}
<small class="text-muted help-text-wrapper">
<i class="fa fa-info" aria-hidden="true"></i>
<span class="help-text">
{{- widget.help_text -}}
</span>
</small>
{%- endif %}
</div>
{%- elif widget_class in ['Select', 'SelectMultiple', 'LazySelect'] -%}
<label class="form-control-label col-form-label col-xs-12 col-sm-3" for="{{ widget.auto_id }}">
<span class="label-wrapper">
{{- widget.label|escape -}}
</span>
{% if widget.field.required -%}
<abbr title="{{ _('Mandatory field') }}" data-bs-toggle="tooltip">
<small>
<sup class="fa fa-asterisk" aria-hidden="true"></sup>
</small>
</abbr>
{%- endif %}
</label>
<div class="col-xs-12 col-sm-9 input-wrapper">
{{ widget|set_attr('style:width: 100%') }}
{% if widget.help_text -%}
<small class="text-muted help-text-wrapper">
<i class="fa fa-info" aria-hidden="true"></i>
<span class="help-text">
{{- widget.help_text -}}
</span>
</small>
{%- endif %}
</div>
{%- elif widget_class == 'FileInput' -%}
<label class="form-control-label col-form-label col-xs-12 col-sm-3" for="{{ widget.auto_id }}">
<span class="label-wrapper">
{{- widget.label|escape -}}
</span>
{% if widget.field.required -%}
<abbr title="{{ _('Mandatory field') }}" data-bs-toggle="tooltip">
<small>
<sup class="fa fa-asterisk" aria-hidden="true"></sup>
</small>
</abbr>
{%- endif %}
</label>
<div class="col-xs-12 col-sm-9 input-wrapper">
<div class="custom-file">
{{ widget|set_attr('class:custom-file-input')}}
<label class="custom-file-label" for="{{ widget.auto_id }}">
{{- _('Choose file') -}}
</label>
</div>
</div>
{%- else -%}
<label class="form-control-label col-form-label col-xs-12 col-sm-3" for="{{ widget.auto_id }}">
<span class="label-wrapper">
{{- widget.label|escape -}}
</span>
{% if widget.field.required -%}
<abbr title="{{ _('Mandatory field') }}" data-bs-toggle="tooltip">
<small>
<sup class="fa fa-asterisk" aria-hidden="true"></sup>
</small>
</abbr>
{%- endif %}
</label>
<div class="col-xs-12 col-sm-9 input-wrapper">
{% if not widget.field.required and widget_class != 'MoneyWidget' -%}
<div class="input-group">
<button class="btn btn-danger ktools-btn-empty" title="{{ _('Set field empty') }}" data-bs-toggle="tooltip" data-empty="{{ widget.html_name }}" type="button">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
{%- endif -%}
{%- if widget_class in ['CustomCheckboxSelectMultiple', 'CustomRadioSelect'] -%}
{% if widget.errors -%}
{{- widget|add_class('is-invalid') -}}
{%- else -%}
{{- widget -}}
{%- endif %}
{%- else -%}
{% if widget.errors -%}
{{- widget|add_class('form-control is-invalid') -}}
{%- else -%}
{{- widget|add_class('form-control') -}}
{%- endif %}
{%- endif -%}
{%- if not widget.field.required and widget_class != 'MoneyWidget' -%}
</div>
{%- endif %}
{% if widget.help_text -%}
<small class="text-muted help-text-wrapper">
<i class="fa fa-info" aria-hidden="true"></i>
<span class="help-text">
{{- widget.help_text -}}
</span>
</small>
{%- endif %}
</div>
{%- endif %}
</div>
</div>
{%- endif %}
{%- endmacro %}

View file

@ -0,0 +1,174 @@
{% macro render_form_simple(form, wrapper_class) -%}
<section class="{{ PROJECT_NAMESPACE }}-form-simple-wrapper {{ wrapper_class }}">
{% if form.errors.__all__ -%}
<div class="global-error alert alert-danger" role="alert">
{% for error in form.errors.__all__ -%}
<p class="error-item">
{{- error -}}
</p>
{%- endfor %}
</div>
{%- endif %}
{% for widget in form -%}
{{ render_widget(widget=widget, form=form) }}
{%- endfor %}
</section>
{%- endmacro %}
{% macro render_widget(widget, form) -%}
{% if form.is_translated|default(False) -%}
{% if widget.name in form.fields_to_override -%}
<!-- Nav tabs -->
<ul class="nav nav-tabs" data-for-field="{{ widget.name }}" role="tablist">
{% for field_name in form.fields_to_override[widget.name] -%}
<li class="nav-item">
<a class="nav-link {% spaceless %}
{% if loop.first %}
active
{% endif %}
{% endspaceless %}" href="#tab_{{ field_name }}" data-bs-toggle="tab" role="tab">
{{ form.field_languages[field_name]}}
{% if field_name in form.errors %}
<span class="attention-indicator text-danger">
<span class="fa fa-fw fa-exclamation-circle" aria-hidden="true"></span>
</span>
{% endif %}
</a>
</li>
{%- endfor %}
</ul>
<!-- Tab panes -->
<div class="tab-content">
{% for field_name in form.fields_to_override[widget.name] -%}
<div id="tab_{{ field_name }}" class="tab-pane {% spaceless %}
{% if loop.first %}
active
{% endif %}
{% endspaceless %}">
{{ render_widget_inner(widget=form[field_name]) }}
</div>
{%- endfor %}
</div>
{%- elif widget.name not in form.translated_fields -%}
{{ render_widget_inner(widget=widget) }}
{%- endif %}
{%- else -%}
{{ render_widget_inner(widget=widget) }}
{%- endif %}
{%- endmacro %}
{% macro render_widget_inner(widget) -%}
{%- set widget_class = widget.field.widget.__class__.__name__ -%}
{% if widget_class == 'HiddenInput' -%}
{{ widget }}
{%- else -%}
<div class="widget-wrapper form-group {% spaceless %}
{% if widget.errors %}
is-invalid
{% endif %}
{% endspaceless %}" data-field-name="{{ widget.html_name }}" data-field-type="{{ dash_case_convert(widget_class) }}"
{{- widget.field.widget.attrs.hidden|yesno(' hidden,') -}}>
<div class="errors-wrapper">
{% if widget.errors -%}
<div class="alert alert-danger widget-error" role="alert">
{% for error in widget.errors -%}
<p class="error-item idx-{{ loop.index0 }}">
{{- error -}}
</p>
{%- endfor %}
</div>
{%- else -%}
{# <div class="error-placeholder">&nbsp;</div> #}
{%- endif %}
</div>
<div>
{% if widget_class == 'CheckboxInput' -%}
<div class="form-check form-switch">
{{ widget|set_attr('role:switch') }}
<label class="form-check-label" for="{{ widget.auto_id }}">
{{- widget.label -}}
</label>
{% if widget.help_text -%}
<p class="text-start text-body-secondary help-text-wrapper">
<small class="help-text">
{{- widget.help_text -}}
</small>
</p>
{%- endif %}
</div>
{%- elif widget_class in ['Select', 'SelectMultiple', 'LazySelect'] -%}
<div class="form-floating">
{{ widget|add_class('form-select') }}
<label for="{{ widget.auto_id }}">{{ widget.label }}</label>
{% if widget.help_text -%}
<p class="text-start text-body-secondary help-text-wrapper">
<small class="help-text">
{{- widget.help_text -}}
</small>
</p>
{%- endif %}
</div>
{%- elif widget_class == 'FileInput' -%}
<div class="form-floating">
<label for="{{ widget.auto_id }}">{{ widget.label }}</label>
{%- set placeholder = 'placeholder:' + widget.field.widget.attrs.placeholder|default('') -%}
{{ widget|add_class('form-control')|set_attr(placeholder)}}
{% if widget.help_text -%}
<p class="text-start text-body-secondary help-text-wrapper">
<small class="help-text">
{{- widget.help_text -}}
</small>
</p>
{%- endif %}
</div>
{%- elif widget_class == 'RadioSelect' -%}
<div class="radio-select-group form-floating">
{%- for group, options, index in widget.optgroups %}
{%- if group %}
<div>
<legend>{{ group }}</legend>
{%- for widget in options %}
{{ _render_radio(widget=widget) }}
{% endfor -%}
</div>
{%- else -%}
{%- for widget in options %}
{{ _render_radio(widget=widget) }}
{% endfor -%}
{% endif -%}
{% endfor -%}
</div>
{%- else -%}
<div class="form-floating">
{%- set placeholder = 'placeholder:' + widget.field.widget.attrs.placeholder|default('') -%}
{{ widget|add_class('form-control')|set_attr(placeholder) }}
<label for="{{ widget.auto_id }}">
{{- widget.label -}}
</label>
</div>
{% if widget.help_text -%}
<p class="text-start text-body-secondary help-text-wrapper">
<small class="help-text">
{{- widget.help_text -}}
</small>
</p>
{%- endif %}
{%- endif %}
</div>
</div>
{%- endif %}
{%- endmacro %}
{% macro _render_radio(widget) -%}
{{ widget|add_class('btn-check')|set_attr('autocomplete:off') }}
<label class="btn-btn-secondary" for="{{ widget.auto_id }}">
{{- widget.label -}}
</label>
{% if widget.help_text -%}
<p class="text-start text-body-secondary help-text-wrapper">
<small class="help-text">
{{- widget.help_text -}}
</small>
</p>
{%- endif %}
{%- endmacro %}

View file

@ -0,0 +1,18 @@
{% macro render_messages() -%}
{% for message in messages.get_messages(request) -%}
{%- set level_class = message.level_tag -%}
{%- set extra_tags = '' -%}
{% if message.extra_tags -%}
{%- set extra_tags = ' ' + message.extra_tags -%}
{%- endif %}
{% if message.level_tag == 'error' -%}
{%- set level_class = 'danger' -%}
{%- endif %}
<div class="alert alert-{{ level_class }} alert-dismissible fade show{{ extra_tags }}" role="alert" data-type="alert-rendered">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<div class="alert-content">
{{- message|safe if 'is-htmlsafe' in extra_tags else message -}}
</div>
</div>
{%- endfor %}
{%- endmacro %}