Add editable "static" content
This commit is contained in:
		@@ -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):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								src/agenda_culturel/migrations/0012_staticcontent.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/agenda_culturel/migrations/0012_staticcontent.py
									
									
									
									
									
										Normal 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')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -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,
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@ INSTALLED_APPS = [
 | 
			
		||||
    'django_better_admin_arrayfield',
 | 
			
		||||
    'django_filters',
 | 
			
		||||
    'compressor',
 | 
			
		||||
    'ckeditor',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE = [
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -14,6 +14,11 @@
 | 
			
		||||
 | 
			
		||||
<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.as_p }}
 | 
			
		||||
    <input type="submit" value="Enregistrer">
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,8 @@
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
{% load static_content_extra %}
 | 
			
		||||
 | 
			
		||||
<h1>Édition de l'événement {{ object.title }} ({{ object.start_day }})</h1>
 | 
			
		||||
 | 
			
		||||
<form method="post">{% csrf_token %}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,19 @@
 | 
			
		||||
 | 
			
		||||
{% block title %}Importer un événement{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
<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="">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {{ form.as_p }}
 | 
			
		||||
            <input type="submit" value="Lancer l'import">
 | 
			
		||||
        </form>
 | 
			
		||||
</article>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,12 +25,17 @@
 | 
			
		||||
 | 
			
		||||
 {% block content %}
 | 
			
		||||
 | 
			
		||||
 {% if home %}
 | 
			
		||||
 <article>{% include "agenda_culturel/static_content.html" with name="home" url_path="/" %}</article>
 | 
			
		||||
 {% endif %}
 | 
			
		||||
 | 
			
		||||
 <hgroup>
 | 
			
		||||
 <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>
 | 
			
		||||
</hgroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% include "agenda_culturel/filter-inc.html" with filter=filter %}
 | 
			
		||||
 | 
			
		||||
<article>
 | 
			
		||||
 
 | 
			
		||||
@@ -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 %}
 | 
			
		||||
@@ -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 %}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/agenda_culturel/templatetags/static_content_extra.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/agenda_culturel/templatetags/static_content_extra.py
									
									
									
									
									
										Normal 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))
 | 
			
		||||
@@ -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/<int:pk>/edit", StaticContentUpdateView.as_view(), name="edit_static_content")
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
if settings.DEBUG:
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user