Merge branch 'evarin/site-cof' into 'master'

Nouveau site du COF

See merge request klub-dev-ens/gestioCOF!247
This commit is contained in:
Martin Pepin 2019-01-14 21:23:10 +01:00
commit 512868ee14
43 changed files with 4457 additions and 4 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@ venv/
/src /src
media/ media/
*.log *.log
.sass-cache/
*.sqlite3 *.sqlite3
.coverage .coverage

View file

11
cof/locale/en/formats.py Normal file
View file

@ -0,0 +1,11 @@
# -*- encoding: utf-8 -*-
"""
English formatting.
"""
from __future__ import unicode_literals
DATETIME_FORMAT = r"l N j, Y \a\t P"
DATE_FORMAT = r"l N j, Y"
TIME_FORMAT = r"P"

View file

@ -2,4 +2,6 @@
Formats français. Formats français.
""" """
DATETIME_FORMAT = r"l j F Y \à H:i" DATETIME_FORMAT = r"l j F Y \à H\hi"
DATE_FORMAT = r"l j F Y"
TIME_FORMAT = r"H\hi"

View file

@ -90,14 +90,17 @@ INSTALLED_APPS = [
"wagtail.wagtailadmin", "wagtail.wagtailadmin",
"wagtail.wagtailcore", "wagtail.wagtailcore",
"wagtail.contrib.modeladmin", "wagtail.contrib.modeladmin",
"wagtail.contrib.wagtailroutablepage",
"wagtailmenus", "wagtailmenus",
"wagtail_modeltranslation",
"modelcluster", "modelcluster",
"taggit", "taggit",
"kfet.auth", "kfet.auth",
"kfet.cms", "kfet.cms",
"corsheaders", "gestioncof.cms",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware", "corsheaders.middleware.CorsMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.sessions.middleware.SessionMiddleware",
@ -112,6 +115,7 @@ MIDDLEWARE = [
"djconfig.middleware.DjConfigMiddleware", "djconfig.middleware.DjConfigMiddleware",
"wagtail.wagtailcore.middleware.SiteMiddleware", "wagtail.wagtailcore.middleware.SiteMiddleware",
"wagtail.wagtailredirects.middleware.RedirectMiddleware", "wagtail.wagtailredirects.middleware.RedirectMiddleware",
"django.middleware.locale.LocaleMiddleware",
] ]
ROOT_URLCONF = "cof.urls" ROOT_URLCONF = "cof.urls"
@ -164,6 +168,8 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
LANGUAGES = (("fr", "Français"), ("en", "English"))
# Various additional settings # Various additional settings
SITE_ID = 1 SITE_ID = 1

View file

@ -4,6 +4,7 @@ Fichier principal de configuration des urls du projet GestioCOF
from django.conf import settings from django.conf import settings
from django.conf.urls import include, url from django.conf.urls import include, url
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import views as django_views from django.contrib.auth import views as django_views
@ -131,4 +132,6 @@ if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Wagtail for uncatched # Wagtail for uncatched
urlpatterns += [url(r"", include(wagtail_urls))] urlpatterns += i18n_patterns(
url(r"", include(wagtail_urls)), prefix_default_language=False
)

View file

@ -0,0 +1 @@
default_app_config = "gestioncof.cms.apps.COFCMSAppConfig"

7
gestioncof/cms/apps.py Normal file
View file

@ -0,0 +1,7 @@
from django.apps import AppConfig
class COFCMSAppConfig(AppConfig):
name = "gestioncof.cms"
label = "cofcms"
verbose_name = "CMS COF"

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,940 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-01-20 19:10
from __future__ import unicode_literals
import django.db.models.deletion
import wagtail.wagtailcore.blocks
import wagtail.wagtailcore.fields
import wagtail.wagtailimages.blocks
from django.db import migrations, models
import gestioncof.cms.models
class Migration(migrations.Migration):
initial = True
dependencies = [
("wagtailcore", "0033_remove_golive_expiry_help_text"),
("wagtailimages", "0019_delete_filter"),
]
operations = [
migrations.CreateModel(
name="COFActuIndexPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
],
options={
"verbose_name": "Index des actualités",
"verbose_name_plural": "Indexs des actualités",
},
bases=("wagtailcore.page", gestioncof.cms.models.COFActuIndexMixin),
),
migrations.CreateModel(
name="COFActuPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"chapo",
models.TextField(blank=True, verbose_name="Description rapide"),
),
(
"chapo_fr",
models.TextField(
blank=True, null=True, verbose_name="Description rapide"
),
),
(
"chapo_en",
models.TextField(
blank=True, null=True, verbose_name="Description rapide"
),
),
(
"body",
wagtail.wagtailcore.fields.RichTextField(verbose_name="Contenu"),
),
(
"body_fr",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Contenu"
),
),
(
"body_en",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Contenu"
),
),
(
"is_event",
models.BooleanField(default=True, verbose_name="Évènement"),
),
(
"date_start",
models.DateTimeField(verbose_name="Date et heure de début"),
),
(
"date_end",
models.DateTimeField(
blank=True,
default=None,
null=True,
verbose_name="Date et heure de fin",
),
),
(
"all_day",
models.BooleanField(default=False, verbose_name="Toute la journée"),
),
(
"image",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="wagtailimages.Image",
verbose_name="Image à la Une",
),
),
],
options={"verbose_name": "Actualité", "verbose_name_plural": "Actualités"},
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name="COFDirectoryEntryPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"body",
wagtail.wagtailcore.fields.RichTextField(
verbose_name="Description"
),
),
(
"body_fr",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Description"
),
),
(
"body_en",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Description"
),
),
(
"links",
wagtail.wagtailcore.fields.StreamField(
(
(
"lien",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
(
"contact",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"email",
wagtail.wagtailcore.blocks.EmailBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
)
),
),
(
"links_fr",
wagtail.wagtailcore.fields.StreamField(
(
(
"lien",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
(
"contact",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"email",
wagtail.wagtailcore.blocks.EmailBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
),
null=True,
),
),
(
"links_en",
wagtail.wagtailcore.fields.StreamField(
(
(
"lien",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
(
"contact",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"email",
wagtail.wagtailcore.blocks.EmailBlock(
required=True
),
),
(
"texte",
wagtail.wagtailcore.blocks.CharBlock(),
),
)
),
),
),
null=True,
),
),
(
"image",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to="wagtailimages.Image",
verbose_name="Image",
),
),
],
options={
"verbose_name": "Éntrée d'annuaire",
"verbose_name_plural": "Éntrées d'annuaire",
},
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name="COFDirectoryPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"introduction",
wagtail.wagtailcore.fields.RichTextField(
verbose_name="Introduction"
),
),
(
"introduction_fr",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Introduction"
),
),
(
"introduction_en",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Introduction"
),
),
],
options={
"verbose_name": "Annuaire (clubs, partenaires, bons plans...)",
"verbose_name_plural": "Annuaires",
},
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name="COFPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"body",
wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(
classname="full title"
),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
)
),
),
(
"body_fr",
wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(
classname="full title"
),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
),
null=True,
),
),
(
"body_en",
wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(
classname="full title"
),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
),
null=True,
),
),
],
options={
"verbose_name": "Page normale COF",
"verbose_name_plural": "Pages normales COF",
},
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name="COFRootPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
),
(
"title_fr",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"title_en",
models.CharField(
help_text="The page title as you'd like it to be seen by the public",
max_length=255,
null=True,
verbose_name="title",
),
),
(
"slug_fr",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"slug_en",
models.SlugField(
allow_unicode=True,
help_text="The name of the page as it will appear in URLs e.g http://domain.com/blog/[my-slug]/",
max_length=255,
null=True,
verbose_name="slug",
),
),
(
"url_path_fr",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"url_path_en",
models.TextField(
blank=True, editable=False, null=True, verbose_name="URL path"
),
),
(
"seo_title_fr",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"seo_title_en",
models.CharField(
blank=True,
help_text="Optional. 'Search Engine Friendly' title. This will appear at the top of the browser window.",
max_length=255,
null=True,
verbose_name="page title",
),
),
(
"search_description_fr",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"search_description_en",
models.TextField(
blank=True, null=True, verbose_name="search description"
),
),
(
"introduction",
wagtail.wagtailcore.fields.RichTextField(
verbose_name="Introduction"
),
),
(
"introduction_fr",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Introduction"
),
),
(
"introduction_en",
wagtail.wagtailcore.fields.RichTextField(
null=True, verbose_name="Introduction"
),
),
],
options={
"verbose_name": "Racine site du COF",
"verbose_name_plural": "Racines site du COF",
},
bases=("wagtailcore.page", gestioncof.cms.models.COFActuIndexMixin),
),
]

