From 842d8cf9b11bc421602035405e0fc23b083c6524 Mon Sep 17 00:00:00 2001 From: Bryan Brancotte <bryan.brancotte@pasteur.fr> Date: Tue, 15 Oct 2019 15:53:05 +0200 Subject: [PATCH] Adding ability to group preferences, and to add a description in each generated tab, only compatible with BS4 --- .../templates/registration/account.html | 67 ++++++++++++++----- .../templatetags/basetheme_bootstrap.py | 6 ++ basetheme_bootstrap/user_preferences.py | 8 +++ basetheme_bootstrap/views.py | 2 + setup.py | 2 +- .../migrations/0002_auto_20191015_1154.py | 33 +++++++++ test_app_1/models.py | 30 +++++++++ test_app_1/templates/test_app_1/base.html | 1 + 8 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 test_app_1/migrations/0002_auto_20191015_1154.py create mode 100644 test_app_1/templates/test_app_1/base.html diff --git a/basetheme_bootstrap/templates/registration/account.html b/basetheme_bootstrap/templates/registration/account.html index 78b5b53..32a73d7 100644 --- a/basetheme_bootstrap/templates/registration/account.html +++ b/basetheme_bootstrap/templates/registration/account.html @@ -1,4 +1,5 @@ {% extends basetheme_bootstrap_base_template %} +{% load basetheme_bootstrap %} {% load crispy_forms_tags %} {% load static %} {% load sstatic %} @@ -9,25 +10,57 @@ {% block content %} -<div class="col-12 col-xs-12 col-md-7 col-lg-8 col-xl-9 mb-sm-4 mb-md-0"> - <div class="card panel panel-default"> - <div class="card-header panel-heading"> - <h3 class="panel-title">{%trans "Preferences"%}</h3> - </div> - <div class="card-body panel-body"> - {%if form_prefs%} - <form method="post"> - {% csrf_token %} - {{ form_prefs|crispy }} - <button class="btn btn-primary {{btn_classes}}" type="submit">Save my preferences - </button> - </form> - {%endif%} +<div class="col-12 col-xs-12 col-md-7 col-lg-8 col-xl-9 mb-sm-4 mb-md-0 order-6"> + <form method="post">{% csrf_token %} + <div class="card panel panel-default"> + <nav class="card-header panel-heading"> + <h3 class="panel-title">{%trans "Preferences"%}</h3> + {% if form_prefs.preferences_groups %} + <div class="nav nav-tabs card-header-tabs" id="nav-tab" role="tablist"> + {% for group_name, field_names in form_prefs.preferences_groups.items %} + <a class="nav-item nav-link {% if forloop.first %}active{%endif%}" + id="nav-{{ group_name|group_name_to_id }}" + data-toggle="tab" + href="#tab-{{ group_name|group_name_to_id }}" + role="tab" aria-controls="nav-contact" aria-selected="false"> + {{group_name}} + </a> + {%endfor%} + </div> + {% endif %} + </nav> + <div class="card-body panel-body tab-content"> + {%if form_prefs%} + {% if not form_prefs.preferences_groups %} + {{ form_prefs|crispy }} + {%else%} + {% for field in form_prefs.hidden_fields %}{{ field}}{% endfor %} + {% for group_name, field_names in form_prefs.preferences_groups.items %} + <div class="tab-pane fade {% if forloop.first %}active show{%endif%}" id="tab-{{ group_name|group_name_to_id }}" role="tabpanel" aria-labelledby="nav-{{ group_name|group_name_to_id }}"> + {{ group_name_desc }} + {% for group_name_desc, description in form_prefs.preferences_groups_descriptions.items %} + {% if group_name_desc == group_name %} + <p>{{ description }}</p> + {% endif%} + {% endfor %} + {% for field in form_prefs.visible_fields %} + {% if field.name in field_names%} + {{ field|as_crispy_field }} + {% endif%} + {% endfor %} + </div> + {% endfor %} + {%endif%} + {%endif%} + </div> + <div class="card-body panel-body pt-0"> + <button class="btn btn-primary {{btn_classes}}" type="submit">Save my preferences + </button> + </div> </div> - </div> - + </form> </div> -<div class="col-12 col-xs-12 col-md-5 col-lg-4 col-xl-3"> +<div class="col-12 col-xs-12 col-md-5 col-lg-4 col-xl-3 order-6"> <div class="card panel panel-default"> <div class="card-header panel-heading"> <h3 class="panel-title">{%trans "Actions"%}</h3> diff --git a/basetheme_bootstrap/templatetags/basetheme_bootstrap.py b/basetheme_bootstrap/templatetags/basetheme_bootstrap.py index 3230434..0576cb6 100644 --- a/basetheme_bootstrap/templatetags/basetheme_bootstrap.py +++ b/basetheme_bootstrap/templatetags/basetheme_bootstrap.py @@ -1,4 +1,5 @@ import logging +import re from django import template from django.conf import settings @@ -44,6 +45,11 @@ def tags_to_bootstrap(tag): return tag +@register.filter +def group_name_to_id(group_name): + pattern = re.compile('[\W_]+') + return pattern.sub('', group_name) + class IncludeIfExistsNode(template.Node): """ A Node that instantiates an IncludeNode but wraps its render() in a diff --git a/basetheme_bootstrap/user_preferences.py b/basetheme_bootstrap/user_preferences.py index a3dc8f3..3d411dc 100644 --- a/basetheme_bootstrap/user_preferences.py +++ b/basetheme_bootstrap/user_preferences.py @@ -94,3 +94,11 @@ class UserPreferencesAbstractModel(models.Model): if field_name == "id" or field_name == "pk" or field_name == "user": continue yield field_name + + @property + def preferences_groups(self): + return None + + @property + def preferences_groups_descriptions(self): + return {} diff --git a/basetheme_bootstrap/views.py b/basetheme_bootstrap/views.py index e9c6b81..a0fae35 100644 --- a/basetheme_bootstrap/views.py +++ b/basetheme_bootstrap/views.py @@ -159,6 +159,8 @@ def account_detail(request): for f in form_prefs.fields.values(): if isinstance(f.widget, widgets.TimeInput): f.widget.input_type = 'time' + form_prefs.preferences_groups = getattr(pref, "preferences_groups", None) + form_prefs.preferences_groups_descriptions = getattr(pref, "preferences_groups_descriptions", None) return render(request, 'registration/account.html', { 'form_prefs': form_prefs, 'btn_classes': 'pull-right float-right' diff --git a/setup.py b/setup.py index a5a27fd..c7dc6ac 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ readme = open('README.rst').read() setup( name='django-basetheme-bootstrap', - version='0.2.23', + version='0.2.24', description='Django Basetheme Bootstrap', long_description=readme, author='Bryan Brancotte', diff --git a/test_app_1/migrations/0002_auto_20191015_1154.py b/test_app_1/migrations/0002_auto_20191015_1154.py new file mode 100644 index 0000000..9c12418 --- /dev/null +++ b/test_app_1/migrations/0002_auto_20191015_1154.py @@ -0,0 +1,33 @@ +# Generated by Django 2.1.7 on 2019-10-15 11:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('test_app_1', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='myuserpreferences', + name='hide_help_2', + field=models.BooleanField(default=False, help_text='hide_help__help_text', verbose_name='hide_help_2__verbose_name'), + ), + migrations.AddField( + model_name='myuserpreferences', + name='hide_help_3', + field=models.BooleanField(default=False, help_text='hide_help__help_text', verbose_name='hide_help_3__verbose_name'), + ), + migrations.AddField( + model_name='myuserpreferences', + name='hide_help_4', + field=models.BooleanField(default=False, help_text='hide_help__help_text', verbose_name='hide_help_4__verbose_name'), + ), + migrations.AddField( + model_name='myuserpreferences', + name='hide_help_5', + field=models.BooleanField(default=False, help_text='hide_help__help_text', verbose_name='hide_help_5__verbose_name'), + ), + ] diff --git a/test_app_1/models.py b/test_app_1/models.py index 6cbd8fe..95537c7 100644 --- a/test_app_1/models.py +++ b/test_app_1/models.py @@ -6,11 +6,41 @@ from basetheme_bootstrap import user_preferences class MyUserPreferences(user_preferences.UserPreferencesAbstractModel, models.Model): + preferences_groups = { + "First group": {"hide_help", "hide_help_3", "hide_help_4", "a_time_field"}, + "Second group": {"hide_help_2"}, + } + + preferences_groups_descriptions={ + "First group":"this is the first group, check the other one", + "Second group":"this is the second group, check the other one", + } + hide_help = models.BooleanField( verbose_name=_("hide_help__verbose_name"), help_text=_("hide_help__help_text"), default=False, ) + hide_help_2 = models.BooleanField( + verbose_name=_("hide_help_2__verbose_name"), + help_text=_("hide_help__help_text"), + default=False, + ) + hide_help_3 = models.BooleanField( + verbose_name=_("hide_help_3__verbose_name"), + help_text=_("hide_help__help_text"), + default=False, + ) + hide_help_4 = models.BooleanField( + verbose_name=_("hide_help_4__verbose_name"), + help_text=_("hide_help__help_text"), + default=False, + ) + hide_help_5 = models.BooleanField( + verbose_name=_("hide_help_5__verbose_name"), + help_text=_("hide_help__help_text"), + default=False, + ) a_time_field = models.TimeField( verbose_name=_("a_time_field__verbose_name"), help_text=_("a_time_field_%(tz)s__help_text") % dict(tz=settings.TIME_ZONE), diff --git a/test_app_1/templates/test_app_1/base.html b/test_app_1/templates/test_app_1/base.html new file mode 100644 index 0000000..e3d651f --- /dev/null +++ b/test_app_1/templates/test_app_1/base.html @@ -0,0 +1 @@ +{% extends "basetheme_bootstrap/base4.html" %} \ No newline at end of file -- GitLab