From cc7422a50383971f1b4408cf41927c57701d9daf Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Thu, 13 Feb 2020 23:47:24 +0100 Subject: [PATCH] theming refactor moved server side for a better page loading experience and less javascript mess --- cookbook/forms.py | 6 ++ cookbook/migrations/0013_userpreference.py | 24 ++++++++ .../migrations/0014_auto_20200213_2332.py | 26 +++++++++ .../migrations/0015_auto_20200213_2334.py | 21 +++++++ .../migrations/0016_auto_20200213_2335.py | 25 +++++++++ cookbook/models.py | 12 ++++ cookbook/templates/base.html | 34 ++---------- cookbook/templates/settings.html | 55 ++----------------- cookbook/templatetags/custom_tags.py | 20 +++++++ cookbook/views/views.py | 17 +++++- 10 files changed, 160 insertions(+), 80 deletions(-) create mode 100644 cookbook/migrations/0013_userpreference.py create mode 100644 cookbook/migrations/0014_auto_20200213_2332.py create mode 100644 cookbook/migrations/0015_auto_20200213_2334.py create mode 100644 cookbook/migrations/0016_auto_20200213_2335.py diff --git a/cookbook/forms.py b/cookbook/forms.py index a097146c7..7be812626 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -26,6 +26,12 @@ class DateWidget(forms.DateInput): super().__init__(**kwargs) +class UserPreferenceForm(forms.ModelForm): + class Meta: + model = UserPreference + fields = ('theme',) + + class ExternalRecipeForm(forms.ModelForm): file_path = forms.CharField(disabled=True, required=False) storage = forms.ModelChoiceField(queryset=Storage.objects.all(), disabled=True, required=False) diff --git a/cookbook/migrations/0013_userpreference.py b/cookbook/migrations/0013_userpreference.py new file mode 100644 index 000000000..f0b3535bc --- /dev/null +++ b/cookbook/migrations/0013_userpreference.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.2 on 2020-02-13 22:15 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cookbook', '0012_auto_20200130_1116'), + ] + + operations = [ + migrations.CreateModel( + name='UserPreference', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('theme', models.CharField(choices=[('BOOTSTRAP', 'Bootstrap'), ('DARKLY', 'Darkly'), ('FLATLY', 'Flatly')], default='BOOTSTRAP', max_length=128)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/cookbook/migrations/0014_auto_20200213_2332.py b/cookbook/migrations/0014_auto_20200213_2332.py new file mode 100644 index 000000000..f9a78c5cd --- /dev/null +++ b/cookbook/migrations/0014_auto_20200213_2332.py @@ -0,0 +1,26 @@ +# Generated by Django 3.0.2 on 2020-02-13 22:32 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cookbook', '0013_userpreference'), + ] + + operations = [ + migrations.AlterField( + model_name='userpreference', + name='theme', + field=models.CharField(choices=[('BOOTSTRAP', 'Bootstrap'), ('DARKLY', 'Darkly'), ('FLATLY', 'Flatly'), ('SUPERHERO', 'Superhero')], default='BOOTSTRAP', max_length=128), + ), + migrations.AlterField( + model_name='userpreference', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, unique=True), + ), + ] diff --git a/cookbook/migrations/0015_auto_20200213_2334.py b/cookbook/migrations/0015_auto_20200213_2334.py new file mode 100644 index 000000000..5d97634c5 --- /dev/null +++ b/cookbook/migrations/0015_auto_20200213_2334.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.2 on 2020-02-13 22:34 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cookbook', '0014_auto_20200213_2332'), + ] + + operations = [ + migrations.AlterField( + model_name='userpreference', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cookbook/migrations/0016_auto_20200213_2335.py b/cookbook/migrations/0016_auto_20200213_2335.py new file mode 100644 index 000000000..7f9c564ff --- /dev/null +++ b/cookbook/migrations/0016_auto_20200213_2335.py @@ -0,0 +1,25 @@ +# Generated by Django 3.0.2 on 2020-02-13 22:35 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cookbook', '0015_auto_20200213_2334'), + ] + + operations = [ + migrations.RemoveField( + model_name='userpreference', + name='id', + ), + migrations.AlterField( + model_name='userpreference', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index c361282d6..5b706ab0b 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -3,6 +3,18 @@ from django.utils.translation import gettext as _ from django.db import models +class UserPreference(models.Model): + BOOTSTRAP = 'BOOTSTRAP' + DARKLY = 'DARKLY' + FLATLY = 'FLATLY' + SUPERHERO = 'SUPERHERO' + + THEMES = ((BOOTSTRAP, 'Bootstrap'), (DARKLY, 'Darkly'), (FLATLY, 'Flatly'), (SUPERHERO, 'Superhero')) + + user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) + theme = models.CharField(choices=THEMES, max_length=128, default=BOOTSTRAP) + + class Storage(models.Model): DROPBOX = 'DB' NEXTCLOUD = 'NEXTCLOUD' diff --git a/cookbook/templates/base.html b/cookbook/templates/base.html index f339a2b9a..a4a157752 100644 --- a/cookbook/templates/base.html +++ b/cookbook/templates/base.html @@ -1,5 +1,6 @@ {% load static %} {% load i18n %} +{% load custom_tags %} @@ -18,31 +19,11 @@ - + - - - @@ -161,15 +142,6 @@

- - - -
{% for message in messages %} @@ -185,6 +157,8 @@ {% endblock %}
+{% block script %} +{% endblock script %} \ No newline at end of file diff --git a/cookbook/templates/settings.html b/cookbook/templates/settings.html index 5d14bcd76..2e0681579 100644 --- a/cookbook/templates/settings.html +++ b/cookbook/templates/settings.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load i18n %} +{% load crispy_forms_tags %} {% load static %} {% block title %}{% trans 'Settings' %}{% endblock %} @@ -40,57 +41,13 @@