View file

@ -0,0 +1,160 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-04-28 13:46
from __future__ import unicode_literals
import django.db.models.deletion
import wagtail.contrib.wagtailroutablepage.models
import wagtail.wagtailcore.blocks
import wagtail.wagtailcore.fields
import wagtail.wagtailimages.blocks
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("wagtailcore", "0039_collectionviewrestriction"),
("cofcms", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="COFUtilPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.Page",
),
)
],
options={
"verbose_name": "Page utilitaire",
"verbose_name_plural": "Pages utilitaires",
},
bases=(
wagtail.contrib.wagtailroutablepage.models.RoutablePageMixin,
"wagtailcore.page",
),
),
migrations.AlterModelOptions(
name="cofdirectoryentrypage",
options={
"verbose_name": "Entrée d'annuaire",
"verbose_name_plural": "Entrées d'annuaire",
},
),
migrations.AddField(
model_name="cofdirectorypage",
name="alphabetique",
field=models.BooleanField(
default=True, verbose_name="Tri par ordre alphabétique ?"
),
),
migrations.AlterField(
model_name="cofpage",
name="body",
field=wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(classname="full title"),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
(
"iframe",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
"Adresse de la page"
),
),
(
"height",
wagtail.wagtailcore.blocks.CharBlock(
"Hauteur (en pixels)"
),
),
)
),
),
)
),
),
migrations.AlterField(
model_name="cofpage",
name="body_en",
field=wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(classname="full title"),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
(
"iframe",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
"Adresse de la page"
),
),
(
"height",
wagtail.wagtailcore.blocks.CharBlock(
"Hauteur (en pixels)"
),
),
)
),
),
),
null=True,
),
),
migrations.AlterField(
model_name="cofpage",
name="body_fr",
field=wagtail.wagtailcore.fields.StreamField(
(
(
"heading",
wagtail.wagtailcore.blocks.CharBlock(classname="full title"),
),
("paragraph", wagtail.wagtailcore.blocks.RichTextBlock()),
("image", wagtail.wagtailimages.blocks.ImageChooserBlock()),
(
"iframe",
wagtail.wagtailcore.blocks.StructBlock(
(
(
"url",
wagtail.wagtailcore.blocks.URLBlock(
"Adresse de la page"
),
),
(
"height",
wagtail.wagtailcore.blocks.CharBlock(
"Hauteur (en pixels)"
),
),
)
),
),
),
null=True,
),
),
]

View file

234
gestioncof/cms/models.py Normal file
View file

