dynamicforms 0.76.14__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.
- dynamicforms/__init__.py +8 -0
- dynamicforms/action.py +521 -0
- dynamicforms/apps.py +5 -0
- dynamicforms/fields.py +1570 -0
- dynamicforms/filters.py +44 -0
- dynamicforms/locale/en/LC_MESSAGES/django.po +67 -0
- dynamicforms/locale/en/LC_MESSAGES/djangojs.po +31 -0
- dynamicforms/locale/sl/LC_MESSAGES/django.po +71 -0
- dynamicforms/locale/sl/LC_MESSAGES/djangojs.po +36 -0
- dynamicforms/management/__init__.py +0 -0
- dynamicforms/management/commands/__init__.py +0 -0
- dynamicforms/management/commands/clean_dfpreuploaded_files.py +26 -0
- dynamicforms/migrations/__init__.py +0 -0
- dynamicforms/mixins/__init__.py +27 -0
- dynamicforms/mixins/action.py +14 -0
- dynamicforms/mixins/choice/__init__.py +94 -0
- dynamicforms/mixins/choice/allow_tags.py +79 -0
- dynamicforms/mixins/choice/null_choice.py +26 -0
- dynamicforms/mixins/choice/single_choice.py +21 -0
- dynamicforms/mixins/color_field.py +4 -0
- dynamicforms/mixins/conditional_visibility.py +193 -0
- dynamicforms/mixins/enable_copy.py +4 -0
- dynamicforms/mixins/field_render.py +209 -0
- dynamicforms/mixins/file_field.py +5 -0
- dynamicforms/mixins/help_text.py +46 -0
- dynamicforms/mixins/implicit_hidden.py +7 -0
- dynamicforms/mixins/implicit_natural_date.py +88 -0
- dynamicforms/mixins/null_value.py +15 -0
- dynamicforms/mixins/password_field.py +23 -0
- dynamicforms/mixins/related_field_ajax.py +142 -0
- dynamicforms/mixins/rtf_field.py +58 -0
- dynamicforms/models.py +5 -0
- dynamicforms/models_utils.py +33 -0
- dynamicforms/pagination.py +175 -0
- dynamicforms/preupload_files.py +42 -0
- dynamicforms/progress.py +71 -0
- dynamicforms/renderers.py +1 -0
- dynamicforms/routers.py +36 -0
- dynamicforms/serializers.py +486 -0
- dynamicforms/struct.py +40 -0
- dynamicforms/template_render/__init__.py +10 -0
- dynamicforms/template_render/layout.py +178 -0
- dynamicforms/template_render/mixins/__init__.py +0 -0
- dynamicforms/template_render/mixins/base.py +39 -0
- dynamicforms/template_render/mixins/field.py +74 -0
- dynamicforms/template_render/mixins/listserializer.py +100 -0
- dynamicforms/template_render/mixins/render_mode_enum.py +8 -0
- dynamicforms/template_render/mixins/serializer.py +301 -0
- dynamicforms/template_render/mixins/serializer_filter.py +19 -0
- dynamicforms/template_render/mixins/serializer_render_actions.py +21 -0
- dynamicforms/template_render/mixins/serializer_render_fields.py +57 -0
- dynamicforms/template_render/mixins/util.py +9 -0
- dynamicforms/template_render/renderer.py +38 -0
- dynamicforms/template_render/responsive_table_layout.py +64 -0
- dynamicforms/urls.py +9 -0
- dynamicforms/utils.py +32 -0
- dynamicforms/views.py +1 -0
- dynamicforms/viewsets.py +421 -0
- dynamicforms-0.76.14.dist-info/METADATA +129 -0
- dynamicforms-0.76.14.dist-info/RECORD +287 -0
- dynamicforms-0.76.14.dist-info/WHEEL +4 -0
- dynamicforms-0.76.14.dist-info/licenses/LICENSE +21 -0
- dynamicforms_legacy/__init__.py +8 -0
- dynamicforms_legacy/action.py +561 -0
- dynamicforms_legacy/apps.py +5 -0
- dynamicforms_legacy/context_processors.py +27 -0
- dynamicforms_legacy/dynamicforms_migration_mixin.py +42 -0
- dynamicforms_legacy/fields.py +1108 -0
- dynamicforms_legacy/filters.py +44 -0
- dynamicforms_legacy/migrations/__init__.py +0 -0
- dynamicforms_legacy/mixins/__init__.py +16 -0
- dynamicforms_legacy/mixins/action.py +14 -0
- dynamicforms_legacy/mixins/allow_tags.py +85 -0
- dynamicforms_legacy/mixins/enable_copy.py +4 -0
- dynamicforms_legacy/mixins/file_field.py +5 -0
- dynamicforms_legacy/mixins/help_text.py +38 -0
- dynamicforms_legacy/mixins/implicit_hidden.py +7 -0
- dynamicforms_legacy/mixins/implicit_natural_date.py +86 -0
- dynamicforms_legacy/mixins/null_choice.py +26 -0
- dynamicforms_legacy/mixins/null_value.py +15 -0
- dynamicforms_legacy/mixins/password_field.py +19 -0
- dynamicforms_legacy/mixins/related_field_ajax.py +58 -0
- dynamicforms_legacy/mixins/render.py +203 -0
- dynamicforms_legacy/mixins/rtf_field.py +52 -0
- dynamicforms_legacy/mixins/single_choice.py +21 -0
- dynamicforms_legacy/models.py +5 -0
- dynamicforms_legacy/pagination.py +168 -0
- dynamicforms_legacy/progress.py +71 -0
- dynamicforms_legacy/renderers.py +183 -0
- dynamicforms_legacy/serializers.py +335 -0
- dynamicforms_legacy/settings.py +196 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +587 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css +6834 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.eot +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.svg +288 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.js +2580 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.min.js +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/npm.js +13 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css +3719 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css +331 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css +8 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css +10038 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js +7013 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js +4435 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js.map +1 -0
- dynamicforms_legacy/static/ckeditor-df/ckEditorCustomBuildReadMe.txt +255 -0
- dynamicforms_legacy/static/ckeditor-df/ckeditor.js +6 -0
- dynamicforms_legacy/static/dynamicforms/dynamicforms.js +1883 -0
- dynamicforms_legacy/static/dynamicforms/icons/copy.svg +7 -0
- dynamicforms_legacy/static/dynamicforms/icons/eye-off-outline.svg +10 -0
- dynamicforms_legacy/static/dynamicforms/icons/eye-outline.svg +7 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_222222_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_228ef1_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ef8c08_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffd27a_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffffff_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.min.css +7 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.structure.min.css +5 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.theme.min.css +5 -0
- dynamicforms_legacy/static/jquery_ui/js/jquery-3.3.1.min.js +2 -0
- dynamicforms_legacy/static/jquery_ui/js/jquery-ui.min.js +13 -0
- dynamicforms_legacy/static/select2/css/select2-bootstrap3.min.css +7 -0
- dynamicforms_legacy/static/select2/css/select2-bootstrap4.min.css +578 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/css/select2.min.css +1 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/af.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ar.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/az.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bg.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bs.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ca.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/cs.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/da.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/de.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/dsb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/el.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/en.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/es.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/et.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/eu.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fa.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/gl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/he.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hsb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hu.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hy.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/id.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/is.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/it.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ja.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/km.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ko.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lt.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lv.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/mk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ms.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ps.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt-BR.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ro.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ru.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr-Cyrl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sv.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/th.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/tr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/uk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/vi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-CN.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-TW.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.js +6457 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.min.js +1 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.js +5746 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.min.js +1 -0
- dynamicforms_legacy/struct.py +40 -0
- dynamicforms_legacy/templates/dynamicforms/base.html +12 -0
- dynamicforms_legacy/templates/dynamicforms/base_form.html +44 -0
- dynamicforms_legacy/templates/dynamicforms/base_includes.html +51 -0
- dynamicforms_legacy/templates/dynamicforms/base_includes_select2.html +6 -0
- dynamicforms_legacy/templates/dynamicforms/base_list.html +47 -0
- dynamicforms_legacy/templates/dynamicforms/base_table_body.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/base_table_filter.html +44 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_form.html +10 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v3.html +90 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v4.html +77 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_list.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_body.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_filter.html +5 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field.html +41 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v3.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v4.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox_multiple.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/fieldset.html +21 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/form.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/input.html +31 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/list_fieldset.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/radio.html +8 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/rtf_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select_multiple.html +17 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/textarea.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog_rest.html +23 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/page.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/field/base_field.html +55 -0
- dynamicforms_legacy/templates/dynamicforms/field/checkbox.html +28 -0
- dynamicforms_legacy/templates/dynamicforms/field/checkbox_multiple.html +16 -0
- dynamicforms_legacy/templates/dynamicforms/field/dict_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/fieldset.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/form.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/field/input.html +31 -0
- dynamicforms_legacy/templates/dynamicforms/field/list_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/list_fieldset.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/radio.html +24 -0
- dynamicforms_legacy/templates/dynamicforms/field/rtf_field.html +14 -0
- dynamicforms_legacy/templates/dynamicforms/field/select.html +97 -0
- dynamicforms_legacy/templates/dynamicforms/field/select_multiple.html +67 -0
- dynamicforms_legacy/templates/dynamicforms/field/textarea.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_form.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_includes.html +225 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_list.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_body.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_filter.html +5 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/base_field.html +16 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox_multiple.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/fieldset.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/form.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/input.html +17 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/list_fieldset.html +6 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/radio.html +8 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/rtf_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select.html +37 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select_multiple.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/textarea.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog.html +2 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog_rest.html +27 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/page.html +20 -0
- dynamicforms_legacy/templates/dynamicforms/modal_dialog.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/modal_dialog_rest.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/page.html +25 -0
- dynamicforms_legacy/templates/dynamicforms/rtf_field_style.html +41 -0
- dynamicforms_legacy/templatetags/__init__.py +0 -0
- dynamicforms_legacy/templatetags/dynamicforms.py +475 -0
- dynamicforms_legacy/urls.py +8 -0
- dynamicforms_legacy/views.py +1 -0
- dynamicforms_legacy/viewsets.py +366 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{% load dynamicforms %}
|
|
2
|
+
{#This template is extended by dynamicforms/modal_dialog_rest#}
|
|
3
|
+
|
|
4
|
+
<div id="dialog-tmp-{{ serializer.uuid }}" class="jquery-ui-dialog dynamicforms-dialog" tabindex="-1" role="dialog"
|
|
5
|
+
aria-hidden="true">
|
|
6
|
+
{% block body %}{% endblock %}
|
|
7
|
+
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
|
|
8
|
+
<div class="ui-dialog-buttonset">{% block footer %}{% endblock %}</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
var $dlgTmp = $('#dialog-tmp-{{ serializer.uuid }}');
|
|
13
|
+
$dlgTmp.dialog({
|
|
14
|
+
title: "{{ title }}",
|
|
15
|
+
modal: true,
|
|
16
|
+
resizable: true,
|
|
17
|
+
width: 'auto',
|
|
18
|
+
dialogClass: "modal",
|
|
19
|
+
close: function (event, ui) { $dlgTmp.remove(); },
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
$dlgTmp.parent().attr("id", "dialog-{{ serializer.uuid }}");
|
|
23
|
+
|
|
24
|
+
$dlgTmp.find('button').button();
|
|
25
|
+
$dlgTmp.find(".close-btn").click(function (event) { $dlgTmp.dialog('close'); });
|
|
26
|
+
</script>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{#This template is extended by dynamicforms/page#}
|
|
2
|
+
{% load dynamicforms %}
|
|
3
|
+
<div class="accordion df-card">
|
|
4
|
+
<div>{% block title_header %}{% endblock %}
|
|
5
|
+
<span class="add-btn">
|
|
6
|
+
{% block render_table_commands %}{% endblock %}
|
|
7
|
+
</span>
|
|
8
|
+
</div>
|
|
9
|
+
<div>
|
|
10
|
+
{% block page_body %}{% endblock %}
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<script type="text/javascript">
|
|
15
|
+
$(".accordion").accordion({
|
|
16
|
+
heightStyle: "content",
|
|
17
|
+
collapsible: false,
|
|
18
|
+
icons: false,
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% load dynamicforms %}
|
|
2
|
+
|
|
3
|
+
{% if data.id %}
|
|
4
|
+
{% set_var title=serializer.form_titles.edit %}
|
|
5
|
+
{% else %}
|
|
6
|
+
{% set_var title=serializer.form_titles.new %}
|
|
7
|
+
{% endif %}
|
|
8
|
+
|
|
9
|
+
{% set_var templatename=DYNAMICFORMS.template|add:'modal_dialog_rest.html' %}
|
|
10
|
+
|
|
11
|
+
{% extendtemplateblock template_name_var=templatename %}
|
|
12
|
+
{% block body %}
|
|
13
|
+
{% include serializer.template_name with serializer=serializer data=data %}
|
|
14
|
+
{% endblock %}
|
|
15
|
+
{% block footer %}
|
|
16
|
+
{% render_table_commands serializer 'form-buttons' button_position='dialog' %}
|
|
17
|
+
{% endblock %}
|
|
18
|
+
{% endextendtemplateblock %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{# TODO: Prestavi, da bo base povlekel podatke iz page-a #}
|
|
2
|
+
{% extends DYNAMICFORMS.template_root|add:'base.html' %}
|
|
3
|
+
{% load dynamicforms %}
|
|
4
|
+
{% block title %}
|
|
5
|
+
{{ serializer.page_title }}
|
|
6
|
+
{% endblock %}
|
|
7
|
+
{% block body %}
|
|
8
|
+
{% get_data_template as data_template %}
|
|
9
|
+
|
|
10
|
+
{% set_var templatename=DYNAMICFORMS.template|add:'page.html' %}
|
|
11
|
+
|
|
12
|
+
{% extendtemplateblock template_name_var=templatename %}
|
|
13
|
+
{% block title_header %}
|
|
14
|
+
{{ serializer.page_title }}
|
|
15
|
+
{% endblock %}
|
|
16
|
+
{% block render_table_commands %}
|
|
17
|
+
{% if serializer.render_type == 'table' %}{% render_table_commands serializer 'header' %}{% endif %}
|
|
18
|
+
{% endblock %}
|
|
19
|
+
{% block page_body %}
|
|
20
|
+
{% include data_template with serializer=serializer data=data %}
|
|
21
|
+
{% endblock %}
|
|
22
|
+
{% endextendtemplateblock %}
|
|
23
|
+
|
|
24
|
+
{% include DYNAMICFORMS.template_root|add:"modal_dialog.html" %}
|
|
25
|
+
{% endblock %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
button.ck.ck-button.ck-heading_alert-primary {
|
|
2
|
+
font-size: 1.5em;
|
|
3
|
+
color: #004085;
|
|
4
|
+
background-color: #cce5ff;
|
|
5
|
+
border-color: #b8daff;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
button.ck.ck-button.ck-heading_alert-secondary {
|
|
9
|
+
font-size: 1.5em;
|
|
10
|
+
color: #383d41;
|
|
11
|
+
background-color: #e2e3e5;
|
|
12
|
+
border-color: #d6d8db;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
button.ck.ck-button.ck-heading_alert-success {
|
|
16
|
+
font-size: 1.5em;
|
|
17
|
+
color: #155724;
|
|
18
|
+
background-color: #d4edda;
|
|
19
|
+
border-color: #c3e6cb;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
button.ck.ck-button.ck-heading_alert-danger {
|
|
23
|
+
font-size: 1.5em;
|
|
24
|
+
color: #721c24;
|
|
25
|
+
background-color: #f8d7da;
|
|
26
|
+
border-color: #f5c6cb;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
button.ck.ck-button.ck-heading_alert-warning {
|
|
30
|
+
font-size: 1.5em;
|
|
31
|
+
color: #856404;
|
|
32
|
+
background-color: #fff3cd;
|
|
33
|
+
border-color: #ffeeba;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
button.ck.ck-button.ck-heading_alert-info {
|
|
37
|
+
font-size: 1.5em;
|
|
38
|
+
color: #0c5460;
|
|
39
|
+
background-color: #d1ecf1;
|
|
40
|
+
border-color: #bee5eb;
|
|
41
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import json as jsonlib
|
|
2
|
+
|
|
3
|
+
from html import unescape
|
|
4
|
+
|
|
5
|
+
from django import template
|
|
6
|
+
from django.template import engines, TemplateSyntaxError
|
|
7
|
+
from django.template.base import NodeList, token_kwargs
|
|
8
|
+
from django.template.defaulttags import IfNode
|
|
9
|
+
from django.template.loader import get_template
|
|
10
|
+
from django.template.loader_tags import BlockNode, ExtendsNode
|
|
11
|
+
from django.utils.safestring import mark_safe
|
|
12
|
+
from django.utils.translation import gettext_lazy as _
|
|
13
|
+
from rest_framework.templatetags import rest_framework as drftt
|
|
14
|
+
from rest_framework.utils.encoders import JSONEncoder
|
|
15
|
+
|
|
16
|
+
from ..action import TablePosition
|
|
17
|
+
from ..mixins import DisplayMode
|
|
18
|
+
from ..renderers import HTMLFormRenderer
|
|
19
|
+
from ..struct import Struct
|
|
20
|
+
|
|
21
|
+
register = template.Library()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@register.filter(name="dict_item")
|
|
25
|
+
def dict_item(d, k):
|
|
26
|
+
"""Returns the given key from a dictionary."""
|
|
27
|
+
return d[k]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# just copy the template tags that are the same as we're not redeclaring them
|
|
31
|
+
# TODO: the following DRF filters pending removal?
|
|
32
|
+
# note that simply copying the filters didn't work: django kept complaining about parameters. So now it's verbatim copy
|
|
33
|
+
@register.filter
|
|
34
|
+
def items(value):
|
|
35
|
+
"""
|
|
36
|
+
Simple filter to return the items of the dict. Useful when the dict may
|
|
37
|
+
have a key 'items' which is resolved first in Django template dot-notation
|
|
38
|
+
lookup. See DRF issue #4931
|
|
39
|
+
Also see: https://stackoverflow.com/questions/15416662/django-template-loop-over-dictionary-items-with-items-as-key
|
|
40
|
+
"""
|
|
41
|
+
return drftt.items(value)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@register.filter
|
|
45
|
+
def format_value(value):
|
|
46
|
+
# TODO: this one pending removal on tasks #62 in #63 completion
|
|
47
|
+
return drftt.format_value(value)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@register.filter
|
|
51
|
+
def as_string(value):
|
|
52
|
+
# TODO: this one pending removal on tasks #62 in #63 completion
|
|
53
|
+
return drftt.as_string(value)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@register.filter
|
|
57
|
+
def as_list_of_strings(value):
|
|
58
|
+
# TODO: this one pending removal on tasks #62 in #63 completion
|
|
59
|
+
return drftt.as_list_of_strings(value)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# // just copy tags
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@register.simple_tag
|
|
66
|
+
def render_form(serializer, form_template=None):
|
|
67
|
+
"""
|
|
68
|
+
Renders form from serializer. If form_template is given, then renderer will use that one, otherwise it will use what
|
|
69
|
+
is defined in self.base_template (e.g.: »form.html«) from template_pack (e.g.: »dynamicforms/bootstrap/field/«)
|
|
70
|
+
|
|
71
|
+
.. code-block:: django
|
|
72
|
+
|
|
73
|
+
{% set_var template_pack=DYNAMICFORMS.template|add:'field' %}
|
|
74
|
+
{% render_form serializer template_pack=template_pack %}
|
|
75
|
+
|
|
76
|
+
:param serializer: Serializer object
|
|
77
|
+
:param form_template: form template file name to use. overrides all other template name declarations
|
|
78
|
+
:return: rendered template
|
|
79
|
+
"""
|
|
80
|
+
style = {}
|
|
81
|
+
if form_template:
|
|
82
|
+
style["form_template"] = form_template
|
|
83
|
+
style["serializer"] = serializer
|
|
84
|
+
|
|
85
|
+
renderer = HTMLFormRenderer()
|
|
86
|
+
return renderer.render(serializer.data, None, {"style": style})
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@register.simple_tag
|
|
90
|
+
def render_field(field, style):
|
|
91
|
+
"""
|
|
92
|
+
Renders separate field. Style is a dict, that contains template_pack or form_template and rendered. It is defined
|
|
93
|
+
when rendering form, so it is best to use that one. To do that dynamicforms should be loaded first.
|
|
94
|
+
|
|
95
|
+
See example below.
|
|
96
|
+
|
|
97
|
+
.. code-block:: django
|
|
98
|
+
|
|
99
|
+
{% load dynamicforms %}
|
|
100
|
+
{% for field in form %}
|
|
101
|
+
{% if not field.read_only %}
|
|
102
|
+
{% render_field field style=style %}
|
|
103
|
+
{% endif %}
|
|
104
|
+
{% endfor %}
|
|
105
|
+
|
|
106
|
+
:param field: Serializer Field instance
|
|
107
|
+
:param style: render parameters
|
|
108
|
+
:return: rendered field template
|
|
109
|
+
"""
|
|
110
|
+
renderer = style.get("renderer", HTMLFormRenderer())
|
|
111
|
+
return renderer.render_field(field, style)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@register.simple_tag
|
|
115
|
+
def table_columns_count(serializer):
|
|
116
|
+
"""
|
|
117
|
+
Returns number of columns including control columns
|
|
118
|
+
|
|
119
|
+
:param serializer: Serializer
|
|
120
|
+
:return: Number of all columns
|
|
121
|
+
"""
|
|
122
|
+
actions = serializer.actions.renderable_actions(serializer)
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
len([f for f in serializer.fields.values() if f.display_table == DisplayMode.FULL])
|
|
126
|
+
+ (1 if any(action.position == "rowend" for action in actions) else 0)
|
|
127
|
+
+ (1 if any(action.position == "rowstart" for action in actions) else 0)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@register.simple_tag(takes_context=True)
|
|
132
|
+
def render_table_commands(context, serializer, position, field_name=None, button_position=None):
|
|
133
|
+
"""
|
|
134
|
+
Renders commands that are defined in serializers controls attribute.
|
|
135
|
+
|
|
136
|
+
:param context: Context
|
|
137
|
+
:param serializer: Serializer
|
|
138
|
+
:param position: Position of command (See action.py->Action for more details)
|
|
139
|
+
:param field_name: If position is left or right to the field, then this parameter must contain field name
|
|
140
|
+
:param button_position: form button position one of (form, dialog, user-provided)
|
|
141
|
+
:return: rendered command buttons. If table_header parameter is given and commands for position are defined,
|
|
142
|
+
returns only rendered table header
|
|
143
|
+
"""
|
|
144
|
+
ret = ""
|
|
145
|
+
|
|
146
|
+
if position == "onfieldchange":
|
|
147
|
+
ret = serializer.actions.render_field_onchange(serializer)
|
|
148
|
+
ret += serializer.actions.render_form_init(serializer)
|
|
149
|
+
elif position == "onfieldinit":
|
|
150
|
+
ret += serializer.actions.render_field_init(serializer, field_name)
|
|
151
|
+
elif position == "form-buttons":
|
|
152
|
+
ret += serializer.actions.render_form_buttons(serializer, button_position)
|
|
153
|
+
else:
|
|
154
|
+
table_header = None
|
|
155
|
+
if position.startswith("thead_"):
|
|
156
|
+
position = position[6:]
|
|
157
|
+
table_header = _("Actions")
|
|
158
|
+
|
|
159
|
+
positions = dict(
|
|
160
|
+
onrowclick=(TablePosition.ROW_CLICK, TablePosition.ROW_RIGHTCLICK),
|
|
161
|
+
header=(TablePosition.HEADER,),
|
|
162
|
+
filterrowstart=(TablePosition.FILTER_ROW_START,),
|
|
163
|
+
filterrowend=(TablePosition.FILTER_ROW_END,),
|
|
164
|
+
rowstart=(TablePosition.ROW_START,),
|
|
165
|
+
rowend=(TablePosition.ROW_END,),
|
|
166
|
+
fieldleft=(TablePosition.FIELD_START,),
|
|
167
|
+
fieldright=(TablePosition.FIELD_END,),
|
|
168
|
+
)
|
|
169
|
+
ret_tmp = serializer.actions.render_renderable_actions(positions[position], field_name, serializer)
|
|
170
|
+
|
|
171
|
+
_position = positions[position][0]
|
|
172
|
+
if ret_tmp and _position in (
|
|
173
|
+
TablePosition.ROW_START,
|
|
174
|
+
TablePosition.ROW_END,
|
|
175
|
+
TablePosition.FILTER_ROW_START,
|
|
176
|
+
TablePosition.FILTER_ROW_END,
|
|
177
|
+
):
|
|
178
|
+
ret += (
|
|
179
|
+
("<th>%s</th>" % table_header)
|
|
180
|
+
if table_header
|
|
181
|
+
else (
|
|
182
|
+
"<td>%s</td>" % ret_tmp
|
|
183
|
+
if _position not in (TablePosition.FILTER_ROW_END, TablePosition.FILTER_ROW_START)
|
|
184
|
+
else "<th>%s</th>" % ret_tmp
|
|
185
|
+
)
|
|
186
|
+
)
|
|
187
|
+
elif ret_tmp:
|
|
188
|
+
ret += ret_tmp
|
|
189
|
+
|
|
190
|
+
ret = "{% load static i18n %}" + ret
|
|
191
|
+
|
|
192
|
+
return mark_safe(context.template.engine.from_string(ret).render(context))
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@register.simple_tag(takes_context=True)
|
|
196
|
+
def field_to_serializer_and_data(context, serializer):
|
|
197
|
+
"""
|
|
198
|
+
Adjusts context such that the nested serializer field becomes THE serializer
|
|
199
|
+
|
|
200
|
+
:param serializer: field to be converted into context
|
|
201
|
+
:return: nothing
|
|
202
|
+
"""
|
|
203
|
+
if hasattr(serializer, "child"):
|
|
204
|
+
# this is a ListSerializer
|
|
205
|
+
context.update(dict(serializer=serializer.child, data=serializer.value, **serializer.child.template_context))
|
|
206
|
+
else:
|
|
207
|
+
serializer._field._data = serializer.value # The serializer has default values here
|
|
208
|
+
context.update(dict(serializer=serializer, data=serializer.value, **serializer.template_context))
|
|
209
|
+
return ""
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@register.simple_tag(takes_context=True)
|
|
213
|
+
def get_data_template(context, context_data=None):
|
|
214
|
+
"""
|
|
215
|
+
Returns template that should be used for rendering current serializer data
|
|
216
|
+
|
|
217
|
+
:param context: template context (automatically provided by django)
|
|
218
|
+
:return: template file name
|
|
219
|
+
"""
|
|
220
|
+
if context_data:
|
|
221
|
+
context = context_data
|
|
222
|
+
serializer = context["serializer"]
|
|
223
|
+
return serializer.data_template
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@register.simple_tag(takes_context=True)
|
|
227
|
+
def set_var(context, **kwds):
|
|
228
|
+
"""
|
|
229
|
+
Sets the given variables to provided values. Kind of like the 'with' block, only it isn't a block tag
|
|
230
|
+
|
|
231
|
+
:param context: template context (automatically provided by django)
|
|
232
|
+
:param kwds: named parameters with their respective values
|
|
233
|
+
:return: this tag doesn't render
|
|
234
|
+
"""
|
|
235
|
+
for k, v in kwds.items():
|
|
236
|
+
context[k] = v
|
|
237
|
+
return ""
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@register.simple_tag(takes_context=True)
|
|
241
|
+
def set_var_conditional(context, condition=None, condition_var=None, compare=None, else_value=None, **kwds):
|
|
242
|
+
"""
|
|
243
|
+
Sets the given variables to provided values. Kind of like the 'with' block, only it isn't a block tag
|
|
244
|
+
|
|
245
|
+
:param context: template context (automatically provided by django)
|
|
246
|
+
:param kwds: named parameters with their respective values
|
|
247
|
+
:param condition_var: pair with compare to obtain True or False whether to use original assignment or else_value
|
|
248
|
+
:param compare: pair with condition_var to obtain True or False whether to use original assignment or else_value
|
|
249
|
+
:param condition: alternative to condition_var & compare: original assignment if truthy or else_value if falsy
|
|
250
|
+
:param else_value: value to be assigned to the variable(s) when condition is falsy
|
|
251
|
+
:return: this tag doesn't render
|
|
252
|
+
"""
|
|
253
|
+
if condition_var is not None:
|
|
254
|
+
condition = condition_var == compare
|
|
255
|
+
for k, v in kwds.items():
|
|
256
|
+
context[k] = v if condition else else_value
|
|
257
|
+
return ""
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@register.simple_tag(takes_context=False)
|
|
261
|
+
def iter_options_bound(field):
|
|
262
|
+
return field.iter_options_bound(field.value) if hasattr(field, "iter_options_bound") else []
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@register.filter
|
|
266
|
+
def json(value):
|
|
267
|
+
"""
|
|
268
|
+
JSON serialises given variable. Use when you want to insert a variable directly into JavaScript
|
|
269
|
+
|
|
270
|
+
:param value: variable to serialise
|
|
271
|
+
:return: JSON serialised string
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
class Encoder(JSONEncoder):
|
|
275
|
+
def default(self, obj):
|
|
276
|
+
if isinstance(obj, Struct):
|
|
277
|
+
return obj.__to_dict__()
|
|
278
|
+
return super().default(obj)
|
|
279
|
+
|
|
280
|
+
return mark_safe(jsonlib.dumps(value, cls=Encoder))
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
@register.simple_tag(takes_context=True)
|
|
284
|
+
def dict_item_default(context, var, d, k, default):
|
|
285
|
+
context[var] = d.get(k, default)
|
|
286
|
+
|
|
287
|
+
return ""
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@register.filter
|
|
291
|
+
def class_name(value):
|
|
292
|
+
return value.__class__.__name__
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@register.filter
|
|
296
|
+
def in_list(value, the_list):
|
|
297
|
+
value = str(value)
|
|
298
|
+
return value in the_list.split(",")
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@register.filter
|
|
302
|
+
def startswith(text, starts):
|
|
303
|
+
try:
|
|
304
|
+
return text.startswith(starts)
|
|
305
|
+
except:
|
|
306
|
+
return False
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
@register.filter
|
|
310
|
+
def handle_rtf_linebreaks(value):
|
|
311
|
+
return mark_safe(unescape(value))
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def parse_tag(token, parser):
|
|
315
|
+
bits = token.split_contents()
|
|
316
|
+
tag_name = bits.pop(0)
|
|
317
|
+
args, kwargs = [], {}
|
|
318
|
+
while bits:
|
|
319
|
+
bit = bits.pop(0)
|
|
320
|
+
param = token_kwargs([bit], parser)
|
|
321
|
+
if param:
|
|
322
|
+
kwargs.update(param)
|
|
323
|
+
else:
|
|
324
|
+
args.append(parser.compile_filter(bit))
|
|
325
|
+
|
|
326
|
+
return tag_name, args, kwargs
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def template_from_string(template_string, using=None):
|
|
330
|
+
"""
|
|
331
|
+
Convert a string into a template object,
|
|
332
|
+
using a given template engine or using the default backends
|
|
333
|
+
from settings.TEMPLATES if no engine was specified.
|
|
334
|
+
"""
|
|
335
|
+
# This function is based on django.template.loader.get_template,
|
|
336
|
+
# but uses Engine.from_string instead of Engine.get_template.
|
|
337
|
+
|
|
338
|
+
# https://stackoverflow.com/a/46756430/9625282
|
|
339
|
+
chain = []
|
|
340
|
+
engine_list = engines.all() if using is None else [engines[using]]
|
|
341
|
+
for engine in engine_list:
|
|
342
|
+
try:
|
|
343
|
+
return engine.from_string(template_string)
|
|
344
|
+
except TemplateSyntaxError as e:
|
|
345
|
+
chain.append(str(e))
|
|
346
|
+
raise TemplateSyntaxError(template_string + ",".join(chain))
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class ExtendTemplateNode(template.Node):
|
|
350
|
+
"""
|
|
351
|
+
Node for rendering extended template
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
def __init__(self, nodelist, template_name, kwargs, only, multiline):
|
|
355
|
+
self.nodelist = nodelist
|
|
356
|
+
self.template_name = template_name
|
|
357
|
+
self.kwargs = kwargs
|
|
358
|
+
self.only = only
|
|
359
|
+
self.multiline = multiline
|
|
360
|
+
|
|
361
|
+
def rearrange_blocks(self, nodelist, blocks):
|
|
362
|
+
for idx, node in enumerate(nodelist):
|
|
363
|
+
if hasattr(node, "nodelist"):
|
|
364
|
+
if isinstance(node, BlockNode):
|
|
365
|
+
if node.name in blocks:
|
|
366
|
+
nodelist[idx] = blocks[node.name]
|
|
367
|
+
if isinstance(node, IfNode):
|
|
368
|
+
for nodelist_tmp in nodelist[idx].conditions_nodelists:
|
|
369
|
+
for item_id, item in enumerate(nodelist_tmp):
|
|
370
|
+
if isinstance(item, NodeList):
|
|
371
|
+
self.rearrange_blocks(nodelist_tmp[item_id], blocks)
|
|
372
|
+
else:
|
|
373
|
+
self.rearrange_blocks(nodelist[idx].nodelist, blocks)
|
|
374
|
+
return nodelist
|
|
375
|
+
|
|
376
|
+
def get_all_blocks(self, nodelist):
|
|
377
|
+
blocks = []
|
|
378
|
+
for node in [node for node in nodelist if isinstance(node, BlockNode)]:
|
|
379
|
+
blocks.append(node)
|
|
380
|
+
blocks.extend(self.get_all_blocks(node.nodelist))
|
|
381
|
+
return blocks
|
|
382
|
+
|
|
383
|
+
@staticmethod
|
|
384
|
+
def get_node_list(nodelist):
|
|
385
|
+
while len(nodelist) == 1 and isinstance(nodelist[0], ExtendsNode):
|
|
386
|
+
nodelist = nodelist[0].nodelist
|
|
387
|
+
ret = NodeList(nodelist)
|
|
388
|
+
ret.contains_nontext = nodelist.contains_nontext
|
|
389
|
+
return ret
|
|
390
|
+
|
|
391
|
+
def render(self, context):
|
|
392
|
+
kwargs = {key: value.resolve(context) for key, value in self.kwargs.items()}
|
|
393
|
+
try:
|
|
394
|
+
if "template_name_var" in kwargs:
|
|
395
|
+
extending_template = get_template(kwargs.get("template_name_var"))
|
|
396
|
+
else:
|
|
397
|
+
extending_template = get_template(self.template_name.resolve())
|
|
398
|
+
except:
|
|
399
|
+
return ""
|
|
400
|
+
|
|
401
|
+
if self.only:
|
|
402
|
+
flattened_context = kwargs
|
|
403
|
+
else:
|
|
404
|
+
flattened_context = context.flatten()
|
|
405
|
+
flattened_context.update(kwargs)
|
|
406
|
+
|
|
407
|
+
nodelist_changed = False
|
|
408
|
+
new_nodelist = self.get_node_list(extending_template.template.nodelist)
|
|
409
|
+
|
|
410
|
+
if "block" in kwargs:
|
|
411
|
+
block_nodes = self.get_all_blocks(new_nodelist)
|
|
412
|
+
new_nodelist = NodeList([node for node in block_nodes if node.name == kwargs.get("block")])
|
|
413
|
+
new_nodelist.contains_nontext = True
|
|
414
|
+
nodelist_changed = True
|
|
415
|
+
|
|
416
|
+
if self.multiline:
|
|
417
|
+
blocks = {node.name: node for node in self.nodelist if isinstance(node, BlockNode)}
|
|
418
|
+
self.rearrange_blocks(new_nodelist, blocks)
|
|
419
|
+
nodelist_changed = True
|
|
420
|
+
|
|
421
|
+
# This is because there can also be cache loader for template. And if in template loaded with such loader nodes
|
|
422
|
+
# are changed, they are changed in next iteration also.
|
|
423
|
+
# So now I load template from empty string and give him changed nodelist. So I don't change original template
|
|
424
|
+
if nodelist_changed:
|
|
425
|
+
extending_template = template_from_string("", None)
|
|
426
|
+
extending_template.template.nodelist = new_nodelist
|
|
427
|
+
|
|
428
|
+
content = extending_template.render(flattened_context)
|
|
429
|
+
content = mark_safe(content)
|
|
430
|
+
return content
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def get_extend_data(token, parser):
|
|
434
|
+
tag_name, args, kwargs = parse_tag(token, parser)
|
|
435
|
+
|
|
436
|
+
template_name = None
|
|
437
|
+
if "template_name_var" not in kwargs:
|
|
438
|
+
template_name = args[0]
|
|
439
|
+
|
|
440
|
+
return args, kwargs, template_name
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
@register.tag("extendtemplate")
|
|
444
|
+
def do_extendtemplate(parser, token):
|
|
445
|
+
"""
|
|
446
|
+
Similar to base tag include, but with possibility to use blocks
|
|
447
|
+
This tag is used as single line (without closing tag) For multiline use extendtemplateblock
|
|
448
|
+
|
|
449
|
+
Template name can be provided in two ways:
|
|
450
|
+
- If template name is static than declare it in first arg
|
|
451
|
+
- If template name is in variable than declare variable name in 'template_name_var' kwarg
|
|
452
|
+
|
|
453
|
+
Keyword parameters will be used as context when rendering template
|
|
454
|
+
If there is "only" in parameters only keyword parameters will be used as context for rendering.
|
|
455
|
+
Otherwise keywords will be added to existing context
|
|
456
|
+
"""
|
|
457
|
+
|
|
458
|
+
args, kwargs, template_name = get_extend_data(token, parser)
|
|
459
|
+
|
|
460
|
+
return ExtendTemplateNode([], template_name, kwargs, "only" in (x.token for x in args), False)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
@register.tag("extendtemplateblock")
|
|
464
|
+
def do_extendtemplateblock(parser, token):
|
|
465
|
+
"""
|
|
466
|
+
Same do_extendtemplate, only multiline... with posibillity to use blocks
|
|
467
|
+
"""
|
|
468
|
+
|
|
469
|
+
args, kwargs, template_name = get_extend_data(token, parser)
|
|
470
|
+
|
|
471
|
+
# This si multiline block with closing tag
|
|
472
|
+
nodelist = parser.parse(("endextendtemplateblock",))
|
|
473
|
+
parser.delete_first_token()
|
|
474
|
+
|
|
475
|
+
return ExtendTemplateNode(nodelist, template_name, kwargs, "only" in (x.token for x in args), True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# from django.shortcuts import render
|