Add editable "static" content

This commit is contained in:
Jean-Marie Favreau 2023-11-09 23:57:58 +01:00
parent 0ae51cd30f
commit 84d650eabd
16 changed files with 174 additions and 4 deletions

View File

@ -1,12 +1,14 @@
from django.contrib import admin from django.contrib import admin
from django import forms 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.admin.mixins import DynamicArrayMixin
from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget from django_better_admin_arrayfield.forms.widgets import DynamicArrayWidget
from django_better_admin_arrayfield.models.fields import DynamicArrayField from django_better_admin_arrayfield.models.fields import DynamicArrayField
admin.site.register(EventSubmissionForm) admin.site.register(EventSubmissionForm)
admin.site.register(Category) admin.site.register(Category)
admin.site.register(StaticContent)
class URLWidget(DynamicArrayWidget): class URLWidget(DynamicArrayWidget):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -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')),
],
),
]

View File

@ -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,
),
]

View File

@ -4,11 +4,25 @@ from django.utils.translation import gettext_lazy as _
from django.template.defaultfilters import slugify # new from django.template.defaultfilters import slugify # new
from django.urls import reverse from django.urls import reverse
from colorfield.fields import ColorField from colorfield.fields import ColorField
from ckeditor.fields import RichTextField
from django.template.defaultfilters import date as _date from django.template.defaultfilters import date as _date
from datetime import datetime 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): class Category(models.Model):
default_name = "Sans catégorie" default_name = "Sans catégorie"

View File

@ -42,6 +42,7 @@ INSTALLED_APPS = [
'django_better_admin_arrayfield', 'django_better_admin_arrayfield',
'django_filters', 'django_filters',
'compressor', 'compressor',
'ckeditor',
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -301,4 +301,19 @@ article#filters {
.helptext { .helptext {
font-size: 80%; font-size: 80%;
opacity: 0.7; 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;
} }

View File

@ -14,6 +14,11 @@
<h1>Proposer un événement</h1> <h1>Proposer un événement</h1>
<article>
{% url 'add_event' as local_url %}
{% include "agenda_culturel/static_content.html" with name="add_event" url_path=local_url %}
</article>
<form method="post">{% csrf_token %} <form method="post">{% csrf_token %}
{{ form.as_p }} {{ form.as_p }}
<input type="submit" value="Enregistrer"> <input type="submit" value="Enregistrer">

View File

@ -12,6 +12,8 @@
{% block content %} {% block content %}
{% load static_content_extra %}
<h1>Édition de l'événement {{ object.title }} ({{ object.start_day }})</h1> <h1>Édition de l'événement {{ object.title }} ({{ object.start_day }})</h1>
<form method="post">{% csrf_token %} <form method="post">{% csrf_token %}

View File

@ -2,11 +2,19 @@
{% block title %}Importer un événement{% endblock %} {% block title %}Importer un événement{% endblock %}
{% block content %} {% block content %}
<h1>Importer un événement</h1> <h1>Importer un événement</h1>
<article>
<header>
{% url 'event_import_form' as local_url %}
{% include "agenda_culturel/static_content.html" with name="import" url_path=local_url %}
</header>
<form method="post" action=""> <form method="post" action="">
{% csrf_token %} {% csrf_token %}
{{ form.as_p }} {{ form.as_p }}
<input type="submit" value="Lancer l'import"> <input type="submit" value="Lancer l'import">
</form> </form>
</article>
{% endblock %} {% endblock %}

View File

@ -25,12 +25,17 @@
{% block content %} {% block content %}
{% if home %}
<article>{% include "agenda_culturel/static_content.html" with name="home" url_path="/" %}</article>
{% endif %}
<hgroup> <hgroup>
<h1>Les événements de la semaine {{ week }}</h1> <h1>Les événements de la semaine {{ week }}</h1>
<h2>Du {{ calendar.calendar_days_list.0.date }} au {{ calendar.calendar_days_list.6.date }} </h2> <h2>Du {{ calendar.calendar_days_list.0.date }} au {{ calendar.calendar_days_list.6.date }} </h2>
</hgroup> </hgroup>
{% include "agenda_culturel/filter-inc.html" with filter=filter %} {% include "agenda_culturel/filter-inc.html" with filter=filter %}
<article> <article>

View File

@ -0,0 +1,14 @@
{% load static_content_extra %}
{% get_static_content_by_name name as content %}
{% if content %}
{% if user.is_authenticated %}
<a href="{% url 'edit_static_content' content.pk %}" role="button" class="slide-buttons">Éditer</a>
{% endif %}
{{ content.text|safe }}
{% else %}
{% if user.is_authenticated %}
<a href="{% url 'create_static_content' %}?name={{ name }}&url_path={{ url_path }}" role="button" class="slide-buttons">Créer</a>
<p><em>Le contenu statique <strong>{{ name }}</strong> n'a pas encore été défini.</em></p>
{% endif %}
{% endif %}

View File

@ -0,0 +1,22 @@
{% extends "agenda_culturel/page.html" %}
{% block title %}Éditer {{ object.name }}{% endblock %}
{% block entete_header %}
{% load static %}
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
{% endblock %}
{% block content %}
<h1>Édition du contenu statique {{ object.name }}</h1>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Enregistrer">
</form>
{% endblock %}

View File

@ -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))

View File

@ -26,6 +26,8 @@ urlpatterns = [
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')), path('accounts/', include('django.contrib.auth.urls')),
path("test_app/", include("test_app.urls")), path("test_app/", include("test_app.urls")),
path("static-content/create", StaticContentCreateView.as_view(), name="create_static_content"),
path("static-content/<int:pk>/edit", StaticContentUpdateView.as_view(), name="edit_static_content")
] ]
if settings.DEBUG: if settings.DEBUG:

View File

@ -8,7 +8,7 @@ from django import forms
from .forms import EventSubmissionModelForm from .forms import EventSubmissionModelForm
from .celery import create_event_from_submission from .celery import create_event_from_submission
from .models import Event, Category from .models import Event, Category, StaticContent
from django.utils import timezone from django.utils import timezone
from enum import StrEnum from enum import StrEnum
from datetime import datetime, timedelta, date, time from datetime import datetime, timedelta, date, time
@ -221,7 +221,7 @@ class EventFilter(django_filters.FilterSet):
def home(request): def home(request):
return week_view(request) return week_view(request, home=True)
def month_view(request, year = None, month = None): def month_view(request, year = None, month = None):
now = date.today() now = date.today()
@ -238,7 +238,7 @@ def month_view(request, year = None, month = None):
return render(request, 'agenda_culturel/page-month.html', context) 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() now = date.today()
if year is None: if year is None:
year = now.year year = now.year
@ -249,6 +249,8 @@ def week_view(request, year = None, week = None):
cweek = CalendarWeek(year, week, filter) cweek = CalendarWeek(year, week, filter)
context = {"year": year, "week": week, "calendar": cweek, "filter": filter } context = {"year": year, "week": week, "calendar": cweek, "filter": filter }
if home:
context["home"] = 1
return render(request, 'agenda_culturel/page-week.html', context) 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) 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 EventForm(forms.ModelForm):
class Meta: class Meta:
model = Event model = Event

View File

@ -31,3 +31,5 @@ django-better-admin-arrayfield==1.4.2
django-filter==23.3 django-filter==23.3
django-compressor==4.4 django-compressor==4.4
django-libsass==0.9 django-libsass==0.9
django-ckeditor==6.7.0