df_site 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- df_site/__init__.py +1 -0
- df_site/__main__.py +37 -0
- df_site/admin.py +130 -0
- df_site/apps.py +57 -0
- df_site/components/__init__.py +1 -0
- df_site/components/base.py +82 -0
- df_site/components/detail.py +191 -0
- df_site/components/list.py +446 -0
- df_site/components/list_filters.py +74 -0
- df_site/components/registry.py +55 -0
- df_site/constants.py +71 -0
- df_site/context_processors.py +61 -0
- df_site/defaults.py +319 -0
- df_site/dynamic_settings.py +37 -0
- df_site/form_fields.py +138 -0
- df_site/management/__init__.py +1 -0
- df_site/management/commands/__init__.py +1 -0
- df_site/management/commands/add_image.py +104 -0
- df_site/management/commands/generate_favicon.py +47 -0
- df_site/middleware.py +20 -0
- df_site/migrations/0001_initial.py +220 -0
- df_site/migrations/0002_alter_alertribbon_message_alter_alertribbon_summary.py +23 -0
- df_site/migrations/__init__.py +0 -0
- df_site/model_fields.py +35 -0
- df_site/models.py +130 -0
- df_site/postman/__init__.py +1 -0
- df_site/postman/forms.py +38 -0
- df_site/postman/urls.py +75 -0
- df_site/postman/views.py +65 -0
- df_site/static/css/app.css +0 -0
- df_site/static/css/base.css +22208 -0
- df_site/static/css/ckeditor5.css +422 -0
- df_site/static/favicon/android-chrome-192x192.png +0 -0
- df_site/static/favicon/android-chrome-512x512.png +0 -0
- df_site/static/favicon/apple-touch-icon.png +0 -0
- df_site/static/favicon/favicon-16x16.png +0 -0
- df_site/static/favicon/favicon-32x32.png +0 -0
- df_site/static/favicon/favicon.ico +0 -0
- df_site/static/favicon/mstile-150x150.png +0 -0
- df_site/static/favicon/safari-pinned-tab.svg +46 -0
- df_site/static/images/accessibility.svg +1 -0
- df_site/static/images/align-bottom.svg +1 -0
- df_site/static/images/align-center.svg +1 -0
- df_site/static/images/align-justify.svg +1 -0
- df_site/static/images/align-left.svg +1 -0
- df_site/static/images/align-middle.svg +1 -0
- df_site/static/images/align-right.svg +1 -0
- df_site/static/images/align-top.svg +1 -0
- df_site/static/images/bold.svg +1 -0
- df_site/static/images/browse-files.svg +1 -0
- df_site/static/images/bulletedlist.svg +1 -0
- df_site/static/images/cancel.svg +1 -0
- df_site/static/images/caption.svg +1 -0
- df_site/static/images/check.svg +1 -0
- df_site/static/images/code.svg +1 -0
- df_site/static/images/codeblock.svg +1 -0
- df_site/static/images/cog.svg +1 -0
- df_site/static/images/color-palette.svg +1 -0
- df_site/static/images/color-tile-check.svg +1 -0
- df_site/static/images/drag-handle.svg +1 -0
- df_site/static/images/drag-indicator.svg +1 -0
- df_site/static/images/dropdown-arrow.svg +1 -0
- df_site/static/images/eraser.svg +1 -0
- df_site/static/images/file-arrow-up-solid.svg +1 -0
- df_site/static/images/find-replace.svg +1 -0
- df_site/static/images/font-background.svg +1 -0
- df_site/static/images/font-color.svg +1 -0
- df_site/static/images/font-family.svg +1 -0
- df_site/static/images/font-size.svg +1 -0
- df_site/static/images/heading1.svg +1 -0
- df_site/static/images/heading2.svg +1 -0
- df_site/static/images/heading3.svg +1 -0
- df_site/static/images/heading4.svg +1 -0
- df_site/static/images/heading5.svg +1 -0
- df_site/static/images/heading6.svg +1 -0
- df_site/static/images/history.svg +1 -0
- df_site/static/images/horizontalline.svg +1 -0
- df_site/static/images/html.svg +1 -0
- df_site/static/images/image-asset-manager.svg +1 -0
- df_site/static/images/image-upload.svg +1 -0
- df_site/static/images/image-url.svg +1 -0
- df_site/static/images/image.svg +1 -0
- df_site/static/images/importexport.svg +1 -0
- df_site/static/images/indent.svg +1 -0
- df_site/static/images/italic.svg +1 -0
- df_site/static/images/link.svg +1 -0
- df_site/static/images/liststylecircle.svg +1 -0
- df_site/static/images/liststyledecimal.svg +1 -0
- df_site/static/images/liststyledecimalleadingzero.svg +1 -0
- df_site/static/images/liststyledisc.svg +1 -0
- df_site/static/images/liststylelowerlatin.svg +1 -0
- df_site/static/images/liststylelowerroman.svg +1 -0
- df_site/static/images/liststylesquare.svg +1 -0
- df_site/static/images/liststyleupperlatin.svg +1 -0
- df_site/static/images/liststyleupperroman.svg +1 -0
- df_site/static/images/loupe.svg +1 -0
- df_site/static/images/low-vision.svg +1 -0
- df_site/static/images/marker.svg +1 -0
- df_site/static/images/media-placeholder.svg +1 -0
- df_site/static/images/media.svg +1 -0
- df_site/static/images/next-arrow.svg +1 -0
- df_site/static/images/numberedlist.svg +1 -0
- df_site/static/images/object-center.svg +1 -0
- df_site/static/images/object-full-width.svg +1 -0
- df_site/static/images/object-inline-left.svg +1 -0
- df_site/static/images/object-inline-right.svg +1 -0
- df_site/static/images/object-inline.svg +1 -0
- df_site/static/images/object-left.svg +1 -0
- df_site/static/images/object-right.svg +1 -0
- df_site/static/images/object-size-custom.svg +1 -0
- df_site/static/images/object-size-full.svg +1 -0
- df_site/static/images/object-size-large.svg +1 -0
- df_site/static/images/object-size-medium.svg +1 -0
- df_site/static/images/object-size-small.svg +1 -0
- df_site/static/images/outdent.svg +1 -0
- df_site/static/images/paragraph.svg +1 -0
- df_site/static/images/pen.svg +1 -0
- df_site/static/images/pencil.svg +1 -0
- df_site/static/images/pilcrow.svg +1 -0
- df_site/static/images/plus.svg +1 -0
- df_site/static/images/previous-arrow.svg +1 -0
- df_site/static/images/project-logo.svg +1 -0
- df_site/static/images/quote.svg +1 -0
- df_site/static/images/redo.svg +1 -0
- df_site/static/images/remove-format.svg +1 -0
- df_site/static/images/return-arrow.svg +1 -0
- df_site/static/images/select-all.svg +1 -0
- df_site/static/images/show-blocks.svg +1 -0
- df_site/static/images/source-editing.svg +1 -0
- df_site/static/images/specialcharacters.svg +1 -0
- df_site/static/images/strikethrough.svg +1 -0
- df_site/static/images/subscript.svg +1 -0
- df_site/static/images/superscript.svg +1 -0
- df_site/static/images/table-cell-properties.svg +1 -0
- df_site/static/images/table-column.svg +1 -0
- df_site/static/images/table-merge-cell.svg +1 -0
- df_site/static/images/table-properties.svg +1 -0
- df_site/static/images/table-row.svg +1 -0
- df_site/static/images/table.svg +1 -0
- df_site/static/images/text-alternative.svg +1 -0
- df_site/static/images/text.svg +1 -0
- df_site/static/images/three-vertical-dots.svg +1 -0
- df_site/static/images/todolist.svg +1 -0
- df_site/static/images/underline.svg +1 -0
- df_site/static/images/undo.svg +1 -0
- df_site/static/images/unlink.svg +1 -0
- df_site/static/js/app.js +98 -0
- df_site/static/js/app.js.map +1 -0
- df_site/static/js/base.js +161181 -0
- df_site/static/js/base.js.map +1 -0
- df_site/static/translations/af.js +1 -0
- df_site/static/translations/ar.js +1 -0
- df_site/static/translations/ast.js +1 -0
- df_site/static/translations/az.js +1 -0
- df_site/static/translations/bg.js +1 -0
- df_site/static/translations/bn.js +1 -0
- df_site/static/translations/bs.js +1 -0
- df_site/static/translations/ca.js +1 -0
- df_site/static/translations/cs.js +1 -0
- df_site/static/translations/da.js +1 -0
- df_site/static/translations/de-ch.js +1 -0
- df_site/static/translations/de.js +1 -0
- df_site/static/translations/el.js +1 -0
- df_site/static/translations/en-au.js +1 -0
- df_site/static/translations/en-gb.js +1 -0
- df_site/static/translations/en.js +1 -0
- df_site/static/translations/eo.js +1 -0
- df_site/static/translations/es-co.js +1 -0
- df_site/static/translations/es.js +1 -0
- df_site/static/translations/et.js +1 -0
- df_site/static/translations/eu.js +1 -0
- df_site/static/translations/fa.js +1 -0
- df_site/static/translations/fi.js +1 -0
- df_site/static/translations/gl.js +1 -0
- df_site/static/translations/gu.js +1 -0
- df_site/static/translations/he.js +1 -0
- df_site/static/translations/hi.js +1 -0
- df_site/static/translations/hr.js +1 -0
- df_site/static/translations/hu.js +1 -0
- df_site/static/translations/hy.js +1 -0
- df_site/static/translations/id.js +1 -0
- df_site/static/translations/it.js +1 -0
- df_site/static/translations/ja.js +1 -0
- df_site/static/translations/jv.js +1 -0
- df_site/static/translations/kk.js +1 -0
- df_site/static/translations/km.js +1 -0
- df_site/static/translations/kn.js +1 -0
- df_site/static/translations/ko.js +1 -0
- df_site/static/translations/ku.js +1 -0
- df_site/static/translations/lt.js +1 -0
- df_site/static/translations/lv.js +1 -0
- df_site/static/translations/ms.js +1 -0
- df_site/static/translations/nb.js +1 -0
- df_site/static/translations/ne.js +1 -0
- df_site/static/translations/nl.js +1 -0
- df_site/static/translations/no.js +1 -0
- df_site/static/translations/oc.js +1 -0
- df_site/static/translations/pl.js +1 -0
- df_site/static/translations/pt-br.js +1 -0
- df_site/static/translations/pt.js +1 -0
- df_site/static/translations/ro.js +1 -0
- df_site/static/translations/ru.js +1 -0
- df_site/static/translations/si.js +1 -0
- df_site/static/translations/sk.js +1 -0
- df_site/static/translations/sl.js +1 -0
- df_site/static/translations/sq.js +1 -0
- df_site/static/translations/sr-latn.js +1 -0
- df_site/static/translations/sr.js +1 -0
- df_site/static/translations/sv.js +1 -0
- df_site/static/translations/th.js +1 -0
- df_site/static/translations/ti.js +1 -0
- df_site/static/translations/tk.js +1 -0
- df_site/static/translations/tr.js +1 -0
- df_site/static/translations/tt.js +1 -0
- df_site/static/translations/ug.js +1 -0
- df_site/static/translations/uk.js +1 -0
- df_site/static/translations/ur.js +1 -0
- df_site/static/translations/uz.js +1 -0
- df_site/static/translations/vi.js +1 -0
- df_site/static/translations/zh-cn.js +1 -0
- df_site/static/translations/zh.js +1 -0
- df_site/static/webfonts/fa-brands-400.ttf +0 -0
- df_site/static/webfonts/fa-brands-400.woff2 +0 -0
- df_site/static/webfonts/fa-regular-400.ttf +0 -0
- df_site/static/webfonts/fa-regular-400.woff2 +0 -0
- df_site/static/webfonts/fa-solid-900.ttf +0 -0
- df_site/static/webfonts/fa-solid-900.woff2 +0 -0
- df_site/static/webfonts/fa-v4compatibility.ttf +0 -0
- df_site/static/webfonts/fa-v4compatibility.woff2 +0 -0
- df_site/templates/account/email.html +78 -0
- df_site/templates/account/password_change.html +28 -0
- df_site/templates/account/snippets/warn_no_email.html +6 -0
- df_site/templates/allauth/elements/alert.html +6 -0
- df_site/templates/allauth/elements/badge.html +4 -0
- df_site/templates/allauth/elements/button.html +14 -0
- df_site/templates/allauth/elements/button_group.html +5 -0
- df_site/templates/allauth/elements/field.html +72 -0
- df_site/templates/allauth/elements/fields.html +3 -0
- df_site/templates/allauth/elements/form.html +10 -0
- df_site/templates/allauth/elements/h1.html +1 -0
- df_site/templates/allauth/elements/h2.html +1 -0
- df_site/templates/allauth/elements/img.html +4 -0
- df_site/templates/allauth/elements/p.html +1 -0
- df_site/templates/allauth/elements/panel.html +14 -0
- df_site/templates/allauth/elements/provider.html +6 -0
- df_site/templates/allauth/elements/provider_list.html +5 -0
- df_site/templates/allauth/elements/table.html +5 -0
- df_site/templates/allauth/layouts/base.html +14 -0
- df_site/templates/allauth/layouts/entrance.html +20 -0
- df_site/templates/allauth/layouts/manage.html +1 -0
- df_site/templates/cookie_consent/_cookie_group.html +64 -0
- df_site/templates/cookie_consent/cookiegroup_list.html +23 -0
- df_site/templates/df_components/base.html +0 -0
- df_site/templates/df_components/detail.html +12 -0
- df_site/templates/df_components/detail_fieldset.html +46 -0
- df_site/templates/df_components/list.html +42 -0
- df_site/templates/df_components/list_filter.html +13 -0
- df_site/templates/df_components/list_filters.html +36 -0
- df_site/templates/df_components/list_hierarchy.html +25 -0
- df_site/templates/df_components/list_pagination.html +39 -0
- df_site/templates/df_components/list_search_form.html +38 -0
- df_site/templates/df_components/list_table.html +35 -0
- df_site/templates/df_site/app.html +1 -0
- df_site/templates/df_site/base.html +221 -0
- df_site/templates/df_site/detail.html +8 -0
- df_site/templates/df_site/humans.txt +11 -0
- df_site/templates/df_site/manage_base.html +51 -0
- df_site/templates/df_site/popup_app.html +1 -0
- df_site/templates/df_site/popup_base.html +29 -0
- df_site/templates/df_site/security.txt +5 -0
- df_site/templates/django_bootstrap5/breadcrumb.html +17 -0
- df_site/templates/django_bootstrap5/pagination.html +40 -0
- df_site/templates/django_ckeditor_5/widget.html +13 -0
- df_site/templates/favicon/browserconfig.xml +9 -0
- df_site/templates/mfa/index.html +115 -0
- df_site/templates/mfa/recovery_codes/index.html +33 -0
- df_site/templates/mfa/webauthn/authenticator_list.html +74 -0
- df_site/templates/pipeline/css.html +1 -0
- df_site/templates/pipeline/js.html +1 -0
- df_site/templates/postman/archives.html +8 -0
- df_site/templates/postman/base.html +20 -0
- df_site/templates/postman/base_folder.html +71 -0
- df_site/templates/postman/base_write.html +26 -0
- df_site/templates/postman/inbox.html +7 -0
- df_site/templates/postman/inc_subject_ex.html +21 -0
- df_site/templates/postman/trash.html +12 -0
- df_site/templates/postman/view.html +64 -0
- df_site/templates/users/settings.html +26 -0
- df_site/templates/usersessions/usersession_list.html +70 -0
- df_site/templatetags/__init__.py +1 -0
- df_site/templatetags/df_site.py +241 -0
- df_site/templatetags/images.py +515 -0
- df_site/templatetags/pipeline_sri.py +97 -0
- df_site/testing/__init__.py +1 -0
- df_site/testing/multiple_views.py +369 -0
- df_site/testing/requests.py +299 -0
- df_site/urls.py +41 -0
- df_site/user_settings.py +69 -0
- df_site/users/__init__.py +1 -0
- df_site/users/forms.py +35 -0
- df_site/users/notifications.py +14 -0
- df_site/users/urls.py +17 -0
- df_site/users/views.py +75 -0
- df_site/views.py +122 -0
- df_site-0.1.0.dist-info/LICENSE +519 -0
- df_site-0.1.0.dist-info/METADATA +217 -0
- df_site-0.1.0.dist-info/RECORD +309 -0
- df_site-0.1.0.dist-info/WHEEL +4 -0
- df_site-0.1.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
{% extends "usersessions/base_manage.html" %}
|
2
|
+
{% load allauth %}
|
3
|
+
{% load i18n %}
|
4
|
+
{% load humanize %}
|
5
|
+
{% block head_title %}
|
6
|
+
{% trans "Sessions" %}
|
7
|
+
{% endblock head_title %}
|
8
|
+
{% block content %}
|
9
|
+
{% element h1 tags="usersessions,list" %}
|
10
|
+
{% trans "Sessions" %}
|
11
|
+
{% endelement %}
|
12
|
+
{% if session_count > 1 %}
|
13
|
+
{% url 'usersessions_list' as action_url %}
|
14
|
+
{% else %}
|
15
|
+
{% url 'account_logout' as action_url %}
|
16
|
+
{% endif %}
|
17
|
+
{% element form action=action_url method="post" tags="sessions" no_visible_fields=True %}
|
18
|
+
{% slot body %}
|
19
|
+
{% csrf_token %}
|
20
|
+
{% element table tags="sessions" %}
|
21
|
+
<thead>
|
22
|
+
<tr>
|
23
|
+
<th class="fs-6">{% translate "Started At" %}</th>
|
24
|
+
<th class="">{% translate "IP Address" %}</th>
|
25
|
+
<th class="">{% translate "Browser" %}</th>
|
26
|
+
{% if show_last_seen_at %}
|
27
|
+
<th class="">{% translate "Last seen at" %}</th>
|
28
|
+
{% endif %}
|
29
|
+
<th></th>
|
30
|
+
</tr>
|
31
|
+
</thead>
|
32
|
+
<tbody>
|
33
|
+
{% for session in sessions %}
|
34
|
+
<tr>
|
35
|
+
<td>
|
36
|
+
<span title="{{ session.created_at }}">{{ session.created_at|naturaltime }}</span>
|
37
|
+
</td>
|
38
|
+
<td>{{ session.ip }}</td>
|
39
|
+
<td>{{ session.user_agent }}</td>
|
40
|
+
{% if show_last_seen_at %}
|
41
|
+
<td>
|
42
|
+
<span title="{{ session.last_seen_at }}">{{ session.last_seen_at|naturaltime }}</span>
|
43
|
+
</td>
|
44
|
+
{% endif %}
|
45
|
+
<td>
|
46
|
+
{% if session.is_current %}
|
47
|
+
{% element badge tags="session,current" %}
|
48
|
+
{% translate "Current" %}
|
49
|
+
{% endelement %}
|
50
|
+
{% else %}
|
51
|
+
{% endif %}
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
{% endfor %}
|
55
|
+
</tbody>
|
56
|
+
{% endelement %}
|
57
|
+
{% endslot %}
|
58
|
+
{% slot actions %}
|
59
|
+
{% if session_count > 1 %}
|
60
|
+
{% element button type="submit" %}
|
61
|
+
{% translate "Sign Out Other Sessions" %}
|
62
|
+
{% endelement %}
|
63
|
+
{% else %}
|
64
|
+
{% element button type="submit" %}
|
65
|
+
{% translate "Sign Out" %}
|
66
|
+
{% endelement %}
|
67
|
+
{% endif %}
|
68
|
+
{% endslot %}
|
69
|
+
{% endelement %}
|
70
|
+
{% endblock content %}
|
@@ -0,0 +1 @@
|
|
1
|
+
"""Template tags for df_site app."""
|
@@ -0,0 +1,241 @@
|
|
1
|
+
"""Custom template tags for the df_site app."""
|
2
|
+
|
3
|
+
import datetime
|
4
|
+
import re
|
5
|
+
from html import escape
|
6
|
+
from typing import Dict, List, Optional, Union
|
7
|
+
|
8
|
+
from django import template
|
9
|
+
from django.conf import settings
|
10
|
+
from django.contrib.admin.views.main import PAGE_VAR
|
11
|
+
from django.core.paginator import Paginator
|
12
|
+
from django.template.base import kwarg_re
|
13
|
+
from django.template.defaultfilters import date
|
14
|
+
from django.template.defaulttags import URLNode
|
15
|
+
from django.template.exceptions import TemplateSyntaxError
|
16
|
+
from django.template.loader import render_to_string
|
17
|
+
from django.utils.safestring import mark_safe
|
18
|
+
|
19
|
+
from df_site.components.base import Component
|
20
|
+
from df_site.constants import BRAND_ICONS, INT_RE
|
21
|
+
|
22
|
+
register = template.Library()
|
23
|
+
|
24
|
+
|
25
|
+
@register.filter()
|
26
|
+
def abs_url(value):
|
27
|
+
"""Given a relative URL, return an absolute URL."""
|
28
|
+
if value and value.startswith("/"):
|
29
|
+
base_url = settings.SERVER_BASE_URL
|
30
|
+
if base_url.endswith("/"):
|
31
|
+
base_url = base_url[:-1]
|
32
|
+
return mark_safe(f"{base_url}{value}") # noqa
|
33
|
+
return value
|
34
|
+
|
35
|
+
|
36
|
+
class AbsoluteURLNode(URLNode):
|
37
|
+
"""A template node that renders an absolute URL."""
|
38
|
+
|
39
|
+
def render(self, context):
|
40
|
+
"""Render the URL node prefixed with the server base URL."""
|
41
|
+
rendered = super().render(context)
|
42
|
+
return abs_url(rendered)
|
43
|
+
|
44
|
+
|
45
|
+
@register.simple_tag(takes_context=True)
|
46
|
+
def paginate_qs(context, queryset, per_page=10, page_attr="page"):
|
47
|
+
"""Paginate a queryset and store the pagination in the context."""
|
48
|
+
paginator = Paginator(queryset, per_page)
|
49
|
+
page_number = context["request"].GET.get(page_attr, "1")
|
50
|
+
if INT_RE.match(page_number):
|
51
|
+
page = paginator.get_page(int(page_number))
|
52
|
+
else:
|
53
|
+
page = paginator.get_page(1)
|
54
|
+
return page
|
55
|
+
|
56
|
+
|
57
|
+
@register.tag(name="abs_url")
|
58
|
+
def abs_url_tag(parser, token):
|
59
|
+
"""Like the default Django's url tag, but return absolute URLs."""
|
60
|
+
bits = token.split_contents()
|
61
|
+
if len(bits) < 2:
|
62
|
+
raise TemplateSyntaxError(f"'{bits[0]}' takes at least one argument, a URL pattern name.")
|
63
|
+
viewname = parser.compile_filter(bits[1])
|
64
|
+
args = []
|
65
|
+
kwargs = {}
|
66
|
+
asvar = None
|
67
|
+
bits = bits[2:]
|
68
|
+
if len(bits) >= 2 and bits[-2] == "as":
|
69
|
+
asvar = bits[-1]
|
70
|
+
bits = bits[:-2]
|
71
|
+
|
72
|
+
for bit in bits:
|
73
|
+
match = kwarg_re.match(bit)
|
74
|
+
if not match:
|
75
|
+
raise TemplateSyntaxError("Malformed arguments to url tag")
|
76
|
+
name, value = match.groups()
|
77
|
+
if name:
|
78
|
+
kwargs[name] = parser.compile_filter(value)
|
79
|
+
else:
|
80
|
+
args.append(parser.compile_filter(value))
|
81
|
+
return AbsoluteURLNode(viewname, args, kwargs, asvar)
|
82
|
+
|
83
|
+
|
84
|
+
@register.filter
|
85
|
+
def fa6_allauth_icon(provider_id):
|
86
|
+
"""Return the font-awesome icon name for a given allauth provider."""
|
87
|
+
return BRAND_ICONS.get(provider_id, "key")
|
88
|
+
|
89
|
+
|
90
|
+
@register.simple_tag
|
91
|
+
def fa6_icon(
|
92
|
+
name,
|
93
|
+
prefix="fa",
|
94
|
+
large: Union[int, bool] = False,
|
95
|
+
fixed: bool = False,
|
96
|
+
spin: bool = False,
|
97
|
+
li: bool = False,
|
98
|
+
rotate: Union[int, bool] = None,
|
99
|
+
border: bool = False,
|
100
|
+
color: str = None,
|
101
|
+
):
|
102
|
+
"""Add font-awesome icons in your HTML code."""
|
103
|
+
if isinstance(large, int) and 2 <= large <= 5:
|
104
|
+
large = f" fa-{large:d}x"
|
105
|
+
elif large:
|
106
|
+
large = " fa-lg"
|
107
|
+
else:
|
108
|
+
large = ""
|
109
|
+
content = '<i class="{prefix} fa-{name}{large}{fixed}{spin}{li}{rotate}{border}{color}"></i>'.format(
|
110
|
+
prefix=prefix,
|
111
|
+
name=name,
|
112
|
+
large=large,
|
113
|
+
fixed=" fa-fw" if fixed else "",
|
114
|
+
spin=" fa-spin" if spin else "",
|
115
|
+
li=" fa-li" if li else "",
|
116
|
+
rotate=f" fa-rotate-{rotate}" if rotate else "",
|
117
|
+
border=" fa-border" if border else "",
|
118
|
+
color=f"text-{color}" if color else "",
|
119
|
+
)
|
120
|
+
return mark_safe(content) # noqa
|
121
|
+
|
122
|
+
|
123
|
+
@register.simple_tag
|
124
|
+
def bootstrap_breadcrumb(
|
125
|
+
breadcrumbs: List[Dict[str, Union[str, bool]]], last_active: bool = True, extra_classes: str = ""
|
126
|
+
):
|
127
|
+
"""Render an breadcrumb.
|
128
|
+
|
129
|
+
**Tag name**::
|
130
|
+
|
131
|
+
bootstrap_breadcrumb
|
132
|
+
|
133
|
+
**Parameters**::
|
134
|
+
|
135
|
+
breadcrumbs
|
136
|
+
List of dictionaries with the following keys:
|
137
|
+
`link`: URL to link to
|
138
|
+
`title`: Text to display
|
139
|
+
`active`: boolean, element is active, meaning that the link is not displayed
|
140
|
+
|
141
|
+
last_active
|
142
|
+
boolean, last element is the active one
|
143
|
+
|
144
|
+
:default: ``True``
|
145
|
+
|
146
|
+
extra_classes
|
147
|
+
string, extra CSS classes for elements
|
148
|
+
|
149
|
+
:default: ""
|
150
|
+
|
151
|
+
**Usage**::
|
152
|
+
|
153
|
+
{% bootstrap_breadcrumb [{content}] %}
|
154
|
+
|
155
|
+
**Example**::
|
156
|
+
|
157
|
+
{% bootstrap_breadcrumb crumbs %}
|
158
|
+
"""
|
159
|
+
context = {
|
160
|
+
"breadcrumbs": breadcrumbs,
|
161
|
+
"last_active": last_active,
|
162
|
+
"extra_classes": extra_classes,
|
163
|
+
}
|
164
|
+
content = render_to_string("django_bootstrap5/breadcrumb.html", context)
|
165
|
+
return mark_safe(content) # noqa S308
|
166
|
+
|
167
|
+
|
168
|
+
@register.simple_tag(takes_context=True)
|
169
|
+
def component(context, comp: Component, **kwargs):
|
170
|
+
"""Render a HTML component in a template."""
|
171
|
+
text = comp.render(context, **kwargs)
|
172
|
+
return mark_safe(text) # noqa S308
|
173
|
+
|
174
|
+
|
175
|
+
@register.simple_tag
|
176
|
+
def component_list_url(cl, page: Optional[int] = None):
|
177
|
+
"""Generate an individual page index link in a paginated list."""
|
178
|
+
kwargs = {}
|
179
|
+
if page is not None:
|
180
|
+
kwargs[PAGE_VAR] = page
|
181
|
+
return cl.get_query_string(kwargs)
|
182
|
+
|
183
|
+
|
184
|
+
auto_pill_re = re.compile(r"^(.*)\((\d+)\)\s*$")
|
185
|
+
|
186
|
+
|
187
|
+
@register.simple_tag
|
188
|
+
def component_auto_badge(
|
189
|
+
value: str, color: str = "primary", extra_class: str = "rounded-pill", regex: re.Pattern = auto_pill_re
|
190
|
+
):
|
191
|
+
"""Automatically extracts suffixes between parenthesis `(.*)` and put them into badges."""
|
192
|
+
if hasattr(value, "__html__"):
|
193
|
+
raw_value = str(value)
|
194
|
+
else:
|
195
|
+
raw_value = escape(str(value))
|
196
|
+
if match := regex.match(raw_value):
|
197
|
+
prefix = match.group(1)
|
198
|
+
suffix = match.group(2)
|
199
|
+
new_value = f'{prefix}<span class="badge text-bg-{color} {extra_class}">{suffix}</span>'
|
200
|
+
value = mark_safe(new_value) # noqa S308
|
201
|
+
return value
|
202
|
+
|
203
|
+
|
204
|
+
@register.simple_tag
|
205
|
+
@register.filter
|
206
|
+
def schema_date(
|
207
|
+
value_: Optional[Union[datetime.date, datetime.datetime, datetime.timedelta]], fmt_: Optional[str] = None, **kwargs
|
208
|
+
):
|
209
|
+
"""Show a date in a <time></time> element.
|
210
|
+
|
211
|
+
Can be used as a filter or as a tag. In the latter case, value and format are the first two arguments.
|
212
|
+
Extra arguments are passed as attributes to the generated HTML.
|
213
|
+
|
214
|
+
`{% schema_date value_ fmt_ itemprop="start" %}` is rendered as
|
215
|
+
`<time itemprop="start" datetime="date">date</time>`
|
216
|
+
`{{ value_|schema_date:fmt_ }}` is rendered as `<time datetime="date">date</time>`
|
217
|
+
"""
|
218
|
+
content = date(value_, fmt_)
|
219
|
+
if isinstance(value_, datetime.date):
|
220
|
+
kwargs["datetime"] = value_.strftime("%Y-%m-%d")
|
221
|
+
elif isinstance(value_, datetime.datetime):
|
222
|
+
kwargs["datetime"] = value_.isoformat()
|
223
|
+
elif isinstance(value_, datetime.timedelta):
|
224
|
+
attr = "P"
|
225
|
+
ts = value_.total_seconds()
|
226
|
+
days = int(ts // 86400)
|
227
|
+
ts %= 86400
|
228
|
+
attr += f"{days}D"
|
229
|
+
hours = int(ts // 3600)
|
230
|
+
ts %= 3600
|
231
|
+
attr += f"{hours}H"
|
232
|
+
minutes = int(ts // 60)
|
233
|
+
ts %= 60
|
234
|
+
attr += f"{minutes}M{ts}S"
|
235
|
+
kwargs["datetime"] = attr
|
236
|
+
else:
|
237
|
+
return content
|
238
|
+
escaped = {escape(k): escape(v) for k, v in kwargs.items()}
|
239
|
+
attr = " ".join(f'{k}="{v}"' for k, v in escaped.items())
|
240
|
+
msg = f"<time {attr}>{content}</time>"
|
241
|
+
return mark_safe(msg) # noqa S308
|