@ -0,0 +1,234 @@
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import models
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route
from wagtail.wagtailadmin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.wagtailcore import blocks
from wagtail.wagtailcore.fields import RichTextField, StreamField
from wagtail.wagtailcore.models import Page
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
# Page pouvant afficher des actualités
class COFActuIndexMixin:
@property
def actus(self):
actus = COFActuPage.objects.live().order_by("-date_start").descendant_of(self)
return actus
# Racine du site du COF
class COFRootPage(Page, COFActuIndexMixin):
introduction = RichTextField("Introduction")
content_panels = Page.content_panels + [
FieldPanel("introduction", classname="full")
]
subpage_types = ["COFActuIndexPage", "COFPage", "COFDirectoryPage", "COFUtilPage"]
class Meta:
verbose_name = "Racine site du COF"
verbose_name_plural = "Racines site du COF"
# Block iframe
class IFrameBlock(blocks.StructBlock):
url = blocks.URLBlock("Adresse de la page")
height = blocks.CharBlock("Hauteur (en pixels)")
class Meta:
verbose_name = "Page incluse (iframe, à utiliser avec précaution)"
verbose_name_plural = "Pages incluses (iframes, à utiliser avec précaution)"
template = "cofcms/iframe_block.html"
# Page lambda du site
class COFPage(Page):
body = StreamField(
[
("heading", blocks.CharBlock(classname="full title")),
("paragraph", blocks.RichTextBlock()),
("image", ImageChooserBlock()),
("iframe", IFrameBlock()),
]
)
content_panels = Page.content_panels + [StreamFieldPanel("body")]
subpage_types = ["COFDirectoryPage", "COFPage"]
parent_page_types = ["COFPage", "COFRootPage"]
class Meta:
verbose_name = "Page normale COF"
verbose_name_plural = "Pages normales COF"
# Actualités
class COFActuIndexPage(Page, COFActuIndexMixin):
subpage_types = ["COFActuPage"]
parent_page_types = ["COFRootPage"]
class Meta:
verbose_name = "Index des actualités"
verbose_name_plural = "Indexs des actualités"
def get_context(self, request):
context = super().get_context(request)
actus = COFActuPage.objects.live().descendant_of(self).order_by("-date_end")
page = request.GET.get("page")
paginator = Paginator(actus, 5)
try:
actus = paginator.page(page)
except PageNotAnInteger:
actus = paginator.page(1)
except EmptyPage:
actus = paginator.page(paginator.num_pages)
context["actus"] = actus
return context
class COFActuPage(RoutablePageMixin, Page):
chapo = models.TextField("Description rapide", blank=True)
body = RichTextField("Contenu")
image = models.ForeignKey(
"wagtailimages.Image",
verbose_name="Image à la Une",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
is_event = models.BooleanField("Évènement", default=True, blank=True)
date_start = models.DateTimeField("Date et heure de début")
date_end = models.DateTimeField(
"Date et heure de fin", blank=True, default=None, null=True
)
all_day = models.BooleanField("Toute la journée", default=False, blank=True)
content_panels = Page.content_panels + [
ImageChooserPanel("image"),
FieldPanel("chapo"),
FieldPanel("body", classname="full"),
FieldPanel("is_event"),
FieldPanel("date_start"),
FieldPanel("date_end"),
FieldPanel("all_day"),
]
subpage_types = []
parent_page_types = ["COFActuIndexPage"]
class Meta:
verbose_name = "Actualité"
verbose_name_plural = "Actualités"
# Annuaires (Clubs, partenaires, bonnes adresses)
class COFDirectoryPage(Page):
introduction = RichTextField("Introduction")
alphabetique = models.BooleanField(
"Tri par ordre alphabétique ?", default=True, blank=True
)
content_panels = Page.content_panels + [
FieldPanel("introduction"),
FieldPanel("alphabetique"),
]
subpage_types = ["COFActuPage", "COFDirectoryEntryPage"]
parent_page_types = ["COFRootPage", "COFPage"]
@property
def entries(self):
entries = COFDirectoryEntryPage.objects.live().descendant_of(self)
if self.alphabetique:
entries = entries.order_by("title")
return entries
class Meta:
verbose_name = "Annuaire (clubs, partenaires, bons plans...)"
verbose_name_plural = "Annuaires"
class COFDirectoryEntryPage(Page):
body = RichTextField("Description")
links = StreamField(
[
(
"lien",
blocks.StructBlock(
[
("url", blocks.URLBlock(required=True)),
("texte", blocks.CharBlock()),
]
),
),
(
"contact",
blocks.StructBlock(
[
("email", blocks.EmailBlock(required=True)),
("texte", blocks.CharBlock()),
]
),
),
]
)
image = models.ForeignKey(
"wagtailimages.Image",
verbose_name="Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
content_panels = Page.content_panels + [
ImageChooserPanel("image"),
FieldPanel("body", classname="full"),
StreamFieldPanel("links"),
]
subpage_types = []
parent_page_types = ["COFDirectoryPage"]
class Meta:
verbose_name = "Entrée d'annuaire"
verbose_name_plural = "Entrées d'annuaire"
# Pour le calendrier, ne doit pas être pris par ModelTranslation
class COFUtilPage(RoutablePageMixin, Page):
# Mini calendrier
@route(r"^calendar/(\d+)/(\d+)/$")
def calendar(self, request, year, month):
from .views import raw_calendar_view
return raw_calendar_view(request, int(year), int(month))
"""
ModelTranslation override le système des @route de wagtail, ce qui empêche
COFUtilPage d'être une page traduite pour pouvoir l'utiliser.
Ce qui fait planter `get_absolute_url` pour des problèmes d'héritage des
pages parentes (qui sont, elles, traduites).
Le seul moyen trouvé pour résoudre ce problème est de faire une autre
fonction à qui on fournit request en argument (donc pas un override de
get_absolute_url).
TODO : vérifier si ces problèmes ont été résolus dans les màj de wagtail
et modeltranslation
"""
def debugged_get_url(self, request):
parent = COFRootPage.objects.parent_of(self).live().first()
burl = parent.relative_url(request.site)
return burl + self.slug
class Meta:
verbose_name = "Page utilitaire"
verbose_name_plural = "Pages utilitaires"

View file

@ -0,0 +1,25 @@
require 'compass/import-once/activate'
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "js"
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass

View file

@ -0,0 +1,5 @@
/* Welcome to Compass. Use this file to write IE specific override styles.
* Import this file using the following HTML or equivalent:
* <!--[if IE]>
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
* <![endif]--> */

View file

@ -0,0 +1,3 @@
/* Welcome to Compass. Use this file to define print styles.
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */

View file

@ -0,0 +1,669 @@
/* Welcome to Compass.
* In this file you should write your main styles. (or centralize your imports)
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
@import url("https://fonts.googleapis.com/css?family=Carter+One|Source+Sans+Pro:300,300i,700");
/* line 5, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
}
/* line 22, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html {
line-height: 1;
}
/* line 24, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
/* line 26, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* line 28, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
/* line 30, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
/* line 103, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
/* line 32, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
/* line 116, ../../../../../../../../../../var/lib/gems/2.3.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}
/* line 12, ../sass/screen.scss */
*, *:after, *:before {
box-sizing: border-box;
}
/* line 16, ../sass/screen.scss */
body {
background: #fefefe;
font: 17px "Source Sans Pro", "sans-serif";
}
/* line 21, ../sass/screen.scss */
header {
background: #5B0012;
}
/* line 25, ../sass/screen.scss */
h1, h2 {
font-family: "Carter One", "serif";
color: #90001C;
}
/* line 30, ../sass/screen.scss */
h1 {
font-size: 2.3em;
}
/* line 34, ../sass/screen.scss */
h2 {
font-size: 1.6em;
}
/* line 38, ../sass/screen.scss */
a {
color: #CC9500;
text-decoration: none;
font-weight: bold;
}
/* line 44, ../sass/screen.scss */
h2 a {
font-weight: inherit;
color: inherit;
}
/* line 50, ../sass/screen.scss */
header a {
color: #fefefe;
}
/* line 53, ../sass/screen.scss */
header section {
display: flex;
width: 100%;
justify-content: space-between;
align-items: stretch;
}
/* line 59, ../sass/screen.scss */
header section.bottom-menu {
justify-content: space-around;
text-align: center;
background: #90001C;
}
/* line 65, ../sass/screen.scss */
header h1 {
padding: 0 15px;
}
/* line 69, ../sass/screen.scss */
header nav ul {
display: inline-flex;
}
/* line 71, ../sass/screen.scss */
header nav ul li {
display: inline-block;
}
/* line 73, ../sass/screen.scss */
header nav ul li > * {
display: block;
padding: 10px 15px;
font-weight: bold;
}
/* line 78, ../sass/screen.scss */
header nav ul li > *:hover {
background: #280008;
}
/* line 84, ../sass/screen.scss */
header nav .lang-select {
display: inline-block;
height: 100%;
vertical-align: top;
position: relative;
}
/* line 90, ../sass/screen.scss */
header nav .lang-select:before {
content: "";
color: #fff;
position: absolute;
top: 0;
left: 0;
border-left: 1px solid #fff;
height: calc(100% - 20px);
margin: 10px 0;
padding-left: 10px;
}
/* line 102, ../sass/screen.scss */
header nav .lang-select a {
padding: 10px 20px;
display: block;
}
/* line 106, ../sass/screen.scss */
header nav .lang-select a img {
display: block;
width: auto;
max-height: 20px;
vertical-align: middle;
}
/* line 117, ../sass/screen.scss */
article {
line-height: 1.4;
}
/* line 119, ../sass/screen.scss */
article p, article ul {
margin: 0.4em 0;
}
/* line 122, ../sass/screen.scss */
article ul {
padding-left: 20px;
}
/* line 124, ../sass/screen.scss */
article ul li {
list-style: outside;
}
/* line 128, ../sass/screen.scss */
article:last-child {
margin-bottom: 30px;
}
/* line 133, ../sass/screen.scss */
.container {
max-width: 1000px;
margin: 0 auto;
position: relative;
}
/* line 138, ../sass/screen.scss */
.container .aside-wrap {
position: absolute;
top: 30px;
height: 100%;
width: 25%;
left: 6px;
}
/* line 145, ../sass/screen.scss */
.container .aside-wrap .aside {
color: #222;
position: fixed;
position: sticky;
top: 5px;
width: 100%;
background: #FFC500;
padding: 15px;
box-shadow: -4px 4px 1px rgba(153, 118, 0, 0.3);
}
/* line 155, ../sass/screen.scss */
.container .aside-wrap .aside h2 {
color: #fff;
}
/* line 159, ../sass/screen.scss */
.container .aside-wrap .aside .calendar {
margin: 0 auto;
display: block;
}
/* line 164, ../sass/screen.scss */
.container .aside-wrap .aside a {
color: #997000;
}
/* line 170, ../sass/screen.scss */
.container .content {
max-width: 900px;
margin-left: auto;
margin-right: 6px;
}
/* line 175, ../sass/screen.scss */
.container .content .intro {
border-bottom: 3px solid #7f7f7f;
margin: 20px 0;
margin-top: 5px;
padding: 15px 5px;
}
/* line 184, ../sass/screen.scss */
.container .content section article {
background: #fff;
padding: 20px 30px;
box-shadow: -4px 4px 1px rgba(153, 118, 0, 0.3);
border: 1px solid rgba(153, 118, 0, 0.1);
border-radius: 2px;
}
/* line 190, ../sass/screen.scss */
.container .content section article a {
color: #CC9500;
}
/* line 195, ../sass/screen.scss */
.container .content section article + h2 {
margin-top: 15px;
}
/* line 199, ../sass/screen.scss */
.container .content section article + article {
margin-top: 25px;
}
/* line 203, ../sass/screen.scss */
.container .content section .image {
margin: 15px 0;
text-align: center;
padding: 20px;
}
/* line 208, ../sass/screen.scss */
.container .content section .image img {
max-width: 100%;
height: auto;
box-shadow: -7px 7px 1px rgba(153, 118, 0, 0.2);
}
/* line 216, ../sass/screen.scss */
.container .content section.directory article.entry {
width: 80%;
max-width: 600px;
max-height: 100%;
position: relative;
margin-left: 6%;
}
/* line 223, ../sass/screen.scss */
.container .content section.directory article.entry .entry-image {
display: block;
float: right;
width: 150px;
background: #fff;
box-shadow: -4px 4px 1px rgba(153, 118, 0, 0.2);
border-right: 1px solid rgba(153, 118, 0, 0.2);
border-top: 1px solid rgba(153, 118, 0, 0.2);
padding: 1px;
overflow: hidden;
margin-left: 10px;
margin-bottom: 10px;
transform: translateX(10px);
}
/* line 237, ../sass/screen.scss */
.container .content section.directory article.entry .entry-image img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
/* line 245, ../sass/screen.scss */
.container .content section.directory article.entry ul.links {
margin-top: 10px;
border-top: 1px solid #90001C;
padding-top: 10px;
}
/* line 253, ../sass/screen.scss */
.container .content section.actuhome {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: top;
}
/* line 259, ../sass/screen.scss */
.container .content section.actuhome article + article {
margin: 0;
}
/* line 263, ../sass/screen.scss */
.container .content section.actuhome article.actu {
position: relative;
background: none;
box-shadow: none;
border: none;
max-width: 400px;
min-width: 300px;
flex: 1;
}
/* line 272, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-header {
position: relative;
box-shadow: -4px 5px 1px rgba(153, 118, 0, 0.3);
border-right: 1px solid rgba(153, 118, 0, 0.2);
border-top: 1px solid rgba(153, 118, 0, 0.2);
min-height: 180px;
padding: 0;
margin: 0;
overflow: hidden;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
/* line 285, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-header h2 {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
padding: 5px;
text-shadow: 0 0 5px rgba(153, 118, 0, 0.8);
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
}
/* line 293, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-header h2 a {
color: #fff;
}
/* line 299, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-misc {
background: white;
box-shadow: -2px 2px 1px rgba(153, 118, 0, 0.2);
border: 1px solid rgba(153, 118, 0, 0.2);
border-radius: 2px;
margin: 0 10px;
padding: 15px;
padding-top: 5px;
}
/* line 308, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-misc .actu-minical {
display: block;
}
/* line 311, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-misc .actu-dates {
display: block;
text-align: right;
font-size: 0.9em;
}
/* line 318, ../sass/screen.scss */
.container .content section.actuhome article.actu .actu-overlay {
display: block;
background: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 5;
opacity: 0;
}
/* line 334, ../sass/screen.scss */
.container .content section.actulist article.actu {
display: flex;
width: 100%;
padding: 0;
}
/* line 339, ../sass/screen.scss */
.container .content section.actulist article.actu .actu-image {
width: 30%;
max-width: 200px;
background-size: cover;
background-position: center center;
}
/* line 345, ../sass/screen.scss */
.container .content section.actulist article.actu .actu-infos {
padding: 15px;
flex: 1;
}
/* line 349, ../sass/screen.scss */
.container .content section.actulist article.actu .actu-infos .actu-dates {
font-weight: bold;
font-size: 0.9em;
}
/* line 359, ../sass/screen.scss */
.container .aside-wrap + .content {
max-width: 70%;
}
/* line 364, ../sass/screen.scss */
.calendar {
color: rgba(0, 0, 0, 0.8);
width: 200px;
}
/* line 368, ../sass/screen.scss */
.calendar td, .calendar th {
text-align: center;
vertical-align: middle;
border: 2px solid transparent;
padding: 1px;
}
/* line 375, ../sass/screen.scss */
.calendar th {
font-weight: bold;
}
/* line 379, ../sass/screen.scss */
.calendar td {
font-size: 0.8em;
width: 28px;
height: 28px;
}
/* line 384, ../sass/screen.scss */
.calendar td.out {
opacity: 0.3;
}
/* line 387, ../sass/screen.scss */
.calendar td.today {
border-bottom-color: #000;
}
/* line 390, ../sass/screen.scss */
.calendar td:nth-child(7), .calendar td:nth-child(6) {
background: rgba(0, 0, 0, 0.2);
}
/* line 393, ../sass/screen.scss */
.calendar td.hasevent {
position: relative;
font-weight: bold;
color: #90001C;
font-size: 1em;
}
/* line 399, ../sass/screen.scss */
.calendar td.hasevent > a {
padding: 3px;
color: #90001C !important;
}
/* line 404, ../sass/screen.scss */
.calendar td.hasevent ul.cal-events {
text-align: left;
display: none;
position: absolute;
z-index: 2;
background: #fff;
width: 150px;
left: -30px;
margin-top: 10px;
padding: 5px;
background-color: #90001C;
}
/* line 417, ../sass/screen.scss */
.calendar td.hasevent ul.cal-events .datename {
display: none;
}
/* line 420, ../sass/screen.scss */
.calendar td.hasevent ul.cal-events:before {
top: -12px;
left: 38px;
content: "";
position: absolute;
border: 6px solid transparent;
border-bottom-color: #90001C;
}
/* line 428, ../sass/screen.scss */
.calendar td.hasevent ul.cal-events a {
color: #fff;
}
/* line 433, ../sass/screen.scss */
.calendar td.hasevent > a:hover {
background-color: #90001C;
color: #fff !important;
}
/* line 437, ../sass/screen.scss */
.calendar td.hasevent > a:hover + ul.cal-events {
display: block;
}
/* line 445, ../sass/screen.scss */
#calendar-wrap .details {
border-top: 1px solid #90001C;
margin-top: 15px;
padding-top: 10px;
}
/* line 450, ../sass/screen.scss */
#calendar-wrap .details li.datename {
font-weight: bold;
font-size: 1.1em;
margin-bottom: 5px;
}
/* line 451, ../sass/screen.scss */
#calendar-wrap .details li.datename:after {
content: " :";
}
/* line 1, ../sass/_responsive.scss */
header .minimenu {
display: none;
}
@media only screen and (max-width: 600px) {
/* line 6, ../sass/_responsive.scss */
header {
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100%;
max-height: 100vh;
height: 60px;
overflow: hidden;
}
/* line 16, ../sass/_responsive.scss */
header .minimenu {
display: block;
position: absolute;
right: 3px;
top: 3px;
}
/* line 23, ../sass/_responsive.scss */
header section {
display: block;
}
/* line 25, ../sass/_responsive.scss */
header section nav {
display: none;
}
/* line 31, ../sass/_responsive.scss */
header.expanded {
overflow: auto;
height: auto;
}
/* line 35, ../sass/_responsive.scss */
header.expanded nav {
display: block;
text-align: center;
}
/* line 38, ../sass/_responsive.scss */
header.expanded nav ul {
flex-wrap: wrap;
justify-content: right;
}
/* line 41, ../sass/_responsive.scss */
header.expanded nav ul li > * {
padding: 18px;
}
/* line 48, ../sass/_responsive.scss */
.container {
margin-top: 65px;
}
/* line 51, ../sass/_responsive.scss */
.container .content {
max-width: unset;
margin: 6px;
}
/* line 56, ../sass/_responsive.scss */
.container .content section article {
padding: 10px;
}
/* line 60, ../sass/_responsive.scss */
.container .content section .image {
padding: 0;
margin: 10px -6px;
}
/* line 65, ../sass/_responsive.scss */
.container .content section.directory article.entry {
width: 100%;
margin-left: 0;
}
/* line 72, ../sass/_responsive.scss */
.container .aside-wrap + .content {
max-width: unset;
margin-top: 120px;
}
/* line 77, ../sass/_responsive.scss */
.container .aside-wrap {
z-index: 3;
top: 60px;
position: fixed;
width: 100%;
margin: 0;
height: auto;
left: 0;
}
/* line 86, ../sass/_responsive.scss */
.container .aside-wrap .aside {
margin: 0;
padding: 0;
top: 0;
position: unset;
}
/* line 92, ../sass/_responsive.scss */
.container .aside-wrap .aside > h2 {
position: relative;
cursor: pointer;
padding: 5px 10px;
}
/* line 96, ../sass/_responsive.scss */
.container .aside-wrap .aside > h2:after {
content: "v";
font-family: "Source Sans Pro", "sans-serif";
font-weight: bold;
color: #CC9500;
position: absolute;
right: 10px;
}
/* line 106, ../sass/_responsive.scss */
.container .aside-wrap .aside:not(.expanded) .aside-content {
display: none;
}
/* line 111, ../sass/_responsive.scss */
.container .aside-wrap .aside ul {
text-align: center;
}
/* line 113, ../sass/_responsive.scss */
.container .aside-wrap .aside ul li {
display: inline-block;
}
/* line 115, ../sass/_responsive.scss */
.container .aside-wrap .aside ul li > * {
display: block;
padding: 15px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
<path fill="none" stroke="#FFFFFF" stroke-width="2" d="M47.062,41.393c0,3.131-2.538,5.669-5.669,5.669H8.608 c-3.131,0-5.669-2.538-5.669-5.669V8.608c0-3.131,2.538-5.669,5.669-5.669h32.785c3.131,0,5.669,2.538,5.669,5.669V41.393z"/>
<g>
<line fill="none" stroke="#FFFFFF" stroke-width="3" x1="10.826" y1="15" x2="40.241" y2="15"/>
<line fill="none" stroke="#FFFFFF" stroke-width="3" x1="10.826" y1="25" x2="40.241" y2="25"/>
<line fill="none" stroke="#FFFFFF" stroke-width="3" x1="10.826" y1="35" x2="40.241" y2="35"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 998 B

View file

@ -0,0 +1,32 @@
$(function(){
var mem = {};
var ctt = $("#calendar-wrap");
makeInteractive();
function makeInteractive () {
$(".cal-btn").on("click", loadCalendar);
$(".hasevent a").on("click", showEvents);
}
function loadCalendar () {
var url = $(this).attr("cal-dest");
if (mem[url] != undefined) {
ctt.html(mem[url]);
makeInteractive();
return;
}
ctt.innerText = "Chargement...";
ctt.load(url, function () {
mem[url] = this.innerHTML;
makeInteractive();
});
}
function showEvents() {
ctt.find(".details").remove();
ctt.append(
$("<div>", {class:"details"})
.html(this.nextElementSibling.outerHTML)
);
}
});

View file

@ -0,0 +1,13 @@
$(function() {
$(".facteur").on("click", function(){
var $this = $(this);
var sticker = $this.attr('data-mref')
.replace('pont', '.')
.replace('arbre', '@')
.replace(/(.)-/g, '$1');
var boite = $("<a>", {href:"ma"+"il"+"to:"+sticker}).text(sticker);
$(this).before(boite)
.remove();
})
});

View file

@ -0,0 +1,11 @@
$fond: #fefefe;
$bandeau: #5B0012;
$sousbandeau: #90001C;
$aside: #FFC500;
$titre: $sousbandeau;
$lien: #CC9500;
$headerlien: $fond;
$ombres: darken($aside, 20%);
$bodyfont: "Source Sans Pro", "sans-serif";
$headfont: "Carter One", "serif";

View file

@ -0,0 +1,124 @@
header .minimenu {
display: none;
}
@media only screen and (max-width: 600px) {
header {
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100%;
max-height: 100vh;
height: 60px;
overflow: hidden;
.minimenu {
display: block;
position: absolute;
right: 3px;
top: 3px;
}
section {
display: block;
nav {
display: none;
}
}
}
header.expanded {
overflow: auto;
height: auto;
nav {
display: block;
text-align: center;
ul {
flex-wrap: wrap;
justify-content: right;
li > * {
padding: 18px;
}
}
}
}
.container {
margin-top: 65px;
.content {
max-width: unset;
margin: 6px;
section {
article {
padding: 10px;
}
.image {
padding: 0;
margin: 10px -6px;
}
&.directory article.entry {
width: 100%;
margin-left: 0;
}
}
}
.aside-wrap + .content {
max-width: unset;
margin-top: 120px;
}
.aside-wrap {
z-index: 3;
top: 60px;
position: fixed;
width: 100%;
margin: 0;
height: auto;
left: 0;
.aside {
margin: 0;
padding: 0;
top: 0;
position: unset;
& > h2 {
position: relative;
cursor: pointer;
padding: 5px 10px;
&:after {
content: "v";
font-family: $bodyfont;
font-weight: bold;
color: $lien;
position: absolute;
right: 10px;
}
}
&:not(.expanded) {
.aside-content {
display: none;
}
}
ul {
text-align: center;
li {
display: inline-block;
& > * {
display: block;
padding: 15px;
}
}
}
}
}
}
}

View file

@ -0,0 +1,460 @@
/* Welcome to Compass.
* In this file you should write your main styles. (or centralize your imports)
* Import this file using the following HTML or equivalent:
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
@import url('https://fonts.googleapis.com/css?family=Carter+One|Source+Sans+Pro:300,300i,700');
@import "compass/reset";
@import "_colors";
*, *:after, *:before {
box-sizing: border-box;
}
body {
background: $fond;
font: 17px $bodyfont;
}
header {
background: $bandeau;
}
h1, h2 {
font-family: $headfont;
color: $titre;
}
h1 {
font-size: 2.3em;
}
h2 {
font-size: 1.6em;
}
a {
color: $lien;
text-decoration: none;
font-weight: bold;
}
h2 a {
font-weight: inherit;
color: inherit;
}
header {
a {
color: $headerlien;
}
section {
display: flex;
width: 100%;
justify-content: space-between;
align-items: stretch;
&.bottom-menu {
justify-content: space-around;
text-align: center;
background: $sousbandeau;
}
}
h1 {
padding: 0 15px;
}
nav {
ul {
display: inline-flex;
li {
display: inline-block;
& > * {
display: block;
padding: 10px 15px;
font-weight: bold;
&:hover {
background: darken($bandeau, 10%);
}
}
}
}
.lang-select {
display: inline-block;
height: 100%;
vertical-align: top;
position: relative;
&:before {
content: "";
color: #fff;
position: absolute;
top: 0;
left: 0;
border-left: 1px solid #fff;
height: calc(100% - 20px);
margin: 10px 0;
padding-left: 10px;
}
a {
padding: 10px 20px;
display: block;
img {
display: block;
width: auto;
max-height: 20px;
vertical-align: middle;
}
}
}
}
}
article {
line-height: 1.4;
p, ul {
margin: 0.4em 0;
}
ul {
padding-left: 20px;
li {
list-style: outside;
}
}
&:last-child {
margin-bottom: 30px;
}
}
.container {
max-width: 1000px;
margin: 0 auto;
position: relative;
.aside-wrap {
position: absolute;
top: 30px;
height: 100%;
width: 25%;
left: 6px;
.aside {
color: #222;
position: fixed;
position: sticky;
top: 5px;
width: 100%;
background: $aside;
padding: 15px;
box-shadow: -4px 4px 1px rgba($ombres, 0.3);
h2 {
color: #fff;
}
.calendar {
margin: 0 auto;
display: block;
}
a {
color: darken($lien, 10%);
}
}
}
.content {
max-width: 900px;
margin-left: auto;
margin-right: 6px;
.intro {
border-bottom: 3px solid darken($fond, 50%);
margin: 20px 0;
margin-top: 5px;
padding: 15px 5px;
}
section {
article {
background: #fff;
padding: 20px 30px;;
box-shadow: -4px 4px 1px rgba($ombres, 0.3);
border: 1px solid rgba($ombres, 0.1);
border-radius: 2px;
a {
color: $lien;
}
}
article + h2 {
margin-top: 15px;
}
article + article {
margin-top: 25px;
}
.image {
margin: 15px 0;
text-align: center;
padding: 20px;
img {
max-width: 100%;
height: auto;
box-shadow: -7px 7px 1px rgba($ombres, 0.2);
}
}
&.directory {
article.entry {
width: 80%;
max-width: 600px;
max-height: 100%;
position: relative;
margin-left: 6%;
.entry-image {
display: block;
float: right;
width: 150px;
background: #fff;
box-shadow: -4px 4px 1px rgba($ombres, 0.2);
border-right: 1px solid rgba($ombres, 0.2);
border-top: 1px solid rgba($ombres, 0.2);
padding: 1px;
overflow: hidden;
margin-left: 10px;
margin-bottom: 10px;
transform: translateX(10px);
img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
}
ul.links {
margin-top: 10px;
border-top: 1px solid $sousbandeau;
padding-top: 10px;
}
}
}
&.actuhome {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: top;
article + article {
margin: 0;
}
article.actu {
position: relative;
background: none;
box-shadow: none;
border: none;
max-width: 400px;
min-width: 300px;
flex: 1;
.actu-header {
position: relative;
box-shadow: -4px 5px 1px rgba($ombres, 0.3);
border-right: 1px solid rgba($ombres, 0.2);
border-top: 1px solid rgba($ombres, 0.2);
min-height: 180px;
padding: 0;
margin: 0;
overflow: hidden;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
h2 {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
padding: 5px;
text-shadow: 0 0 5px rgba($ombres, 0.8);
background: linear-gradient(to top, rgba(#000, 0.7), rgba(#000, 0));
a {
color: #fff;
}
}
}
.actu-misc {
background: lighten($fond, 15%);
box-shadow: -2px 2px 1px rgba($ombres, 0.2);
border: 1px solid rgba($ombres, 0.2);
border-radius: 2px;
margin: 0 10px;
padding: 15px;
padding-top: 5px;
.actu-minical {
display: block;
}
.actu-dates {
display: block;
text-align: right;
font-size: 0.9em;
}
}
.actu-overlay {
display: block;
background: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 5;
opacity: 0;
}
}
}
&.actulist {
article.actu {
display:flex;
width: 100%;
padding: 0;
.actu-image {
width: 30%;
max-width: 200px;
background-size: cover;
background-position: center center;
}
.actu-infos {
padding: 15px;
flex: 1;
.actu-dates {
font-weight: bold;
font-size: 0.9em;
}
}
}
}
}
}
.aside-wrap + .content {
max-width: 70%;
}
}
.calendar {
color: rgba(#000, 0.8);
width: 200px;
td, th {
text-align: center;
vertical-align: middle;
border: 2px solid transparent;
padding: 1px;
}
th {
font-weight: bold;
}
td {
font-size: 0.8em;
width: 28px;
height: 28px;
&.out {
opacity: 0.3;
}
&.today {
border-bottom-color: #000;
}
&:nth-child(7), &:nth-child(6) {
background: rgba(#000, 0.2);
}
&.hasevent {
position: relative;
font-weight: bold;
color: $sousbandeau;
font-size: 1em;
& > a {
padding: 3px;
color: $sousbandeau !important;
}
ul.cal-events {
text-align: left;
display: none;
position: absolute;
z-index: 2;
background: #fff;
width: 150px;
left: -30px;
margin-top: 10px;
padding: 5px;
background-color: $sousbandeau;
.datename {
display: none;
}
&:before {
top: -12px;
left: 38px;
content: "";
position: absolute;
border: 6px solid transparent;
border-bottom-color: $sousbandeau;
}
a {
color: #fff;
}
}
& > a:hover {
background-color: $sousbandeau;
color: #fff !important;
& + ul.cal-events {
display: block;
}
}
}
}
}
#calendar-wrap .details {
border-top: 1px solid $sousbandeau;
margin-top: 15px;
padding-top: 10px;
li.datename {
&:after {
content: " :";
}
font-weight: bold;
font-size: 1.1em;
margin-bottom: 5px;
}
}
@import "_responsive";

View file

@ -0,0 +1,51 @@
{% load static menu_tags wagtailuserbar i18n wagtailcore_tags %}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Association des élèves de l'ENS Ulm{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% static "cofcms/css/screen.css" %}"/>
{% block extra_head %}{% endblock %}
</head>
<body>
<header id="header">
<section class="top-menu">
<h1 class="cof"><a href="/">COF</a></h1>
<a class="minimenu" href="javascript:void(0)" onclick="document.getElementById('header').classList.toggle('expanded');"><img src="{% static "cofcms/images/minimenu.svg" %}"></a>
<nav>
{% flat_menu "cof-nav-ext" template="cofcms/base_nav.html" %}
</nav>
</section>
<section class="bottom-menu">
<nav>
{% flat_menu "cof-nav-int" template="cofcms/base_nav.html" apply_active_classes=True %}
{% get_current_language as curlang %}
<div class="lang-select">
{% if curlang == 'en' %}
{% language 'fr' %}
<a href="{% pageurl self %}" title="Français"><img src="{% static "cofcms/images/fr.png" %}"></a>
{% endlanguage %}
{% else %}
{% language 'en' %}
<a href="{% pageurl self %}" title="English"><img src="{% static "cofcms/images/en.png" %}"></a>
{% endlanguage %}
{% endif %}
</div>
</nav>
</section>
</header>
<div class="container">
{% block superaside %}{% endblock %}
<div class="content">
{% block content %}{% endblock %}
</div>
</div>
{% wagtailuserbar %}
</body>
</html>

View file

@ -0,0 +1,12 @@
{% extends "cofcms/base.html" %}
{% block superaside %}
<div class="aside-wrap">
<div class="aside" id="aside">
<h2 onclick="document.getElementById('aside').classList.toggle('expanded')">{% block aside_title %}{% endblock %}</h2>
<div class="aside-content">
{% block aside %}{% endblock %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% load wagtailcore_tags i18n cofcms_tags %}
<ul class="menu">
{% for item in menu_items %}
<li class="{{ item.active_class }}">
{% if item.link_page %}
<a href="{% pageurl item.link_page.specific %}">
{{ item.link_page.specific.title }}
</a>
{% else %}
<a href="{{ item.href }}">
{{ item.text }}
</a>
{% endif %}
</li>
{% endfor %}
</ul>

View file

@ -0,0 +1,28 @@
{% load wagtailcore_tags wagtailroutablepage_tags static i18n %}
<table class="calendar">
<tbody>
<tr>
<th><a href="javascript:void(0);" cal-dest="{{ prev_month }}" class="cal-btn">&lt;</a></th>
<th colspan="5">{{ this_month|date:"F Y" }}</th>
<th><a href="javascript:void(0);" cal-dest="{{ next_month }}" class="cal-btn">&gt;</a></th>
</tr>
<tr>{% blocktrans %}<th>L</th><th>M</th><th>M</th><th>J</th><th>V</th><th>S</th><th>D</th>{% endblocktrans %}</tr>
{% for week in weeks %}
<tr>
{% for day in week %}
<td class="{{ day.class }}">
{% if day.events %}
<a href="javascript:void(0)">{{ day.day }}</a>
<ul class="cal-events">
<li class="datename">{% trans "Le " %}{{ day.date|date }}</li>
{% for event in day.events %}
<li><a href="{% pageurl event %}">{{ event.title }}</a></li>
{% endfor %}
</ul>
{% else %}{{ day.day }}{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

View file

@ -0,0 +1,2 @@
{% load cofcms_tags %}
{% calendar month year %}

View file

@ -0,0 +1,53 @@
{% extends "cofcms/base_aside.html" %}
{% load wagtailimages_tags cofcms_tags wagtailcore_tags static i18n %}
{% block extra_head %}
{{ block.super }}
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "cofcms/js/calendar.js" %}"></script>
{% endblock %}
{% block aside_title %}Calendrier{% endblock %}
{% block aside %}
<div id="calendar-wrap">
{% calendar %}
</div>
{% endblock %}
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<div>{{ page.introduction|safe }}</div>
</section>
<section class="actulist">
{% if actus.has_previous %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">Actualités plus récentes</a>
{% endif %}
{% if actus.has_next %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">Actualités plus anciennes</a>
{% endif %}
{% for actu in page.actus %}
<article class="actu">
<div class="actu-image" {% if actu.image %}{% image actu.image fill-400x200 as img %}style="background-image:url('{{ img.url }}');"{% endif %}></div>
<div class="actu-infos">
<h2><a href="{% pageurl actu %}">{{ actu.title }}</a></h2>
{% if actu.is_event %}
<p><span class="actu-dates">{{ actu|dates|capfirst }}</span><br />{{ actu.chapo }}</p>
{% else %}
{{ actu.body|safe|truncatewords_html:15 }}
{% endif %}
<a href="{% pageurl actu %}">Lire plus &gt;</a>
</div>
</article>
{% endfor %}
{% if actus.has_previous %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">Actualités plus récentes</a>
{% endif %}
{% if actus.has_next %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">Actualités plus anciennes</a>
{% endif %}
</section>
{% endblock %}

View file

@ -0,0 +1,17 @@
{% extends "cofcms/base.html" %}
{% load wagtailimages_tags cofcms_tags i18n %}
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<p class="date">A lieu {{ page|dates }}</p>
<p>{{ page.chapo }}</p>
</section>
<section class="pagecontent">
<div class="image">{% image page.image width-700 %}</div>
<article>
{{ page.body|safe }}
</article>
</section>
{% endblock %}

View file

@ -0,0 +1,48 @@
{% extends "cofcms/base_aside.html" %}
{% load wagtailimages_tags cofcms_tags static %}
{% block extra_head %}
{{ block.super }}
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "cofcms/js/script.js" %}"></script>
{% endblock %}
{% block aside_title %}Accès rapide{% endblock %}
{% block aside %}
<ul>
{% for entry in page.entries %}
<li><a href="#{{ entry.slug }}">{{ entry.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<div>{{ page.introduction|safe }}</div>
</section>
<section class="directory">
{% for entry in page.entries %}
<article class="entry" id="{{ entry.slug }}">
{% if entry.image %}
<div class="entry-image">{% image entry.image width-150 class="entry-img" %}</div>
{% endif %}
<h2>{{ entry.title }}</h2>
<div class="desc">{{ entry.body|safe }}</div>
{% if entry.links %}
<ul class="links">
{% for block in entry.links %}
<li>
{% if block.block_type == "lien" %}
<a href="{{ block.value.url }}">{{ block.value.texte }}</a>
{% else %}
{{ block.value.texte }} : <button data-mref="{{ block.value.email|obfuscate_mail }}" class="facteur">Afficher l'adresse mail</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</article>
{% endfor %}
</section>
{% endblock %}

View file

@ -0,0 +1,29 @@
{% extends "cofcms/base.html" %}
{% load wagtailimages_tags cofcms_tags %}
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<div>{{ page.introduction|safe }}</div>
</section>
<section class="pagecontent">
{% for block in page.body %}
{% if block.block_type == "heading" %}
<h2>{{ block.value }}</h2>
{% elif block.block_type == "paragraph" %}
<article class="paragraph">
{{ block.value|safe }}
</article>
{% elif block.block_type == "image" %}
<div class="image">
{% image block.value width-800 %}
</div>
{% elif block.block_type == "iframe" %}
<article class="paragraph">
<iframe src="{{ block.value.url }}" width="100%" height="{{ block.value.height }}px"></iframe>
</article>
{% endif %}
{% endfor %}
</section>
{% endblock %}

View file

@ -0,0 +1,41 @@
{% extends "cofcms/base_aside.html" %}
{% load static cofcms_tags wagtailimages_tags wagtailroutablepage_tags i18n wagtailcore_tags %}
{% block extra_head %}
{{ block.super }}
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "cofcms/js/calendar.js" %}"></script>
{% endblock %}
{% block aside_title %}Agenda{% endblock %}
{% block aside %}
<div id="calendar-wrap">
{% calendar %}
</div>
{% endblock %}
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<div>{{ page.introduction|safe }}</div>
</section>
<section class="actuhome">
{% for actu in page.actus %}
<article class="actu">
<div class="actu-header" {% if actu.image %}{% image actu.image fill-400x200 as img %}style="background-image:url('{{ img.url }}');"{% endif %}>
<h2><a href="{% pageurl actu %}">{{ actu.title }}</a></h2>
</div>
<div class="actu-misc">
{% if actu.is_event %}
<span class="actu-minical">{% mini_calendar actu %}</span><span class="actu-dates">{{ actu|dates }}</span>
{% else %}
{{ actu.body|safe|truncatewords_html:10 }}
{% endif %}
</div>
<a href="{% pageurl actu %}" class="actu-overlay"></a>
</article>
{% endfor %}
</section>
{% endblock %}

View file

@ -0,0 +1,11 @@
<table class="calendar mini">
<tbody>
<tr>
{% for day in days %}
<td class="{{ day.hasevent|yesno:"hasevent ," }}{{ day.today|yesno:"today," }}">
{{ day.day }}
</td>
{% endfor %}
</tr>
</tbody>
</table>

View file

@ -0,0 +1,26 @@
{% extends "cofcms/base.html" %}
{% load i18n %}
{% block content %}
<section class="intro">
<h1>{% trans "Listes mail" %}</h1>
</section>
<section class="pagecontent">
<article class="paragraph">
{% blocktrans %}
Tous les abonnements aux listes de diffusion de mail à l'ENS se gèrent sur le serveur de mail SYMPA
Pour y accéder : Merci de répondre à cette question anti-robots.
{% endblocktrans %}
</article>
<article class="paragraph">
<form method="POST" action="">
{% csrf_token %}
{% if erreur %}<p class="erreur">{% trans erreur %}</p>{% endif %}
<p>{% blocktrans %}Comment s'appellent les poissons du bassin ?{% endblocktrans %}</p>
<input type="text" name="bassin" />
<input type="submit" />
</article>
</section>
{% endblock %}

View file

View file

@ -0,0 +1,161 @@
from datetime import date, timedelta
from django import template
from django.utils import formats, timezone
from django.utils.translation import ugettext as _
from ..models import COFActuPage, COFUtilPage
register = template.Library()
@register.filter()
def obfuscate_mail(value):
val = value.replace("", "-").replace("@", "arbre").replace(".", "pont")[1:]
return val
@register.inclusion_tag("cofcms/calendar.html", takes_context=True)
def calendar(context, month=None, year=None):
now = timezone.now()
if month is None:
month_start = date(now.year, now.month, 1)
else:
month_start = date(year, month, 1)
next_month = month_start + timedelta(days=32)
next_month = date(next_month.year, next_month.month, 1)
prev_month = month_start - timedelta(days=2)
month_prestart = month_start - timedelta(days=month_start.weekday())
month_postend = next_month + timedelta(days=(next_month.weekday() + 6) % 7)
events = (
COFActuPage.objects.live()
.filter(date_start__range=[month_prestart, month_postend], is_event=True)
.order_by("-date_start")
)
events = list(events)
weeks = []
curday = month_prestart
deltaday = timedelta(days=1)
while curday < next_month and len(weeks) < 10:
week = []
for k in range(7):
curevents = []
for k in range(len(events) - 1, -1, -1):
e = events[k]
if e.date_start.date() > curday:
break
if (e.date_start if e.date_end is None else e.date_end).date() < curday:
del events[k]
else:
curevents.append(e)
day = {
"day": curday.day,
"date": curday,
"class": (
("today " if curday == now.date() else "")
+ (
"in "
if (
curday.month == month_start.month
and curday.year == month_start.year
)
else "out "
)
+ ("hasevent" if len(curevents) > 0 else "")
),
"events": curevents,
}
week.append(day)
curday += deltaday
weeks.append(week)
# Calendar next/prev urls
try:
utilpage = COFUtilPage.objects.live()[0]
except COFUtilPage.DoesNotExist:
utilpage = None
request = context["request"]
burl = utilpage.debugged_get_url(request) + "/"
prev_url = burl + utilpage.reverse_subpage(
"calendar", args=[str(prev_month.year), str(prev_month.month)]
)
next_url = burl + utilpage.reverse_subpage(
"calendar", args=[str(next_month.year), str(next_month.month)]
)
context.push(
{
"events": events,
"weeks": weeks,
"this_month": month_start,
"prev_month": prev_url,
"next_month": next_url,
}
)
return context
@register.inclusion_tag("cofcms/mini_calendar.html")
def mini_calendar(event):
days = []
today = timezone.now().date()
date_start = event.date_start.date()
date_end = event.date_end.date() if event.date_end else date_start
week_start = date_start - timedelta(days=date_start.weekday())
curday = week_start
for i in range(7):
days.append(
{
"day": curday.day,
"hasevent": curday >= date_start and curday <= date_end,
"today": curday == today,
}
)
curday += timedelta(days=1)
return {"days": days}
@register.filter()
def dates(event):
def factorize_suffix(a, b):
i = -1
imin = -min(len(a), len(b))
while i > imin and a[i] == b[i]:
i -= 1
if i == -1:
return (a, b, "")
else:
return (a[: i + 1], b[: i + 1], a[i + 1 :])
datestart_string = formats.date_format(event.date_start)
timestart_string = formats.time_format(event.date_start)
if event.date_end:
if event.date_end.date() == event.date_start.date():
if event.all_day:
return _("le %s") % datestart_string
else:
return _("le %s de %s à %s") % (
datestart_string,
timestart_string,
formats.time_format(event.date_end),
)
else:
dateend_string = formats.date_format(event.date_end)
diffstart, diffend, common = factorize_suffix(
datestart_string, dateend_string
)
if event.all_day:
return _("du %s au %s%s") % (diffstart, diffend, common)
else:
return _("du %s%s à %s au %s à %s") % (
diffstart,
common,
timestart_string,
diffend,
formats.time_format(event.date_end),
)
else:
if event.all_day:
return _("le %s") % datestart_string
else:
return _("le %s à %s") % (datestart_string, timestart_string)

View file

@ -0,0 +1,41 @@
from modeltranslation.decorators import register
from wagtail_modeltranslation.translator import WagtailTranslationOptions
from .models import (
COFActuIndexPage,
COFActuPage,
COFDirectoryEntryPage,
COFDirectoryPage,
COFPage,
COFRootPage,
)
@register(COFRootPage)
class COFRootPageTr(WagtailTranslationOptions):
fields = ("introduction",)
@register(COFPage)
class COFPageTr(WagtailTranslationOptions):
fields = ("body",)
@register(COFActuIndexPage)
class COFActuIndexPageTr(WagtailTranslationOptions):
fields = ()
@register(COFActuPage)
class COFActuPageTr(WagtailTranslationOptions):
fields = ("chapo", "body")
@register(COFDirectoryPage)
class COFDirectoryPageTr(WagtailTranslationOptions):
fields = ("introduction",)
@register(COFDirectoryEntryPage)
class COFDirectoryEntryPageTr(WagtailTranslationOptions):
fields = ("body", "links")

0
gestioncof/cms/urls.py Normal file
View file

5
gestioncof/cms/views.py Normal file
View file

@ -0,0 +1,5 @@
from django.shortcuts import render
def raw_calendar_view(request, year, month):
return render(request, "cofcms/calendar_raw.html", {"month": month, "year": year})

View file

@ -20,8 +20,9 @@ git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_customma
ldap3 ldap3
channels==1.1.5 channels==1.1.5
python-dateutil python-dateutil
wagtail==1.10.* wagtail==1.11.*
wagtailmenus==2.2.* wagtailmenus==2.2.*
wagtail-modeltranslation==0.6.0rc2
django-cors-headers==2.2.0 django-cors-headers==2.2.0
# Production tools # Production tools