Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Imports
3from django.conf import settings
4from django.core.exceptions import ImproperlyConfigured
5import os
6from superdjango.utils import camelcase_to_underscore
7from .library import FieldGroup
9# Exports
11__all__ = (
12 "get_field_template",
13 "get_field_type",
14 "get_html_framework",
15 "get_html_path",
16 "get_input_type",
17 "is_required_field",
18 "HTMLFramework",
19)
21# Functions
24def get_field_template(instance):
25 """Get the template to use for a given field instance.
27 :param instance: The field instance to be checked.
28 :type instance: BaseType[Field]
30 :rtype: str
32 """
33 from .shortcuts import template_exists
35 field_type = camelcase_to_underscore(get_field_type(instance)).replace("_field", "")
36 input_type = camelcase_to_underscore(get_input_type(instance)).replace("_widget", "")
38 # textarea simply becomes text.
39 if input_type == "textarea":
40 input_type = "text"
42 # In some cases, the input type (based on the widget) indicates the field template that should be used. This allows
43 # the wrapper templates in html/forms/fields to do their job, but should also make it possible to specify a custom
44 # template.
45 template = "html/forms/fields/%s.html" % input_type
46 if template_exists(template):
47 # print("%s(field_type=%s, input_type=%s, template=%s)" % (instance.name, field_type, input_type, template))
48 return template
50 # Deal with special Django fields.
51 if field_type == "username":
52 return "html/forms/fields/char.html"
54 # In remaining cases, we attempt to use the field type.
55 template = "html/forms/fields/%s.html" % field_type
56 if template_exists(template):
57 # print("%s(field_type=%s, input_type=%s, template=%s)" % (instance.name, field_type, input_type, template))
58 return template
60 # print("%s(field_type=%s, input_type=%s)" % (instance.name, field_type, input_type))
61 return "html/forms/fields/char.html"
63 # if field_type == "username":
64 # return "html/forms/"
66 # field_type = get_field_type(instance).replace("Field", "").lower()
67 # input_type = get_input_type(instance).lower()
68 #
69 # if field_type == "char":
70 # if input_type == "codeeditorwidget":
71 # file = "code_editor.html"
72 # elif input_type == "markdownwidget":
73 # file = "markdown.html"
74 # elif input_type == "textarea":
75 # file = "text.html"
76 # else:
77 # file = "char.html"
78 # elif field_type == "username":
79 # # This is the UsernameField in Django's standard AuthenticationForm.
80 # file = "char.html"
81 # else:
82 # if input_type == "chooserwidget":
83 # file = "chooser.html"
84 # else:
85 # file = "%s.html" % field_type
86 #
87 # # print("%s:" % instance.name, get_field_type(instance), field_type, input_type, file)
88 #
89 # return "html/forms/fields/%s" % file
91 # widget = instance.field.widget.__class__.__name__
92 # file = camelcase_to_underscore(widget).replace("_", "-") + ".html"
93 #
94 # return "html/forms/fields/%s" % file
97def get_field_type(instance):
98 """Get the type of field for a given instance.
100 :param instance: The field instance to be checked.
101 :type instance: Type[Field]
103 :rtype: str
105 """
106 return instance.field.__class__.__name__
107 # return instance.field.__class__.__name__.replace("Field", "").lower()
110def get_html_framework():
111 """Get the framework to use for rendering standard HTM Gel templates.
113 :rtype: str
114 :raise: ImproperlyConfigured
116 """
117 if HTMLFramework.is_bootstrap():
118 return "bootstrap4"
119 elif HTMLFramework.is_foundation():
120 return "foundation6"
121 elif HTMLFramework.is_uikit():
122 return "uikit3"
123 elif hasattr(settings, "HTML_FRAMEWORK"):
124 return settings.HTML_FRAMEWORK
125 else:
126 raise ImproperlyConfigured("The SuperDjango HTML framework has not been defined.")
129def get_html_path(prefix="html"):
130 """Get the path to standard HTM Gel templates.
132 :param prefix: The prefix or starting point of the path. This may be given as ``["superdjango", "ui"]`` or
133 ``["superdjango", "views"]`` or a custom prefix to use templates that you've created.
134 :type prefix: list | str | tuple
136 :rtype: str
137 :raise: ImproperlyConfigured
139 """
141 if type(prefix) is str:
142 prefix = [prefix]
144 return os.path.join(*prefix, "_frameworks", get_html_framework())
147def get_input_type(instance):
148 """Get the type of field for a given instance.
150 :param instance: The field instance to be checked.
151 :type instance: Type[Field]
153 :rtype: str
155 """
156 if isinstance(instance, FieldGroup):
157 return "fieldgroup"
159 return instance.field.widget.__class__.__name__
162def is_required_field(instance):
163 """Determine if the given field is required.
165 :param instance: The field instance to be checked.
166 :type instance: Type[Field]
168 :rtype: bool
170 """
171 try:
172 return instance.field.required
173 except AttributeError:
174 pass
176 try:
177 return instance.required
178 except AttributeError:
179 pass
181 return False
183# Classes
186class HTMLFramework(object):
187 """A utility class which encapsulates functionality for identifying the current HTML framework."""
189 @classmethod
190 def is_bootstrap(cls):
191 """Indicates the use of Twitter Bootstrap.
193 :rtype: bool
195 """
196 return "superdjango.html.frameworks.bootstrap4" in settings.INSTALLED_APPS
198 @classmethod
199 def is_foundation(cls):
200 """Indicates the use of Twitter Bootstrap.
202 :rtype: bool
204 """
205 return "superdjango.html.frameworks.foundation6" in settings.INSTALLED_APPS
207 @classmethod
208 def is_uikit(cls):
209 """Indicates the use of Twitter Bootstrap.
211 :rtype: bool
213 """
214 return "superdjango.html.frameworks.uikit3" in settings.INSTALLED_APPS
216 @classmethod
217 def get_path(cls, *parts, prefix="html"):
218 """As with ``path()``, but joins the given parts relative to the path of the HTML framework."""
219 base = cls.path(prefix=prefix)
220 return os.path.join(base, *parts)
222 @classmethod
223 def path(cls, prefix="html"):
224 """Get the path to the framework. See :py:func:`get_html_path`."""
225 return get_html_path(prefix=prefix)