From 84d650eabdc8a55adedb830f3051ebe17c3f1374 Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Thu, 9 Nov 2023 23:57:58 +0100 Subject: [PATCH] Add editable "static" content --- src/agenda_culturel/admin.py | 4 +++- .../migrations/0012_staticcontent.py | 22 ++++++++++++++++++ .../migrations/0013_staticcontent_url_path.py | 19 +++++++++++++++ src/agenda_culturel/models.py | 14 +++++++++++ src/agenda_culturel/settings/base.py | 1 + src/agenda_culturel/static/style.scss | 15 ++++++++++++ .../agenda_culturel/event_create_form.html | 5 ++++ .../templates/agenda_culturel/event_form.html | 2 ++ .../templates/agenda_culturel/import.html | 8 +++++++ .../templates/agenda_culturel/page-week.html | 5 ++++ .../agenda_culturel/static_content.html | 14 +++++++++++ .../agenda_culturel/staticcontent_form.html | 22 ++++++++++++++++++ .../templatetags/static_content_extra.py | 20 ++++++++++++++++ src/agenda_culturel/urls.py | 2 ++ src/agenda_culturel/views.py | 23 ++++++++++++++++--- src/requirements.txt | 2 ++ 16 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 src/agenda_culturel/migrations/0012_staticcontent.py create mode 100644 src/agenda_culturel/migrations/0013_staticcontent_url_path.py create mode 100644 src/agenda_culturel/templates/agenda_culturel/static_content.html create mode 100644 src/agenda_culturel/templates/agenda_culturel/staticcontent_form.html create mode 100644 src/agenda_culturel/templatetags/static_content_extra.py diff --git a/src/agenda_culturel/admin.py b/src/agenda_culturel/admin.py index 302f280..bc1335f 100644 --- a/src/agenda_culturel/admin.py +++ b/src/agenda_culturel/admin.py @@ -1,12 +1,14 @@ from django.contrib import admin from django import forms -from .models import Event, EventSubmissionForm, Category +from .models import Event, EventSubmissionForm, Category, StaticContent from django_better_admin_arrayfield.admin.mixins import DynamicArrayMixin from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget from django_better_admin_arrayfield.models.fields import DynamicArrayField admin.site.register(EventSubmissionForm) admin.site.register(Category) +admin.site.register(StaticContent) + class URLWidget(DynamicArrayWidget): def __init__(self, *args, **kwargs): diff --git a/src/agenda_culturel/migrations/0012_staticcontent.py b/src/agenda_culturel/migrations/0012_staticcontent.py new file mode 100644 index 0000000..247f7ed --- /dev/null +++ b/src/agenda_culturel/migrations/0012_staticcontent.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.1 on 2023-11-09 21:35 + +import ckeditor.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agenda_culturel', '0011_alter_event_category'), + ] + + operations = [ + migrations.CreateModel( + name='StaticContent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='Category name', max_length=512, unique=True, verbose_name='Name')), + ('text', ckeditor.fields.RichTextField(help_text='Text as shown to the visitors', verbose_name='Content')), + ], + ), + ] diff --git a/src/agenda_culturel/migrations/0013_staticcontent_url_path.py b/src/agenda_culturel/migrations/0013_staticcontent_url_path.py new file mode 100644 index 0000000..db02d84 --- /dev/null +++ b/src/agenda_culturel/migrations/0013_staticcontent_url_path.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.1 on 2023-11-09 22:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agenda_culturel', '0012_staticcontent'), + ] + + operations = [ + migrations.AddField( + model_name='staticcontent', + name='url_path', + field=models.CharField(default='', help_text='URL path where the content is included.', verbose_name='URL path'), + preserve_default=False, + ), + ] diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index 5214365..8668ab2 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -4,11 +4,25 @@ from django.utils.translation import gettext_lazy as _ from django.template.defaultfilters import slugify # new from django.urls import reverse from colorfield.fields import ColorField +from ckeditor.fields import RichTextField + from django.template.defaultfilters import date as _date from datetime import datetime +class StaticContent(models.Model): + + name = models.CharField(verbose_name=_('Name'), help_text=_('Category name'), max_length=512, unique=True) + text = RichTextField(verbose_name=_('Content'), help_text=_('Text as shown to the visitors')) + url_path = models.CharField(verbose_name=_('URL path'), help_text=_('URL path where the content is included.')) + + def __str__(self): + return self.name + + def get_absolute_url(self): + return self.url_path + class Category(models.Model): default_name = "Sans catégorie" diff --git a/src/agenda_culturel/settings/base.py b/src/agenda_culturel/settings/base.py index dcca4d4..17ae87a 100644 --- a/src/agenda_culturel/settings/base.py +++ b/src/agenda_culturel/settings/base.py @@ -42,6 +42,7 @@ INSTALLED_APPS = [ 'django_better_admin_arrayfield', 'django_filters', 'compressor', + 'ckeditor', ] MIDDLEWARE = [ diff --git a/src/agenda_culturel/static/style.scss b/src/agenda_culturel/static/style.scss index a91fa79..72262dc 100644 --- a/src/agenda_culturel/static/style.scss +++ b/src/agenda_culturel/static/style.scss @@ -301,4 +301,19 @@ article#filters { .helptext { font-size: 80%; opacity: 0.7; +} + +.django-ckeditor-widget { + width: 100%; +} + +.cke_editable { + font-size: 13px; + line-height: 1.6; + background-color: #1C1C1C !important; + word-wrap: break-word; +} + +.slide-buttons { + float: right; } \ No newline at end of file diff --git a/src/agenda_culturel/templates/agenda_culturel/event_create_form.html b/src/agenda_culturel/templates/agenda_culturel/event_create_form.html index eea2fb2..dc2a410 100644 --- a/src/agenda_culturel/templates/agenda_culturel/event_create_form.html +++ b/src/agenda_culturel/templates/agenda_culturel/event_create_form.html @@ -14,6 +14,11 @@

