8
0
Fork 0
mirror of https://gitlab.federez.net/re2o/re2o synced 2024-05-10 11:36:25 +00:00

Add custom themes

This commit is contained in:
Yoann Pétri 2020-11-17 13:54:33 +01:00 committed by Gabriel Detraz
parent 892ac7e958
commit 682d824121
27 changed files with 289 additions and 0 deletions

4
.gitignore vendored
View file

@ -47,3 +47,7 @@ settings_local.py
local_routers.py local_routers.py
re2o.png re2o.png
media/ media/
# themes
static/css/themes/*
!static/css/themes/default.css

View file

View file

@ -56,6 +56,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<link href="{% static 'css/typeaheadjs.css' %}" rel="stylesheet"> <link href="{% static 'css/typeaheadjs.css' %}" rel="stylesheet">
<link href="{% static 'css/bootstrap-tokenfield.css' %}" rel="stylesheet"> <link href="{% static 'css/bootstrap-tokenfield.css' %}" rel="stylesheet">
<link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet"> <link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
{# load theme #}
{% if request.user.is_authenticated %}
<link href="{% static 'css/themes/' %}{{request.user.theme}}" rel="stylesheet">
{% else %}
<link href="{% static 'css/themes/default.css' %}" rel="stylesheet">
{% endif %}
<link href="{% static 'css/base.css' %}" rel="stylesheet"> <link href="{% static 'css/base.css' %}" rel="stylesheet">
{# Favicon with iOS, Android, touchbar support #} {# Favicon with iOS, Android, touchbar support #}

23
themes/README.md Normal file
View file

@ -0,0 +1,23 @@
# Custom themes for Re2o
The following themes are licensed under MIT to Thomas Park. See https://bootswatch.com.
By default, only the default.css is enabled, which is a blank css file.
**How to activate new themes ?**
You can activate themes by copying them, or making a symbolic link to the `static/css/themes` directory and collecting the statics.
**How to change the default theme ?**
You can change the default theme by changing the default.css file.
**How to add new theme ?**
You can add a brand new theme by adding a css file to the `static/css/themes` directory and collecting the statics.
**What happens if I delete a theme ?**
User with this theme will continue to try to load this theme, without success if the theme was correctly deleted. It won't cause any malfunctions on the client side, and the default re2o theme (but not the default.css) theme will be loaded. Users will not be able to select this theme anymore afterwards.
Try to not delete the default.css theme.

11
themes/cerulan.css Normal file

File diff suppressed because one or more lines are too long

11
themes/cosmo.css Normal file

File diff suppressed because one or more lines are too long

11
themes/cyborg.css Normal file

File diff suppressed because one or more lines are too long

11
themes/darkly.css Normal file

File diff suppressed because one or more lines are too long

0
themes/default.css Normal file
View file

11
themes/flatly.css Normal file

File diff suppressed because one or more lines are too long

11
themes/journal.css Normal file

File diff suppressed because one or more lines are too long

11
themes/lumen.css Normal file

File diff suppressed because one or more lines are too long

11
themes/paper.css Normal file

File diff suppressed because one or more lines are too long

11
themes/readable.css Normal file

File diff suppressed because one or more lines are too long

11
themes/sandstone.css Normal file

File diff suppressed because one or more lines are too long

11
themes/simplex.css Normal file

File diff suppressed because one or more lines are too long

11
themes/slate.css Normal file

File diff suppressed because one or more lines are too long

11
themes/spacelab.css Normal file

File diff suppressed because one or more lines are too long

11
themes/superhero.css Normal file

File diff suppressed because one or more lines are too long

11
themes/united.css Normal file

File diff suppressed because one or more lines are too long

11
themes/yeti.css Normal file

File diff suppressed because one or more lines are too long

View file

@ -41,11 +41,14 @@ of each of the method.
from __future__ import unicode_literals from __future__ import unicode_literals
from os import walk, path
from django import forms from django import forms
from django.forms import ModelForm, Form from django.forms import ModelForm, Form
from django.contrib.auth.forms import ReadOnlyPasswordHashField from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.password_validation import validate_password, password_validators_help_text_html from django.contrib.auth.password_validation import validate_password, password_validators_help_text_html
from django.core.validators import MinLengthValidator from django.core.validators import MinLengthValidator
from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.utils.functional import lazy from django.utils.functional import lazy
from django.contrib.auth.models import Group, Permission from django.contrib.auth.models import Group, Permission
@ -1040,3 +1043,17 @@ class InitialRegisterForm(forms.Form):
if self.cleaned_data["register_machine"]: if self.cleaned_data["register_machine"]:
if self.mac_address and self.nas_type: if self.mac_address and self.nas_type:
self.user.autoregister_machine(self.mac_address, self.nas_type) self.user.autoregister_machine(self.mac_address, self.nas_type)
class ThemeForm(FormRevMixin, forms.Form):
"""Form to change the theme of a user.
"""
theme = forms.ChoiceField(widget=forms.Select())
def __init__(self, *args, **kwargs):
_, _ ,themes = next(walk(path.join(settings.STATIC_ROOT, "css/themes")))
if not themes:
themes = ["default.css"]
super(ThemeForm, self).__init__(*args, **kwargs)
self.fields['theme'].choices = [(theme, theme) for theme in themes]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-16 18:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0094_remove_user_profile_image'),
]
operations = [
migrations.AddField(
model_name='user',
name='theme',
field=models.CharField(default='default.css', max_length=255),
),
]

View file

@ -305,6 +305,7 @@ class User(
verbose_name=_("enable shortcuts on Re2o website"), default=True verbose_name=_("enable shortcuts on Re2o website"), default=True
) )
email_change_date = models.DateTimeField(auto_now_add=True) email_change_date = models.DateTimeField(auto_now_add=True)
theme = models.CharField(max_length=255, default="default.css")
USERNAME_FIELD = "pseudo" USERNAME_FIELD = "pseudo"
REQUIRED_FIELDS = ["surname", "email"] REQUIRED_FIELDS = ["surname", "email"]
@ -1963,6 +1964,14 @@ class User(
def __str__(self): def __str__(self):
return self.pseudo return self.pseudo
@property
def theme_name(self):
"""Return the theme without the extension
Returns:
str: name of theme
"""
return self.theme.split(".")[0]
class Adherent(User): class Adherent(User):
"""Base re2o Adherent model, inherit from User. Add other attributes. """Base re2o Adherent model, inherit from User. Add other attributes.

View file

@ -176,6 +176,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Edit the groups" %} {% trans "Edit the groups" %}
</a> </a>
{% acl_end %} {% acl_end %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-theme' users.id %}">
<i class="fa fa-paint-brush"></i>
{% trans "Change theme" %}
</a>
{% history_button users text=True %} {% history_button users text=True %}
</ul> </ul>
</div> </div>
@ -345,6 +349,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<dt>{% trans "Shortcuts enabled" %}</dt> <dt>{% trans "Shortcuts enabled" %}</dt>
<dd>{{ users.shortcuts_enabled | tick }}</dd> <dd>{{ users.shortcuts_enabled | tick }}</dd>
</div> </div>
<div class="col-md-6 col-xs-12">
<dt>{% trans "Theme" %}</dt>
<dd>{{ request.user.theme_name }}</dd>
</div>
</dl> </dl>
</div> </div>
</div> </div>

View file

@ -127,4 +127,5 @@ urlpatterns = [
url(r"^$", views.index, name="index"), url(r"^$", views.index, name="index"),
url(r"^index_clubs/$", views.index_clubs, name="index-clubs"), url(r"^index_clubs/$", views.index_clubs, name="index-clubs"),
url(r"^initial_register/$", views.initial_register, name="initial-register"), url(r"^initial_register/$", views.initial_register, name="initial-register"),
url(r"^edit_theme/(?P<userid>[0-9]+)$", views.edit_theme, name="edit-theme"),
] ]

View file

@ -128,6 +128,7 @@ from .forms import (
ClubAdminandMembersForm, ClubAdminandMembersForm,
GroupForm, GroupForm,
InitialRegisterForm, InitialRegisterForm,
ThemeForm
) )
import os import os
@ -1593,3 +1594,27 @@ def initial_register(request):
request, request,
) )
@login_required
@can_edit(User)
def edit_theme(request, user, userid):
"""View for editing base user informations.
Perform an acl check on user instance.
Parameters:
request (django request): Standard django request.
user: User instance to edit
Returns:
Django User form.
"""
theme_form = ThemeForm(request.POST or None, initial={'theme':user.theme})
if theme_form.is_valid():
user.theme = theme_form.cleaned_data["theme"]
user.save()
messages.success(request, _("The theme was edited."))
return redirect(reverse("users:profil", kwargs={"userid": str(userid)}))
return form(
{"userform": theme_form, "action_name": _("Edit")}, "users/user.html", request,
)