{% trans 'Style' %}

-
-
- -
-
+
+ {% csrf_token %} + {{ form|crispy }} + +
-
-
- -
-
-
-
- {% endblock %} \ No newline at end of file diff --git a/cookbook/templatetags/custom_tags.py b/cookbook/templatetags/custom_tags.py index 4435e0e54..8347388d1 100644 --- a/cookbook/templatetags/custom_tags.py +++ b/cookbook/templatetags/custom_tags.py @@ -2,6 +2,9 @@ from django import template import markdown as md import bleach from bleach_whitelist import markdown_tags, markdown_attrs +from django.templatetags.static import static + +from cookbook.models import UserPreference register = template.Library() @@ -14,3 +17,20 @@ def get_class(value): @register.filter() def markdown(value): return bleach.clean(md.markdown(value, extensions=['markdown.extensions.fenced_code']), markdown_tags, markdown_attrs) + + +@register.simple_tag +def theme_url(request): + try: + themes = { + UserPreference.BOOTSTRAP: 'themes/bootstrap.min.css', + UserPreference.FLATLY: 'themes/flatly.min.css', + UserPreference.DARKLY: 'themes/darkly.min.css', + UserPreference.SUPERHERO: 'themes/superhero.min.css', + } + if request.user.userpreference.theme in themes: + return static(themes[request.user.userpreference.theme]) + else: + raise AttributeError + except AttributeError: + return static('themes/bootstrap.min.css') diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 5ac33a6bf..c1569d68e 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -145,4 +145,19 @@ def shopping_list(request): @login_required def settings(request): - return render(request, 'settings.html', {}) + up = request.user.userpreference + + if request.method == "POST": + form = UserPreferenceForm(request.POST) + if form.is_valid(): + if not up: + up = UserPreference(user=request.user) + up.theme = form.cleaned_data['theme'] + up.save() + + if up: + form = UserPreferenceForm(instance=up) + else: + form = UserPreferenceForm() + + return render(request, 'settings.html', {'form': form})