Proposer un événement

+
+{% url 'add_event' as local_url %} +{% include "agenda_culturel/static_content.html" with name="add_event" url_path=local_url %} +
+
{% csrf_token %} {{ form.as_p }} diff --git a/src/agenda_culturel/templates/agenda_culturel/event_form.html b/src/agenda_culturel/templates/agenda_culturel/event_form.html index 79a35ca..0d6aca7 100644 --- a/src/agenda_culturel/templates/agenda_culturel/event_form.html +++ b/src/agenda_culturel/templates/agenda_culturel/event_form.html @@ -12,6 +12,8 @@ {% block content %} +{% load static_content_extra %} +

Édition de l'événement {{ object.title }} ({{ object.start_day }})

{% csrf_token %} diff --git a/src/agenda_culturel/templates/agenda_culturel/import.html b/src/agenda_culturel/templates/agenda_culturel/import.html index 25ebe47..6bf3dab 100644 --- a/src/agenda_culturel/templates/agenda_culturel/import.html +++ b/src/agenda_culturel/templates/agenda_culturel/import.html @@ -2,11 +2,19 @@ {% block title %}Importer un événement{% endblock %} + {% block content %} +

Importer un événement

+
+
+{% url 'event_import_form' as local_url %} +{% include "agenda_culturel/static_content.html" with name="import" url_path=local_url %} +
{% csrf_token %} {{ form.as_p }} +
{% endblock %} diff --git a/src/agenda_culturel/templates/agenda_culturel/page-week.html b/src/agenda_culturel/templates/agenda_culturel/page-week.html index 7b91a4c..72e7aac 100644 --- a/src/agenda_culturel/templates/agenda_culturel/page-week.html +++ b/src/agenda_culturel/templates/agenda_culturel/page-week.html @@ -25,12 +25,17 @@ {% block content %} + {% if home %} +
{% include "agenda_culturel/static_content.html" with name="home" url_path="/" %}
+ {% endif %} +

Les événements de la semaine {{ week }}

Du {{ calendar.calendar_days_list.0.date }} au {{ calendar.calendar_days_list.6.date }}

+ {% include "agenda_culturel/filter-inc.html" with filter=filter %}
diff --git a/src/agenda_culturel/templates/agenda_culturel/static_content.html b/src/agenda_culturel/templates/agenda_culturel/static_content.html new file mode 100644 index 0000000..950db5e --- /dev/null +++ b/src/agenda_culturel/templates/agenda_culturel/static_content.html @@ -0,0 +1,14 @@ +{% load static_content_extra %} + +{% get_static_content_by_name name as content %} +{% if content %} + {% if user.is_authenticated %} + Éditer + {% endif %} + {{ content.text|safe }} +{% else %} + {% if user.is_authenticated %} + Créer +

