Add editable "static" content
This commit is contained in:
parent
0ae51cd30f
commit
84d650eabd
@ -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):
|
||||||
|
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.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"
|
||||||
|
@ -42,6 +42,7 @@ INSTALLED_APPS = [
|
|||||||
'django_better_admin_arrayfield',
|
'django_better_admin_arrayfield',
|
||||||
'django_filters',
|
'django_filters',
|
||||||
'compressor',
|
'compressor',
|
||||||
|
'ckeditor',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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">
|
||||||
|
@ -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 %}
|
||||||
|
@ -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 %}
|
||||||
|
@ -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>
|
||||||
|
@ -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("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:
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user