Le contenu statique {{ name }} n'a pas encore été défini.

+{% endif %} +{% endif %} diff --git a/src/agenda_culturel/templates/agenda_culturel/staticcontent_form.html b/src/agenda_culturel/templates/agenda_culturel/staticcontent_form.html new file mode 100644 index 0000000..ab7ccdc --- /dev/null +++ b/src/agenda_culturel/templates/agenda_culturel/staticcontent_form.html @@ -0,0 +1,22 @@ +{% extends "agenda_culturel/page.html" %} + +{% block title %}Éditer {{ object.name }}{% endblock %} + +{% block entete_header %} +{% load static %} + + + + +{% endblock %} + +{% block content %} + +

Édition du contenu statique {{ object.name }}

+ +
{% csrf_token %} + {{ form.as_p }} + +
+ +{% endblock %} \ No newline at end of file diff --git a/src/agenda_culturel/templatetags/static_content_extra.py b/src/agenda_culturel/templatetags/static_content_extra.py new file mode 100644 index 0000000..256f43c --- /dev/null +++ b/src/agenda_culturel/templatetags/static_content_extra.py @@ -0,0 +1,20 @@ +from django import template +from django.utils.safestring import mark_safe + +from agenda_culturel.models import StaticContent +from django.db.models import Q + +register = template.Library() + +@register.simple_tag +def get_static_content_by_name(name): + result = StaticContent.objects.filter(name=name) + if result is None or len(result) == 0: + return None + else: + return result[0] + +@register.simple_tag +def concat_all(*args): + """concatenate all args""" + return ''.join(map(str, args)) \ No newline at end of file diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index e8aae57..4e7a4b0 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -26,6 +26,8 @@ urlpatterns = [ path("admin/", admin.site.urls), path('accounts/', include('django.contrib.auth.urls')), path("test_app/", include("test_app.urls")), + path("static-content/create", StaticContentCreateView.as_view(), name="create_static_content"), + path("static-content//edit", StaticContentUpdateView.as_view(), name="edit_static_content") ] if settings.DEBUG: diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 6547c20..e6c3d56 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -8,7 +8,7 @@ from django import forms from .forms import EventSubmissionModelForm from .celery import create_event_from_submission -from .models import Event, Category +from .models import Event, Category, StaticContent from django.utils import timezone from enum import StrEnum from datetime import datetime, timedelta, date, time @@ -221,7 +221,7 @@ class EventFilter(django_filters.FilterSet): def home(request): - return week_view(request) + return week_view(request, home=True) def month_view(request, year = None, month = None): now = date.today() @@ -238,7 +238,7 @@ def month_view(request, year = None, month = None): return render(request, 'agenda_culturel/page-month.html', context) -def week_view(request, year = None, week = None): +def week_view(request, year = None, week = None, home=True): now = date.today() if year is None: year = now.year @@ -249,6 +249,8 @@ def week_view(request, year = None, week = None): cweek = CalendarWeek(year, week, filter) context = {"year": year, "week": week, "calendar": cweek, "filter": filter } + if home: + context["home"] = 1 return render(request, 'agenda_culturel/page-week.html', context) @@ -285,6 +287,21 @@ def tag_list(request): return render(request, 'agenda_culturel/tags.html', context) +class StaticContentCreateView(LoginRequiredMixin, CreateView): + model = StaticContent + fields = ['text'] + + def form_valid(self, form): + form.instance.name = self.request.GET["name"] + form.instance.url_path = self.request.GET["url_path"] + return super().form_valid(form) + +class StaticContentUpdateView(LoginRequiredMixin, UpdateView): + model = StaticContent + fields = ['text'] + + + class EventForm(forms.ModelForm): class Meta: model = Event diff --git a/src/requirements.txt b/src/requirements.txt index dd7bb93..39b2a19 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -31,3 +31,5 @@ django-better-admin-arrayfield==1.4.2 django-filter==23.3 django-compressor==4.4 django-libsass==0.9 +django-ckeditor==6.7.0 +