diff --git a/.gitignore b/.gitignore index 825eed63..347d4b78 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ venv/ /src media/ *.log +.sass-cache/ *.sqlite3 .coverage diff --git a/cof/locale/en/__init__.py b/cof/locale/en/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cof/locale/en/formats.py b/cof/locale/en/formats.py new file mode 100644 index 00000000..abd616db --- /dev/null +++ b/cof/locale/en/formats.py @@ -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" diff --git a/cof/locale/fr/formats.py b/cof/locale/fr/formats.py index 3120d5ce..6fd5b5ba 100644 --- a/cof/locale/fr/formats.py +++ b/cof/locale/fr/formats.py @@ -2,4 +2,6 @@ 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" diff --git a/cof/settings/common.py b/cof/settings/common.py index 50622f72..003cd6ce 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -90,14 +90,17 @@ INSTALLED_APPS = [ "wagtail.wagtailadmin", "wagtail.wagtailcore", "wagtail.contrib.modeladmin", + "wagtail.contrib.wagtailroutablepage", "wagtailmenus", + "wagtail_modeltranslation", "modelcluster", "taggit", "kfet.auth", "kfet.cms", - "corsheaders", + "gestioncof.cms", ] + MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", @@ -112,6 +115,7 @@ MIDDLEWARE = [ "djconfig.middleware.DjConfigMiddleware", "wagtail.wagtailcore.middleware.SiteMiddleware", "wagtail.wagtailredirects.middleware.RedirectMiddleware", + "django.middleware.locale.LocaleMiddleware", ] ROOT_URLCONF = "cof.urls" @@ -164,6 +168,8 @@ USE_L10N = True USE_TZ = True +LANGUAGES = (("fr", "Français"), ("en", "English")) + # Various additional settings SITE_ID = 1 diff --git a/cof/urls.py b/cof/urls.py index c952cd98..19a0581f 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -4,6 +4,7 @@ Fichier principal de configuration des urls du projet GestioCOF from django.conf import settings from django.conf.urls import include, url +from django.conf.urls.i18n import i18n_patterns from django.conf.urls.static import static from django.contrib import admin 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) # Wagtail for uncatched -urlpatterns += [url(r"", include(wagtail_urls))] +urlpatterns += i18n_patterns( + url(r"", include(wagtail_urls)), prefix_default_language=False +) diff --git a/gestioncof/cms/__init__.py b/gestioncof/cms/__init__.py new file mode 100644 index 00000000..043b644d --- /dev/null +++ b/gestioncof/cms/__init__.py @@ -0,0 +1 @@ +default_app_config = "gestioncof.cms.apps.COFCMSAppConfig" diff --git a/gestioncof/cms/apps.py b/gestioncof/cms/apps.py new file mode 100644 index 00000000..3cd041cc --- /dev/null +++ b/gestioncof/cms/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class COFCMSAppConfig(AppConfig): + name = "gestioncof.cms" + label = "cofcms" + verbose_name = "CMS COF" diff --git a/gestioncof/cms/fixtures/cofcms.json b/gestioncof/cms/fixtures/cofcms.json new file mode 100644 index 00000000..5517b4f7 --- /dev/null +++ b/gestioncof/cms/fixtures/cofcms.json @@ -0,0 +1,1193 @@ +[ +{ + "model": "wagtailcore.page", + "pk": 11, + "fields": { + "path": "000100010002", + "depth": 3, + "numchild": 6, + "title": "Site du COF", + "slug": "site", + "content_type": [ + "cofcms", + "cofrootpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/", + "owner": [ + "root" + ], + "seo_title": "Accueil", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T18:43:08.377Z", + "last_published_at": "2018-01-28T21:08:40.416Z", + "latest_revision_created_at": "2018-01-28T21:08:38.791Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 12, + "fields": { + "path": "0001000100020001", + "depth": 4, + "numchild": 3, + "title": "Actualit\u00e9s", + "slug": "actualites", + "content_type": [ + "cofcms", + "cofactuindexpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/actualites/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T18:45:07.969Z", + "last_published_at": "2018-01-22T18:45:07.752Z", + "latest_revision_created_at": "2018-01-22T18:45:07.752Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 13, + "fields": { + "path": "0001000100020002", + "depth": 4, + "numchild": 0, + "title": "Pr\u00e9sentation", + "slug": "pr\u00e9sentation", + "content_type": [ + "cofcms", + "cofpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/pr\u00e9sentation/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T18:47:15.337Z", + "last_published_at": "2018-01-22T20:10:37.728Z", + "latest_revision_created_at": "2018-01-22T20:10:37.728Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 14, + "fields": { + "path": "0001000100020003", + "depth": 4, + "numchild": 2, + "title": "Clubs", + "slug": "clubs", + "content_type": [ + "cofcms", + "cofdirectorypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/clubs/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T18:58:18.232Z", + "last_published_at": "2018-01-22T19:02:50.157Z", + "latest_revision_created_at": "2018-01-22T19:02:50.157Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 15, + "fields": { + "path": "0001000100020004", + "depth": 4, + "numchild": 3, + "title": "Partenaires", + "slug": "partenaires", + "content_type": [ + "cofcms", + "cofdirectorypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/partenaires/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T18:59:44.708Z", + "last_published_at": "2018-01-28T16:19:18.663Z", + "latest_revision_created_at": "2018-01-28T16:19:18.663Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 16, + "fields": { + "path": "0001000100020005", + "depth": 4, + "numchild": 1, + "title": "Cours Particuliers", + "slug": "cours-particuliers", + "content_type": [ + "cofcms", + "cofpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/cours-particuliers/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": true, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T19:00:35.984Z", + "last_published_at": "2018-01-22T19:02:23.524Z", + "latest_revision_created_at": "2018-01-22T19:02:23.524Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 17, + "fields": { + "path": "00010001000200010001", + "depth": 5, + "numchild": 0, + "title": "Singin' in the R'ENS", + "slug": "singin-in-the-rens", + "content_type": [ + "cofcms", + "cofactupage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/actualites/singin-in-the-rens/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T19:14:34.348Z", + "last_published_at": "2018-01-22T19:14:34.060Z", + "latest_revision_created_at": "2018-01-22T19:14:34.060Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 18, + "fields": { + "path": "00010001000200010002", + "depth": 5, + "numchild": 0, + "title": "Le Retour du Bur\u00f4", + "slug": "le-retour-du-bur\u00f4", + "content_type": [ + "cofcms", + "cofactupage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/actualites/le-retour-du-bur\u00f4/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T19:17:07.870Z", + "last_published_at": "2018-01-22T19:17:07.603Z", + "latest_revision_created_at": "2018-01-22T19:17:07.603Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 19, + "fields": { + "path": "00010001000200010003", + "depth": 5, + "numchild": 0, + "title": "\u00c9lection du Bur\u00f4 2018", + "slug": "\u00e9lection-du-bur\u00f4-2018", + "content_type": [ + "cofcms", + "cofactupage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/actualites/\u00e9lection-du-bur\u00f4-2018/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T19:22:34.232Z", + "last_published_at": "2018-01-22T19:22:33.946Z", + "latest_revision_created_at": "2018-01-22T19:22:33.946Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 20, + "fields": { + "path": "00010001000200030001", + "depth": 5, + "numchild": 0, + "title": "Arts Plastiques", + "slug": "arts-plastiques", + "content_type": [ + "cofcms", + "cofdirectoryentrypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/clubs/arts-plastiques/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T20:12:40.652Z", + "last_published_at": "2018-01-22T20:12:40.395Z", + "latest_revision_created_at": "2018-01-22T20:12:40.395Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 21, + "fields": { + "path": "00010001000200030002", + "depth": 5, + "numchild": 0, + "title": "B\u00e9d\u00e9th\u00e8que", + "slug": "b\u00e9d\u00e9th\u00e8que", + "content_type": [ + "cofcms", + "cofdirectoryentrypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/clubs/b\u00e9d\u00e9th\u00e8que/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T20:14:00.475Z", + "last_published_at": "2018-01-22T20:14:00.222Z", + "latest_revision_created_at": "2018-01-22T20:14:00.222Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 22, + "fields": { + "path": "00010001000200040001", + "depth": 5, + "numchild": 0, + "title": "MGEN", + "slug": "mgen", + "content_type": [ + "cofcms", + "cofdirectoryentrypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/partenaires/mgen/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T20:20:46.919Z", + "last_published_at": "2018-01-22T20:20:46.667Z", + "latest_revision_created_at": "2018-01-22T20:20:46.667Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 23, + "fields": { + "path": "00010001000200040002", + "depth": 5, + "numchild": 0, + "title": "Soci\u00e9t\u00e9 G\u00e9n\u00e9rale", + "slug": "soci\u00e9t\u00e9-g\u00e9n\u00e9rale", + "content_type": [ + "cofcms", + "cofdirectoryentrypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/partenaires/soci\u00e9t\u00e9-g\u00e9n\u00e9rale/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-22T20:21:19.043Z", + "last_published_at": "2018-01-22T20:21:18.752Z", + "latest_revision_created_at": "2018-01-22T20:21:18.752Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 24, + "fields": { + "path": "00010001000200040003", + "depth": 5, + "numchild": 0, + "title": "MAIF", + "slug": "maif", + "content_type": [ + "cofcms", + "cofdirectoryentrypage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/partenaires/maif/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-28T16:20:33.653Z", + "last_published_at": "2018-01-28T16:20:33.392Z", + "latest_revision_created_at": "2018-01-28T16:20:33.392Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 25, + "fields": { + "path": "0001000100020006", + "depth": 4, + "numchild": 0, + "title": "Ne pas supprimer", + "slug": "utils", + "content_type": [ + "cofcms", + "cofutilpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-01-28T21:16:04.989Z", + "last_published_at": "2018-01-28T21:16:19.180Z", + "latest_revision_created_at": "2018-01-28T21:16:18.887Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.page", + "pk": 26, + "fields": { + "path": "00010001000200050001", + "depth": 5, + "numchild": 0, + "title": "Demande de petit cours", + "slug": "demande-de-petit-cours", + "content_type": [ + "cofcms", + "cofpage" + ], + "live": true, + "has_unpublished_changes": false, + "url_path": "/global/site/cours-particuliers/demande-de-petit-cours/", + "owner": [ + "root" + ], + "seo_title": "", + "show_in_menus": false, + "search_description": "", + "go_live_at": null, + "expire_at": null, + "expired": false, + "locked": false, + "first_published_at": "2018-03-21T19:54:20.527Z", + "last_published_at": "2018-03-21T19:54:20.527Z", + "latest_revision_created_at": "2018-03-21T19:54:20.302Z", + "live_revision": null + } +}, +{ + "model": "wagtailcore.collection", + "pk": 3, + "fields": { + "path": "00010002", + "depth": 2, + "numchild": 0, + "name": "COF" + } +}, +{ + "model": "wagtailimages.image", + "pk": 33, + "fields": { + "collection": 3, + "title": "COF-17", + "file": "original_images/cof-768x576.jpg", + "width": 768, + "height": 576, + "created_at": "2018-01-22T18:49:25.647Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": 132330 + } +}, +{ + "model": "wagtailimages.image", + "pk": 34, + "fields": { + "collection": 3, + "title": "Singin in the RENS", + "file": "original_images/singin.jpg", + "width": 682, + "height": 361, + "created_at": "2018-01-22T19:13:49.753Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailimages.image", + "pk": 35, + "fields": { + "collection": 3, + "title": "Retour du Bur\u00f4", + "file": "original_images/retour.jpg", + "width": 614, + "height": 211, + "created_at": "2018-01-22T19:16:25.375Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailimages.image", + "pk": 36, + "fields": { + "collection": 3, + "title": "elections 18", + "file": "original_images/elections.png", + "width": 850, + "height": 406, + "created_at": "2018-01-22T19:21:31.954Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailimages.image", + "pk": 37, + "fields": { + "collection": 3, + "title": "Arts Plastiques", + "file": "original_images/ArtsPla.png", + "width": 150, + "height": 150, + "created_at": "2018-01-22T20:11:56.461Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailimages.image", + "pk": 38, + "fields": { + "collection": 3, + "title": "MGEN", + "file": "original_images/MGEN.jpg", + "width": 300, + "height": 204, + "created_at": "2018-01-22T20:20:41.712Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailimages.image", + "pk": 39, + "fields": { + "collection": 3, + "title": "MAIF", + "file": "original_images/Logo-MAIF.gif", + "width": 300, + "height": 290, + "created_at": "2018-01-28T16:20:13.828Z", + "uploaded_by_user": [ + "root" + ], + "focal_point_x": null, + "focal_point_y": null, + "focal_point_width": null, + "focal_point_height": null, + "file_size": null + } +}, +{ + "model": "wagtailmenus.mainmenu", + "pk": 1, + "fields": { + "site": [ + "localhost", + 8000 + ], + "max_levels": 2, + "use_specific": 1 + } +}, +{ + "model": "wagtailmenus.flatmenu", + "pk": 2, + "fields": { + "site": [ + "localhost", + 8000 + ], + "title": "COF - liens externes", + "handle": "cof-nav-ext", + "heading": "", + "max_levels": 1, + "use_specific": 1 + } +}, +{ + "model": "wagtailmenus.flatmenu", + "pk": 3, + "fields": { + "site": [ + "localhost", + 8000 + ], + "title": "COF - liens internes", + "handle": "cof-nav-int", + "heading": "", + "max_levels": 1, + "use_specific": 1 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 7, + "fields": { + "sort_order": 0, + "link_page": null, + "link_url": "https://www.cof.ens.fr/bda/", + "link_text": "BdA", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 8, + "fields": { + "sort_order": 1, + "link_page": null, + "link_url": "https://www.cof.ens.fr/bds/", + "link_text": "BdS", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 9, + "fields": { + "sort_order": 2, + "link_page": null, + "link_url": "https://www.cof.ens.fr/gestion", + "link_text": "GestioCOF", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 10, + "fields": { + "sort_order": 3, + "link_page": null, + "link_url": "https://www.cof.ens.fr/bocal", + "link_text": "Le BOcal", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 11, + "fields": { + "sort_order": 4, + "link_page": null, + "link_url": "https://photos.cof.ens.fr/", + "link_text": "Serveur photos", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 12, + "fields": { + "sort_order": 5, + "link_page": null, + "link_url": "https://www.eleves.ens.fr", + "link_text": "Services élèves ENS", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 2 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 13, + "fields": { + "sort_order": 0, + "link_page": 13, + "link_url": null, + "link_text": "", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 3 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 14, + "fields": { + "sort_order": 1, + "link_page": 12, + "link_url": null, + "link_text": "", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 3 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 15, + "fields": { + "sort_order": 2, + "link_page": 14, + "link_url": null, + "link_text": "", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 3 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 16, + "fields": { + "sort_order": 3, + "link_page": 15, + "link_url": null, + "link_text": "", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 3 + } +}, +{ + "model": "wagtailmenus.flatmenuitem", + "pk": 17, + "fields": { + "sort_order": 4, + "link_page": 16, + "link_url": null, + "link_text": "", + "handle": "", + "url_append": "", + "allow_subnav": false, + "menu": 3 + } +}, +{ + "model": "cofcms.cofrootpage", + "pk": 11, + "fields": { + "title_fr": "Site du COF", + "title_en": "COF's website", + "slug_fr": "site", + "slug_en": null, + "url_path_fr": "/global/site/", + "url_path_en": "/global/site/", + "seo_title_fr": "Accueil", + "seo_title_en": "Home", + "search_description_fr": "", + "search_description_en": "", + "introduction": "

Bienvenue sur le site du COF

", + "introduction_fr": "

Bienvenue sur le site du COF

", + "introduction_en": "

Welcome to the COF's website

" + } +}, +{ + "model": "cofcms.cofpage", + "pk": 13, + "fields": { + "title_fr": "Pr\u00e9sentation", + "title_en": "Presentation", + "slug_fr": "pr\u00e9sentation", + "slug_en": "presentation", + "url_path_fr": "/global/site/pr\u00e9sentation/", + "url_path_en": "/global/site/presentation/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "[{\"id\": \"344a0786-f540-4d77-bbf5-59ab96bb529b\", \"value\": \"Quoi ?\", \"type\": \"heading\"}, {\"id\": \"6f46dd11-a7a8-4491-9b98-7adc56a75e42\", \"value\": \"

Le COF (Comit\\u00e9 d\\u2019Organisation des F\\u00eates), c\\u2019est le petit nom de \\nl\\u2019AEENS, l\\u2019Association des \\u00c9l\\u00e8ves de l\\u2019ENS (association de loi 1901). \\nC\\u2019est lui qui organise les\\u00a0\\u00e9v\\u00e8nements\\u00a0culturels, associatifs et bien s\\u00fbr\\n festifs, de l\\u2019\\u00c9cole normale.

\\n

Ses principales responsabilit\\u00e9s sont entre autres :

\\n\\n

Il est bien s\\u00fbr tr\\u00e8s li\\u00e9 au BDS (Bureau des Sports) avec qui il pr\\u00e9pare les InterENS sportives, mais qui est\\u00a0n\\u00e9anmoins\\u00a0une entit\\u00e9 distincte du COF.

\", \"type\": \"paragraph\"}, {\"id\": \"c02ba930-48ab-4f1f-8e3a-e8edeed1346d\", \"value\": \"Qui ?\", \"type\": \"heading\"}, {\"id\": \"6a1db5e4-06b3-44ae-bef1-2be9b049dc35\", \"value\": \"

Le COF c\\u2019est avant tout ses membres (environ 700 chaque ann\\u00e9e) et ses\\n clubs (entre 20 et 40 selon les ann\\u00e9es). Chaque club est g\\u00e9r\\u00e9 par un \\nresponsable (voir les pages des clubs).

\\n

Comme dans toute association il y a un bureau \\u2013 compos\\u00e9 de 12 personnes r\\u00e9\\u00e9lues tous les 6 mois.

\\n

Le COF organise au moins 3 Assembl\\u00e9es G\\u00e9n\\u00e9rales par an, une en \\noctobre pour attribuer les budgets annuels, une en f\\u00e9vrier pour \\nr\\u00e9ajuster les budgets, discuter des projets, des affaires courantes ; et\\n la derni\\u00e8re en juin pour faire un bilan de l\\u2019ann\\u00e9e, voter les \\ncotisations et les partenariats. C\\u2019est l\\u2019occasion pour tous les membres \\nde se rassembler et de faire entendre leur voix, pour les clubs de se \\npr\\u00e9senter et pour le Bur\\u00f4\\u2026 et de vous rendre des comptes ! Il y en a \\naussi une avant chaque \\u00e9lection afin d\\u2019\\u00e9couter la pr\\u00e9sentation des \\ncandidats au Bur\\u00f4.

\", \"type\": \"paragraph\"}, {\"id\": \"224a0c75-eb3c-4088-9091-cb1178e6f550\", \"value\": 33, \"type\": \"image\"}, {\"id\": \"0213e74b-321a-4357-a5f5-47aca37df908\", \"value\": \"Poste / Nom\\n\\n\\n\\n\\n\\t
Pr\\u00e9sident : Valentin Cocco
Vice-pr\\u00e9sident : Th\\u00e9o Mathevet
Tr\\u00e9sorier : Mathias Penot\\n\\n\\n\\t
Sous-tr\\u00e9sorier : Octave Tessiot
Secr\\u00e9taire : L\\u00e9na Gurriaran
Charg\\u00e9 de comm' : Cl\\u00e9ment de Mecquenem
Charg\\u00e9 de comm' adjoint : Charles Giroudot
Pr\\u00e9sidente du Bureau des Arts : Caroline Delattre
Bureau des Arts : Bryan Rimbault
Bureau des Arts : Philippe Danr\\u00e9
Bureau des Arts : Louise Garrigou
Bureau des Arts : Emile Laymand

Bureau des Arts : Cl\\u00e9mence Elmira

\", \"type\": \"paragraph\"}, {\"id\": \"7c37c61e-cff5-4b6b-9b5f-8c54120a9c75\", \"value\": \"O\\u00f9 ?\", \"type\": \"heading\"}, {\"id\": \"61a65072-1eb2-4f99-bad1-045c03594318\", \"value\": \"

Le COF dispose d\\u2019un local dans l\\u2019\\u00e9cole, au 45 rue d\\u2019Ulm. Il suffit de\\n traverser la cour aux Ernest puis de tourner tout de suite \\u00e0 gauche.

\", \"type\": \"paragraph\"}, {\"id\": \"3d399310-d415-47be-b9c6-7b01a4a3ffd3\", \"value\": \"Quand ?\", \"type\": \"heading\"}, {\"id\": \"c7bdee8c-6833-47a2-b4f0-ac9a21c6cf90\", \"value\": \"

Le COF assure deux permanences tous les jours (sauf samedi et dimanche) : une de 12h \\u00e0 14h, et une de 18h \\u00e0 20h.

\", \"type\": \"paragraph\"}, {\"id\": \"53358653-c518-4120-925a-5e314f064cf2\", \"value\": \"Des questions ?\", \"type\": \"heading\"}, {\"id\": \"6e6ac1b2-9eaf-44cd-a6f0-1c497148ee84\", \"value\": \"

Vous pouvez nous contacter facilement !

\\n\", \"type\": \"paragraph\"}]", + "body_fr": "[{\"id\": \"344a0786-f540-4d77-bbf5-59ab96bb529b\", \"value\": \"Quoi ?\", \"type\": \"heading\"}, {\"id\": \"6f46dd11-a7a8-4491-9b98-7adc56a75e42\", \"value\": \"

Le COF (Comit\\u00e9 d\\u2019Organisation des F\\u00eates), c\\u2019est le petit nom de \\nl\\u2019AEENS, l\\u2019Association des \\u00c9l\\u00e8ves de l\\u2019ENS (association de loi 1901). \\nC\\u2019est lui qui organise les\\u00a0\\u00e9v\\u00e8nements\\u00a0culturels, associatifs et bien s\\u00fbr\\n festifs, de l\\u2019\\u00c9cole normale.

\\n

Ses principales responsabilit\\u00e9s sont entre autres :

\\n\\n

Il est bien s\\u00fbr tr\\u00e8s li\\u00e9 au BDS (Bureau des Sports) avec qui il pr\\u00e9pare les InterENS sportives, mais qui est\\u00a0n\\u00e9anmoins\\u00a0une entit\\u00e9 distincte du COF.

\", \"type\": \"paragraph\"}, {\"id\": \"c02ba930-48ab-4f1f-8e3a-e8edeed1346d\", \"value\": \"Qui ?\", \"type\": \"heading\"}, {\"id\": \"6a1db5e4-06b3-44ae-bef1-2be9b049dc35\", \"value\": \"

Le COF c\\u2019est avant tout ses membres (environ 700 chaque ann\\u00e9e) et ses\\n clubs (entre 20 et 40 selon les ann\\u00e9es). Chaque club est g\\u00e9r\\u00e9 par un \\nresponsable (voir les pages des clubs).

\\n

Comme dans toute association il y a un bureau \\u2013 compos\\u00e9 de 12 personnes r\\u00e9\\u00e9lues tous les 6 mois.

\\n

Le COF organise au moins 3 Assembl\\u00e9es G\\u00e9n\\u00e9rales par an, une en \\noctobre pour attribuer les budgets annuels, une en f\\u00e9vrier pour \\nr\\u00e9ajuster les budgets, discuter des projets, des affaires courantes ; et\\n la derni\\u00e8re en juin pour faire un bilan de l\\u2019ann\\u00e9e, voter les \\ncotisations et les partenariats. C\\u2019est l\\u2019occasion pour tous les membres \\nde se rassembler et de faire entendre leur voix, pour les clubs de se \\npr\\u00e9senter et pour le Bur\\u00f4\\u2026 et de vous rendre des comptes ! Il y en a \\naussi une avant chaque \\u00e9lection afin d\\u2019\\u00e9couter la pr\\u00e9sentation des \\ncandidats au Bur\\u00f4.

\", \"type\": \"paragraph\"}, {\"id\": \"224a0c75-eb3c-4088-9091-cb1178e6f550\", \"value\": 33, \"type\": \"image\"}, {\"id\": \"0213e74b-321a-4357-a5f5-47aca37df908\", \"value\": \"Poste / Nom\\n\\n\\n\\n\\n\\t
Pr\\u00e9sident : Valentin Cocco
Vice-pr\\u00e9sident : Th\\u00e9o Mathevet
Tr\\u00e9sorier : Mathias Penot\\n\\n\\n\\t
Sous-tr\\u00e9sorier : Octave Tessiot
Secr\\u00e9taire : L\\u00e9na Gurriaran
Charg\\u00e9 de comm' : Cl\\u00e9ment de Mecquenem
Charg\\u00e9 de comm' adjoint : Charles Giroudot
Pr\\u00e9sidente du Bureau des Arts : Caroline Delattre
Bureau des Arts : Bryan Rimbault
Bureau des Arts : Philippe Danr\\u00e9
Bureau des Arts : Louise Garrigou
Bureau des Arts : Emile Laymand

Bureau des Arts : Cl\\u00e9mence Elmira

\", \"type\": \"paragraph\"}, {\"id\": \"7c37c61e-cff5-4b6b-9b5f-8c54120a9c75\", \"value\": \"O\\u00f9 ?\", \"type\": \"heading\"}, {\"id\": \"61a65072-1eb2-4f99-bad1-045c03594318\", \"value\": \"

Le COF dispose d\\u2019un local dans l\\u2019\\u00e9cole, au 45 rue d\\u2019Ulm. Il suffit de\\n traverser la cour aux Ernest puis de tourner tout de suite \\u00e0 gauche.

\", \"type\": \"paragraph\"}, {\"id\": \"3d399310-d415-47be-b9c6-7b01a4a3ffd3\", \"value\": \"Quand ?\", \"type\": \"heading\"}, {\"id\": \"c7bdee8c-6833-47a2-b4f0-ac9a21c6cf90\", \"value\": \"

Le COF assure deux permanences tous les jours (sauf samedi et dimanche) : une de 12h \\u00e0 14h, et une de 18h \\u00e0 20h.

\", \"type\": \"paragraph\"}, {\"id\": \"53358653-c518-4120-925a-5e314f064cf2\", \"value\": \"Des questions ?\", \"type\": \"heading\"}, {\"id\": \"6e6ac1b2-9eaf-44cd-a6f0-1c497148ee84\", \"value\": \"

Vous pouvez nous contacter facilement !

\\n\", \"type\": \"paragraph\"}]", + "body_en": "[]" + } +}, +{ + "model": "cofcms.cofpage", + "pk": 16, + "fields": { + "title_fr": "Cours Particuliers", + "title_en": null, + "slug_fr": "cours-particuliers", + "slug_en": null, + "url_path_fr": "/global/site/cours-particuliers/", + "url_path_en": "/global/site/cours-particuliers/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "[{\"id\": \"dbf9f940-51a6-43d1-89ff-1bf0648cead8\", \"value\": \"

Les \\u00e9l\\u00e8ves de l'ENS peuvent donner des cours particuliers. Si vous \\n\\u00eates int\\u00e9ress\\u00e9 pour en prendre, merci de faire une demande de petits \\ncours sur cette page.

\\n \\n \\n\\t\\n\\t
\\n\\tSi vous \\u00eates \\u00e9l\\u00e8ve de l'\\u00e9cole, vous pouvez g\\u00e9rer vos petits cours sur GestioCOF.\", \"type\": \"paragraph\"}]", + "body_fr": "[{\"id\": \"dbf9f940-51a6-43d1-89ff-1bf0648cead8\", \"value\": \"

Les \\u00e9l\\u00e8ves de l'ENS peuvent donner des cours particuliers. Si vous \\n\\u00eates int\\u00e9ress\\u00e9 pour en prendre, merci de faire une demande de petits \\ncours sur cette page.

\\n \\n \\n\\t\\n\\t
\\n\\tSi vous \\u00eates \\u00e9l\\u00e8ve de l'\\u00e9cole, vous pouvez g\\u00e9rer vos petits cours sur GestioCOF.\", \"type\": \"paragraph\"}]", + "body_en": "[]" + } +}, +{ + "model": "cofcms.cofpage", + "pk": 26, + "fields": { + "title_fr": "Demande de petit cours", + "title_en": null, + "slug_fr": "demande-de-petit-cours", + "slug_en": null, + "url_path_fr": "/global/site/cours-particuliers/demande-de-petit-cours/", + "url_path_en": "/global/site/cours-particuliers/demande-de-petit-cours/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "[{\"value\": {\"url\": \"https://www.cof.ens.fr/gestion/petitcours/demande-raw\", \"height\": \"1050\"}, \"id\": \"397ff222-6c1b-4e5c-a971-a50621dd83b3\", \"type\": \"iframe\"}]", + "body_fr": "[{\"value\": {\"url\": \"https://www.cof.ens.fr/gestion/petitcours/demande-raw\", \"height\": \"1050\"}, \"id\": \"397ff222-6c1b-4e5c-a971-a50621dd83b3\", \"type\": \"iframe\"}]", + "body_en": "[]" + } +}, +{ + "model": "cofcms.cofactuindexpage", + "pk": 12, + "fields": { + "title_fr": "Actualit\u00e9s", + "title_en": "News", + "slug_fr": "actualites", + "slug_en": "news", + "url_path_fr": "/global/site/actualites/", + "url_path_en": "/global/site/news/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "" + } +}, +{ + "model": "cofcms.cofactupage", + "pk": 17, + "fields": { + "title_fr": "Singin' in the R'ENS", + "title_en": null, + "slug_fr": "singin-in-the-rens", + "slug_en": null, + "url_path_fr": "/global/site/actualites/singin-in-the-rens/", + "url_path_en": "/global/site/news/singin-in-the-rens/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "chapo": "Soir\u00e9e com\u00e9die musicale", + "chapo_fr": "Soir\u00e9e com\u00e9die musicale", + "chapo_en": "", + "body": "Je chante dans l'ENS
Je chante dans l'ENS
Cette glorieuse soir\u00e9e
Me rendra le sourire
Je tournoie sur la piste
Lumi\u00e8re noire au plafond
Vibrations dans mon coeur
Et j'suis pr\u00eat\u00b7e \u00e0 chanter
Que la foule endiabl\u00e9e
Chasse tous mes tracassins
Viens \u00e0 notre soir\u00e9e
On va bien s'amuser
Oui descends en K-F\u00eat
Avec le sourire aux l\u00e8vres
Et puis chante
Chante dans l'ENS !

\n Une ambiance de com\u00e9die musicale, de la danse, du chant, et beaucoup de\n bonne humeur : venez nombreux\u00b7ses jeudi 25 janvier pour notre soir\u00e9e \nSingin' in the R'ENS, qui aura lieu en K-F\u00eat d\u00e8s 23h !

", + "body_fr": "Je chante dans l'ENS
Je chante dans l'ENS
Cette glorieuse soir\u00e9e
Me rendra le sourire
Je tournoie sur la piste
Lumi\u00e8re noire au plafond
Vibrations dans mon coeur
Et j'suis pr\u00eat\u00b7e \u00e0 chanter
Que la foule endiabl\u00e9e
Chasse tous mes tracassins
Viens \u00e0 notre soir\u00e9e
On va bien s'amuser
Oui descends en K-F\u00eat
Avec le sourire aux l\u00e8vres
Et puis chante
Chante dans l'ENS !

\n Une ambiance de com\u00e9die musicale, de la danse, du chant, et beaucoup de\n bonne humeur : venez nombreux\u00b7ses jeudi 25 janvier pour notre soir\u00e9e \nSingin' in the R'ENS, qui aura lieu en K-F\u00eat d\u00e8s 23h !

", + "body_en": "", + "image": 34, + "is_event": true, + "date_start": "2018-01-25T21:00:00Z", + "date_end": null, + "all_day": false + } +}, +{ + "model": "cofcms.cofactupage", + "pk": 18, + "fields": { + "title_fr": "Le Retour du Bur\u00f4", + "title_en": null, + "slug_fr": "le-retour-du-bur\u00f4", + "slug_en": null, + "url_path_fr": "/global/site/actualites/le-retour-du-bur\u00f4/", + "url_path_en": "/global/site/news/le-retour-du-bur\u00f4/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "chapo": "Premi\u00e8re soir\u00e9e du nouveau COF", + "chapo_fr": "Premi\u00e8re soir\u00e9e du nouveau COF", + "chapo_en": "", + "body": "Le Retour du \nBur\u00f4, qu'est-ce que c'est donc ? La premi\u00e8re soir\u00e9e du nouveau COF pardi\n ! Le th\u00e8me ? Top : je suis une saga cin\u00e9matographique \u00e0 grand succ\u00e8s, \nje compte actuellement huit \u00e9pisodes (et demi) \u00e0 mon actif, j'ai fait \nr\u00eaver des g\u00e9n\u00e9rations enti\u00e8res depuis 1977, m\u00eame sans m'avoir vu vous me\n connaissez sans doute pour une c\u00e9l\u00e8bre r\u00e9plique, je suis, je suis... Je\n suis ton p\u00e8re ! Hum hum, je suis : Star Wars !
Au programme, bracelets-lasers, \u00e9toiles dans les yeux, et voyage musical interstellaire.

Rendez-vous jeudi 18 janvier en K-F\u00eat, \u00e0 partir de 22h ! Venez du COFt\u00e9 obscur, on a des cookies !

", + "body_fr": "Le Retour du \nBur\u00f4, qu'est-ce que c'est donc ? La premi\u00e8re soir\u00e9e du nouveau COF pardi\n ! Le th\u00e8me ? Top : je suis une saga cin\u00e9matographique \u00e0 grand succ\u00e8s, \nje compte actuellement huit \u00e9pisodes (et demi) \u00e0 mon actif, j'ai fait \nr\u00eaver des g\u00e9n\u00e9rations enti\u00e8res depuis 1977, m\u00eame sans m'avoir vu vous me\n connaissez sans doute pour une c\u00e9l\u00e8bre r\u00e9plique, je suis, je suis... Je\n suis ton p\u00e8re ! Hum hum, je suis : Star Wars !
Au programme, bracelets-lasers, \u00e9toiles dans les yeux, et voyage musical interstellaire.

Rendez-vous jeudi 18 janvier en K-F\u00eat, \u00e0 partir de 22h ! Venez du COFt\u00e9 obscur, on a des cookies !

", + "body_en": "", + "image": 35, + "is_event": true, + "date_start": "2018-01-18T21:00:00Z", + "date_end": null, + "all_day": false + } +}, +{ + "model": "cofcms.cofactupage", + "pk": 19, + "fields": { + "title_fr": "\u00c9lection du Bur\u00f4 2018", + "title_en": null, + "slug_fr": "\u00e9lection-du-bur\u00f4-2018", + "slug_en": null, + "url_path_fr": "/global/site/actualites/\u00e9lection-du-bur\u00f4-2018/", + "url_path_en": "/global/site/news/\u00e9lection-du-bur\u00f4-2018/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "chapo": "", + "chapo_fr": "", + "chapo_en": "", + "body": "Les campagnes battent leurs pleins rythm\u00e9es par de nombreux petits \nd\u00e9jeuners, soir\u00e9es et autres \u00e9v\u00e9nements organis\u00e9s par les diff\u00e9rentes \nlistes et ces deux semaines se finiront par l\u2019\u00e9lection du nouveau Bur\u00f4.\n

\u00a0

\n

\u00a0

\n

Passez donc en aquarium pour le premier tour des \u00e9lections du Bur\u00f4 du\n COF 2018 ! Si vous ne pouvez pas venir en personne, un vote \n\u00e9lectronique sera mis en place !

", + "body_fr": "Les campagnes battent leurs pleins rythm\u00e9es par de nombreux petits \nd\u00e9jeuners, soir\u00e9es et autres \u00e9v\u00e9nements organis\u00e9s par les diff\u00e9rentes \nlistes et ces deux semaines se finiront par l\u2019\u00e9lection du nouveau Bur\u00f4.\n

\u00a0

\n

\u00a0

\n

Passez donc en aquarium pour le premier tour des \u00e9lections du Bur\u00f4 du\n COF 2018 ! Si vous ne pouvez pas venir en personne, un vote \n\u00e9lectronique sera mis en place !

", + "body_en": "", + "image": 36, + "is_event": false, + "date_start": "2017-12-18T19:22:00Z", + "date_end": "2018-01-25T19:22:00Z", + "all_day": true + } +}, +{ + "model": "cofcms.cofdirectorypage", + "pk": 14, + "fields": { + "title_fr": "Clubs", + "title_en": null, + "slug_fr": "clubs", + "slug_en": null, + "url_path_fr": "/global/site/clubs/", + "url_path_en": "/global/site/clubs/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "introduction": "
\nVoici tous les clubs du COF !\n

La plupart de ces clubs ont des mailing lists, auxquelles il est souvent possible de s\u2019inscrire via le serveur mail sympa.

", + "introduction_fr": "
\nVoici tous les clubs du COF !\n

La plupart de ces clubs ont des mailing lists, auxquelles il est souvent possible de s\u2019inscrire via le serveur mail sympa.

", + "introduction_en": "", + "alphabetique": true + } +}, +{ + "model": "cofcms.cofdirectorypage", + "pk": 15, + "fields": { + "title_fr": "Partenaires", + "title_en": null, + "slug_fr": "partenaires", + "slug_en": null, + "url_path_fr": "/global/site/partenaires/", + "url_path_en": "/global/site/partenaires/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "introduction": "

Le COF a n\u00e9goci\u00e9 pour vous de nombreux partenariats ! Bien s\u00fbr, il faut \u00eatre membre du COF pour en b\u00e9n\u00e9ficier.

", + "introduction_fr": "

Le COF a n\u00e9goci\u00e9 pour vous de nombreux partenariats ! Bien s\u00fbr, il faut \u00eatre membre du COF pour en b\u00e9n\u00e9ficier.

", + "introduction_en": "", + "alphabetique": false + } +}, +{ + "model": "cofcms.cofdirectoryentrypage", + "pk": 20, + "fields": { + "title_fr": "Arts Plastiques", + "title_en": null, + "slug_fr": "arts-plastiques", + "slug_en": null, + "url_path_fr": "/global/site/clubs/arts-plastiques/", + "url_path_en": "/global/site/clubs/arts-plastiques/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "Le club Arts Plastiques te propose un lieu de rencontre entre \npersonnes int\u00e9ress\u00e9es par les arts plastiques, le dessin ou la peinture.
\nMais, que faisons-nous au club Arts Plastiques ? D\u2019abord, des s\u00e9ances \nd\u2019initiation; et puis des s\u00e9ances \u00e0 th\u00e8me, avec des intervenants; des \nprojets communs; des sorties croquis\u2026

\nQue tu n\u2019aies jamais touch\u00e9 \u00e0 un pinceau, ou que tu sois d\u00e9j\u00e0 un-e grand-e artiste, n\u2019h\u00e9site pas \u00e0 venir nous rejoindre !

", + "body_fr": "Le club Arts Plastiques te propose un lieu de rencontre entre \npersonnes int\u00e9ress\u00e9es par les arts plastiques, le dessin ou la peinture.
\nMais, que faisons-nous au club Arts Plastiques ? D\u2019abord, des s\u00e9ances \nd\u2019initiation; et puis des s\u00e9ances \u00e0 th\u00e8me, avec des intervenants; des \nprojets communs; des sorties croquis\u2026

\nQue tu n\u2019aies jamais touch\u00e9 \u00e0 un pinceau, ou que tu sois d\u00e9j\u00e0 un-e grand-e artiste, n\u2019h\u00e9site pas \u00e0 venir nous rejoindre !

", + "body_en": "", + "links": "[{\"id\": \"8988ae9e-7b34-4d76-957b-04892697ff98\", \"value\": {\"texte\": \"Mailing-liste\", \"email\": \"artsplastiques@ens.fr\"}, \"type\": \"contact\"}]", + "links_fr": "[{\"id\": \"8988ae9e-7b34-4d76-957b-04892697ff98\", \"value\": {\"texte\": \"Mailing-liste\", \"email\": \"artsplastiques@ens.fr\"}, \"type\": \"contact\"}]", + "links_en": "[]", + "image": 37 + } +}, +{ + "model": "cofcms.cofdirectoryentrypage", + "pk": 21, + "fields": { + "title_fr": "B\u00e9d\u00e9th\u00e8que", + "title_en": null, + "slug_fr": "b\u00e9d\u00e9th\u00e8que", + "slug_en": null, + "url_path_fr": "/global/site/clubs/b\u00e9d\u00e9th\u00e8que/", + "url_path_en": "/global/site/clubs/b\u00e9d\u00e9th\u00e8que/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "De Riad Sattouf \u00e0 Katsuhiro Otomo, en passant par Andr\u00e9 Franquin, \nJacques Tardi, Didier Tarquin et Georges Wolinski, la BDth\u00e8que poss\u00e8de \nune collection de quatre mille bandes dessin\u00e9es sur une cinquantaine \nd\u2019\u00e9tag\u00e8res, en constante croissance. Class\u00e9es par dessinateur et \ncatalogu\u00e9es, toutes ces oeuvres offrent un large panorama du XXe si\u00e8cle \net sont librement consultables sur place sans mod\u00e9ration ! \u00c0 cela \ns\u2019ajoutent des milliers de p\u00e9riodiques sp\u00e9cialis\u00e9s datant de l\u2019\u00e2ge d\u2019or \nde la BD franco-belge, un Enfer cach\u00e9, et quelques conseils de lecture \n\u00e9crits par des fans.

\nLe club organise ausis des \u00e9v\u00e9nements divers par exemple un s\u00e9minaire \nsur la bande dessin\u00e9e, qui ne demande qu\u2019\u00e0 \u00eatre relanc\u00e9. \u00c0 l\u2019ordre du \njour, la mise en place d\u2019une exp\u00e9dition \u00e0 Angoul\u00eame avec le BDA en \njanvier 2017 pourrait m\u00eame se faire avec ton aide. Tous les \ndons et suggestions d\u2019achats sont les bienvenus. Pour participer aux \nd\u00e9cisions d\u2019achats, \u00e9crire des suggesions de lecture dans le BOcal, \nchoisir les bandes dessin\u00e9es \u00e0 mettre en valeur, n\u2019h\u00e9site pas \u00e0 \nrejoindre le club!

", + "body_fr": "De Riad Sattouf \u00e0 Katsuhiro Otomo, en passant par Andr\u00e9 Franquin, \nJacques Tardi, Didier Tarquin et Georges Wolinski, la BDth\u00e8que poss\u00e8de \nune collection de quatre mille bandes dessin\u00e9es sur une cinquantaine \nd\u2019\u00e9tag\u00e8res, en constante croissance. Class\u00e9es par dessinateur et \ncatalogu\u00e9es, toutes ces oeuvres offrent un large panorama du XXe si\u00e8cle \net sont librement consultables sur place sans mod\u00e9ration ! \u00c0 cela \ns\u2019ajoutent des milliers de p\u00e9riodiques sp\u00e9cialis\u00e9s datant de l\u2019\u00e2ge d\u2019or \nde la BD franco-belge, un Enfer cach\u00e9, et quelques conseils de lecture \n\u00e9crits par des fans.

\nLe club organise ausis des \u00e9v\u00e9nements divers par exemple un s\u00e9minaire \nsur la bande dessin\u00e9e, qui ne demande qu\u2019\u00e0 \u00eatre relanc\u00e9. \u00c0 l\u2019ordre du \njour, la mise en place d\u2019une exp\u00e9dition \u00e0 Angoul\u00eame avec le BDA en \njanvier 2017 pourrait m\u00eame se faire avec ton aide. Tous les \ndons et suggestions d\u2019achats sont les bienvenus. Pour participer aux \nd\u00e9cisions d\u2019achats, \u00e9crire des suggesions de lecture dans le BOcal, \nchoisir les bandes dessin\u00e9es \u00e0 mettre en valeur, n\u2019h\u00e9site pas \u00e0 \nrejoindre le club!

", + "body_en": "", + "links": "[{\"id\": \"9708004f-5d09-4cef-a60a-31b63fe5f377\", \"value\": {\"texte\": \"Mailing-liste\", \"email\": \"bdtheque@ens.fr\"}, \"type\": \"contact\"}]", + "links_fr": "[{\"id\": \"9708004f-5d09-4cef-a60a-31b63fe5f377\", \"value\": {\"texte\": \"Mailing-liste\", \"email\": \"bdtheque@ens.fr\"}, \"type\": \"contact\"}]", + "links_en": "[]", + "image": null + } +}, +{ + "model": "cofcms.cofdirectoryentrypage", + "pk": 22, + "fields": { + "title_fr": "MGEN", + "title_en": null, + "slug_fr": "mgen", + "slug_en": null, + "url_path_fr": "/global/site/partenaires/mgen/", + "url_path_en": "/global/site/partenaires/mgen/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "

La MGEN est un des \nprincipaux partenaires du COF. Elle\u00a0participe au financement des \nprincipaux \u00e9v\u00e9nements (Jour le plus court, 48h des Arts) et \u00e0 \nl\u2019impression de la Plakette Alpha.

\n

Elle dispose \u00e9galement d\u2019un stand chaque ann\u00e9e au moment de la \nrentr\u00e9e, afin de proposer ses prestations aux pensionnaires de l\u2019Ecole.

", + "body_fr": "

La MGEN est un des \nprincipaux partenaires du COF. Elle\u00a0participe au financement des \nprincipaux \u00e9v\u00e9nements (Jour le plus court, 48h des Arts) et \u00e0 \nl\u2019impression de la Plakette Alpha.

\n

Elle dispose \u00e9galement d\u2019un stand chaque ann\u00e9e au moment de la \nrentr\u00e9e, afin de proposer ses prestations aux pensionnaires de l\u2019Ecole.

", + "body_en": "", + "links": "[{\"id\": \"031dc9b4-9ac6-411c-8131-a3021c4edd0c\", \"value\": {\"url\": \"https://www.mgen.fr/accueil/\", \"texte\": \"Site internet\"}, \"type\": \"lien\"}]", + "links_fr": "[{\"id\": \"031dc9b4-9ac6-411c-8131-a3021c4edd0c\", \"value\": {\"url\": \"https://www.mgen.fr/accueil/\", \"texte\": \"Site internet\"}, \"type\": \"lien\"}]", + "links_en": "[]", + "image": 38 + } +}, +{ + "model": "cofcms.cofdirectoryentrypage", + "pk": 23, + "fields": { + "title_fr": "Soci\u00e9t\u00e9 G\u00e9n\u00e9rale", + "title_en": null, + "slug_fr": "soci\u00e9t\u00e9-g\u00e9n\u00e9rale", + "slug_en": null, + "url_path_fr": "/global/site/partenaires/soci\u00e9t\u00e9-g\u00e9n\u00e9rale/", + "url_path_en": "/global/site/partenaires/soci\u00e9t\u00e9-g\u00e9n\u00e9rale/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "

Si vous ouvrez un compte \u00e0 la SoG\u00e9, ils vous versent 140\u20ac et versent \naussi une somme au bureau, nous permettant de financer vos clubs et \n\u00e9v\u00e8nements. Vous pouvez donc rembourser votre cotisation au COF (voire \nplus) rien qu\u2019en ouvrant un compte !

\n

Vous devez ouvrir ce compte lors des journ\u00e9es de rentr\u00e9e, lorsque la \nSoG\u00e9 a un stand \u00e0 l\u2019Ecole, ou toute l\u2019ann\u00e9e \u00e0 leur agence au 38 rue \nGay-Lussac.

", + "body_fr": "

Si vous ouvrez un compte \u00e0 la SoG\u00e9, ils vous versent 140\u20ac et versent \naussi une somme au bureau, nous permettant de financer vos clubs et \n\u00e9v\u00e8nements. Vous pouvez donc rembourser votre cotisation au COF (voire \nplus) rien qu\u2019en ouvrant un compte !

\n

Vous devez ouvrir ce compte lors des journ\u00e9es de rentr\u00e9e, lorsque la \nSoG\u00e9 a un stand \u00e0 l\u2019Ecole, ou toute l\u2019ann\u00e9e \u00e0 leur agence au 38 rue \nGay-Lussac.

", + "body_en": "", + "links": "[]", + "links_fr": "[]", + "links_en": "[]", + "image": null + } +}, +{ + "model": "cofcms.cofdirectoryentrypage", + "pk": 24, + "fields": { + "title_fr": "MAIF", + "title_en": null, + "slug_fr": "maif", + "slug_en": null, + "url_path_fr": "/global/site/partenaires/maif/", + "url_path_en": "/global/site/partenaires/maif/", + "seo_title_fr": null, + "seo_title_en": null, + "search_description_fr": "", + "search_description_en": "", + "body": "

La Maif\u00a0est un partenaire important du COF, et participe notamment au financement de la Plakette.

\n

Elle est aussi pr\u00e9sente \u00e0 chaque rentr\u00e9e pour proposer ses services sous la forme d\u2019un stand d\u2019information.

", + "body_fr": "

La Maif\u00a0est un partenaire important du COF, et participe notamment au financement de la Plakette.

\n

Elle est aussi pr\u00e9sente \u00e0 chaque rentr\u00e9e pour proposer ses services sous la forme d\u2019un stand d\u2019information.

", + "body_en": "", + "links": "[{\"id\": \"87e216ff-343e-4f64-aae8-1141809a6631\", \"value\": {\"url\": \"http://www.maif.fr/accueil.html\", \"texte\": \"Site internet\"}, \"type\": \"lien\"}]", + "links_fr": "[{\"id\": \"87e216ff-343e-4f64-aae8-1141809a6631\", \"value\": {\"url\": \"http://www.maif.fr/accueil.html\", \"texte\": \"Site internet\"}, \"type\": \"lien\"}]", + "links_en": "[]", + "image": 39 + } +}, +{ + "model": "cofcms.cofutilpage", + "pk": 25, + "fields": {} +} +] diff --git a/gestioncof/cms/migrations/0001_initial.py b/gestioncof/cms/migrations/0001_initial.py new file mode 100644 index 00000000..27fe51ff --- /dev/null +++ b/gestioncof/cms/migrations/0001_initial.py @@ -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), + ), + ] diff --git a/gestioncof/cms/migrations/0002_utilpage_and_fixes.py b/gestioncof/cms/migrations/0002_utilpage_and_fixes.py new file mode 100644 index 00000000..e628b81f --- /dev/null +++ b/gestioncof/cms/migrations/0002_utilpage_and_fixes.py @@ -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, + ), + ), + ] diff --git a/gestioncof/cms/migrations/__init__.py b/gestioncof/cms/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/gestioncof/cms/models.py b/gestioncof/cms/models.py new file mode 100644 index 00000000..10c090fe --- /dev/null +++ b/gestioncof/cms/models.py @@ -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" diff --git a/gestioncof/cms/static/cofcms/config.rb b/gestioncof/cms/static/cofcms/config.rb new file mode 100644 index 00000000..826a3727 --- /dev/null +++ b/gestioncof/cms/static/cofcms/config.rb @@ -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 diff --git a/gestioncof/cms/static/cofcms/css/ie.css b/gestioncof/cms/static/cofcms/css/ie.css new file mode 100644 index 00000000..5cd5b6c5 --- /dev/null +++ b/gestioncof/cms/static/cofcms/css/ie.css @@ -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: + * */ diff --git a/gestioncof/cms/static/cofcms/css/print.css b/gestioncof/cms/static/cofcms/css/print.css new file mode 100644 index 00000000..b0e9e456 --- /dev/null +++ b/gestioncof/cms/static/cofcms/css/print.css @@ -0,0 +1,3 @@ +/* Welcome to Compass. Use this file to define print styles. + * Import this file using the following HTML or equivalent: + * */ diff --git a/gestioncof/cms/static/cofcms/css/screen.css b/gestioncof/cms/static/cofcms/css/screen.css new file mode 100644 index 00000000..4cab72c5 --- /dev/null +++ b/gestioncof/cms/static/cofcms/css/screen.css @@ -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: + * */ +@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; + } +} diff --git a/gestioncof/cms/static/cofcms/images/en.png b/gestioncof/cms/static/cofcms/images/en.png new file mode 100644 index 00000000..f3a0d4da Binary files /dev/null and b/gestioncof/cms/static/cofcms/images/en.png differ diff --git a/gestioncof/cms/static/cofcms/images/fr.png b/gestioncof/cms/static/cofcms/images/fr.png new file mode 100644 index 00000000..46568585 Binary files /dev/null and b/gestioncof/cms/static/cofcms/images/fr.png differ diff --git a/gestioncof/cms/static/cofcms/images/minimenu.svg b/gestioncof/cms/static/cofcms/images/minimenu.svg new file mode 100644 index 00000000..46a31695 --- /dev/null +++ b/gestioncof/cms/static/cofcms/images/minimenu.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/gestioncof/cms/static/cofcms/js/calendar.js b/gestioncof/cms/static/cofcms/js/calendar.js new file mode 100644 index 00000000..dbc1024d --- /dev/null +++ b/gestioncof/cms/static/cofcms/js/calendar.js @@ -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( + $("
", {class:"details"}) + .html(this.nextElementSibling.outerHTML) + ); + } +}); diff --git a/gestioncof/cms/static/cofcms/js/script.js b/gestioncof/cms/static/cofcms/js/script.js new file mode 100644 index 00000000..c7693a6d --- /dev/null +++ b/gestioncof/cms/static/cofcms/js/script.js @@ -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 = $("", {href:"ma"+"il"+"to:"+sticker}).text(sticker); + $(this).before(boite) + .remove(); + }) +}); diff --git a/gestioncof/cms/static/cofcms/sass/_colors.scss b/gestioncof/cms/static/cofcms/sass/_colors.scss new file mode 100644 index 00000000..2d295b98 --- /dev/null +++ b/gestioncof/cms/static/cofcms/sass/_colors.scss @@ -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"; diff --git a/gestioncof/cms/static/cofcms/sass/_responsive.scss b/gestioncof/cms/static/cofcms/sass/_responsive.scss new file mode 100644 index 00000000..28216a98 --- /dev/null +++ b/gestioncof/cms/static/cofcms/sass/_responsive.scss @@ -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; + } + } + } + } + } + } +} diff --git a/gestioncof/cms/static/cofcms/sass/screen.scss b/gestioncof/cms/static/cofcms/sass/screen.scss new file mode 100644 index 00000000..43ad8216 --- /dev/null +++ b/gestioncof/cms/static/cofcms/sass/screen.scss @@ -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: + * */ + +@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"; diff --git a/gestioncof/cms/templates/cofcms/base.html b/gestioncof/cms/templates/cofcms/base.html new file mode 100644 index 00000000..c11a2761 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/base.html @@ -0,0 +1,51 @@ +{% load static menu_tags wagtailuserbar i18n wagtailcore_tags %} + + + + + + {% block title %}Association des élèves de l'ENS Ulm{% endblock %} + + {% block extra_head %}{% endblock %} + + + + + +
+ {% block superaside %}{% endblock %} + +
+ {% block content %}{% endblock %} +
+
+ {% wagtailuserbar %} + + diff --git a/gestioncof/cms/templates/cofcms/base_aside.html b/gestioncof/cms/templates/cofcms/base_aside.html new file mode 100644 index 00000000..f27d9a06 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/base_aside.html @@ -0,0 +1,12 @@ +{% extends "cofcms/base.html" %} + +{% block superaside %} +
+
+

{% block aside_title %}{% endblock %}

+
+ {% block aside %}{% endblock %} +
+
+
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/base_nav.html b/gestioncof/cms/templates/cofcms/base_nav.html new file mode 100644 index 00000000..a7a299b0 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/base_nav.html @@ -0,0 +1,16 @@ +{% load wagtailcore_tags i18n cofcms_tags %} + diff --git a/gestioncof/cms/templates/cofcms/calendar.html b/gestioncof/cms/templates/cofcms/calendar.html new file mode 100644 index 00000000..a6a9d87e --- /dev/null +++ b/gestioncof/cms/templates/cofcms/calendar.html @@ -0,0 +1,28 @@ +{% load wagtailcore_tags wagtailroutablepage_tags static i18n %} + + + + + + + + {% blocktrans %}{% endblocktrans %} + {% for week in weeks %} + + {% for day in week %} + + {% endfor %} + + {% endfor %} + +
<{{ this_month|date:"F Y" }}>
LMMJVSD
+ {% if day.events %} + {{ day.day }} +
    +
  • {% trans "Le " %}{{ day.date|date }}
  • + {% for event in day.events %} +
  • {{ event.title }}
  • + {% endfor %} +
+ {% else %}{{ day.day }}{% endif %} +
diff --git a/gestioncof/cms/templates/cofcms/calendar_raw.html b/gestioncof/cms/templates/cofcms/calendar_raw.html new file mode 100644 index 00000000..9ee1aa79 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/calendar_raw.html @@ -0,0 +1,2 @@ +{% load cofcms_tags %} +{% calendar month year %} diff --git a/gestioncof/cms/templates/cofcms/cof_actu_index_page.html b/gestioncof/cms/templates/cofcms/cof_actu_index_page.html new file mode 100644 index 00000000..a6a909db --- /dev/null +++ b/gestioncof/cms/templates/cofcms/cof_actu_index_page.html @@ -0,0 +1,53 @@ +{% extends "cofcms/base_aside.html" %} +{% load wagtailimages_tags cofcms_tags wagtailcore_tags static i18n %} + +{% block extra_head %} + {{ block.super }} + + +{% endblock %} + +{% block aside_title %}Calendrier{% endblock %} +{% block aside %} +
+ {% calendar %} +
+{% endblock %} + +{% block content %} +
+

{{ page.title }}

+
{{ page.introduction|safe }}
+
+ +
+ {% if actus.has_previous %} + Actualités plus récentes + {% endif %} + {% if actus.has_next %} + Actualités plus anciennes + {% endif %} + + {% for actu in page.actus %} +
+
+
+

{{ actu.title }}

+ {% if actu.is_event %} +

{{ actu|dates|capfirst }}
{{ actu.chapo }}

+ {% else %} + {{ actu.body|safe|truncatewords_html:15 }} + {% endif %} + Lire plus > +
+
+ {% endfor %} + + {% if actus.has_previous %} + Actualités plus récentes + {% endif %} + {% if actus.has_next %} + Actualités plus anciennes + {% endif %} +
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/cof_actu_page.html b/gestioncof/cms/templates/cofcms/cof_actu_page.html new file mode 100644 index 00000000..b531aedc --- /dev/null +++ b/gestioncof/cms/templates/cofcms/cof_actu_page.html @@ -0,0 +1,17 @@ +{% extends "cofcms/base.html" %} +{% load wagtailimages_tags cofcms_tags i18n %} + +{% block content %} +
+

{{ page.title }}

+

A lieu {{ page|dates }}

+

{{ page.chapo }}

+
+ +
+
{% image page.image width-700 %}
+
+ {{ page.body|safe }} +
+
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/cof_directory_page.html b/gestioncof/cms/templates/cofcms/cof_directory_page.html new file mode 100644 index 00000000..6ac5491b --- /dev/null +++ b/gestioncof/cms/templates/cofcms/cof_directory_page.html @@ -0,0 +1,48 @@ +{% extends "cofcms/base_aside.html" %} +{% load wagtailimages_tags cofcms_tags static %} + +{% block extra_head %} + {{ block.super }} + + +{% endblock %} +{% block aside_title %}Accès rapide{% endblock %} +{% block aside %} + +{% endblock %} + +{% block content %} +
+

{{ page.title }}

+
{{ page.introduction|safe }}
+
+ +
+ {% for entry in page.entries %} +
+ {% if entry.image %} +
{% image entry.image width-150 class="entry-img" %}
+ {% endif %} +

{{ entry.title }}

+
{{ entry.body|safe }}
+ {% if entry.links %} + + {% endif %} +
+ {% endfor %} +
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/cof_page.html b/gestioncof/cms/templates/cofcms/cof_page.html new file mode 100644 index 00000000..28862d2b --- /dev/null +++ b/gestioncof/cms/templates/cofcms/cof_page.html @@ -0,0 +1,29 @@ +{% extends "cofcms/base.html" %} +{% load wagtailimages_tags cofcms_tags %} + +{% block content %} +
+

{{ page.title }}

+
{{ page.introduction|safe }}
+
+ +
+ {% for block in page.body %} + {% if block.block_type == "heading" %} +

{{ block.value }}

+ {% elif block.block_type == "paragraph" %} +
+ {{ block.value|safe }} +
+ {% elif block.block_type == "image" %} +
+ {% image block.value width-800 %} +
+ {% elif block.block_type == "iframe" %} +
+ +
+ {% endif %} + {% endfor %} +
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/cof_root_page.html b/gestioncof/cms/templates/cofcms/cof_root_page.html new file mode 100644 index 00000000..984b72dc --- /dev/null +++ b/gestioncof/cms/templates/cofcms/cof_root_page.html @@ -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 }} + + +{% endblock %} + +{% block aside_title %}Agenda{% endblock %} +{% block aside %} +
+ {% calendar %} +
+{% endblock %} + +{% block content %} +
+

{{ page.title }}

+
{{ page.introduction|safe }}
+
+ +
+ {% for actu in page.actus %} +
+ +
+ {% if actu.is_event %} + {% mini_calendar actu %}{{ actu|dates }} + {% else %} + {{ actu.body|safe|truncatewords_html:10 }} + {% endif %} +
+ +
+ {% endfor %} +
+{% endblock %} diff --git a/gestioncof/cms/templates/cofcms/mini_calendar.html b/gestioncof/cms/templates/cofcms/mini_calendar.html new file mode 100644 index 00000000..fc750631 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/mini_calendar.html @@ -0,0 +1,11 @@ + + + + {% for day in days %} + + {% endfor %} + + +
+ {{ day.day }} +
diff --git a/gestioncof/cms/templates/cofcms/sympa.html b/gestioncof/cms/templates/cofcms/sympa.html new file mode 100644 index 00000000..119c0614 --- /dev/null +++ b/gestioncof/cms/templates/cofcms/sympa.html @@ -0,0 +1,26 @@ +{% extends "cofcms/base.html" %} +{% load i18n %} + +{% block content %} +
+

{% trans "Listes mail" %}

+
+ +
+
+ {% 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 %} +
+
+
+ {% csrf_token %} + {% if erreur %}

{% trans erreur %}

{% endif %} +

{% blocktrans %}Comment s'appellent les poissons du bassin ?{% endblocktrans %}

+ + +
+
+{% endblock %} diff --git a/gestioncof/cms/templatetags/__init__.py b/gestioncof/cms/templatetags/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/gestioncof/cms/templatetags/cofcms_tags.py b/gestioncof/cms/templatetags/cofcms_tags.py new file mode 100644 index 00000000..686f15f6 --- /dev/null +++ b/gestioncof/cms/templatetags/cofcms_tags.py @@ -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) diff --git a/gestioncof/cms/translation.py b/gestioncof/cms/translation.py new file mode 100644 index 00000000..0a11520e --- /dev/null +++ b/gestioncof/cms/translation.py @@ -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") diff --git a/gestioncof/cms/urls.py b/gestioncof/cms/urls.py new file mode 100644 index 00000000..e69de29b diff --git a/gestioncof/cms/views.py b/gestioncof/cms/views.py new file mode 100644 index 00000000..1b9ce4e9 --- /dev/null +++ b/gestioncof/cms/views.py @@ -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}) diff --git a/requirements.txt b/requirements.txt index 5edfd659..4d443d16 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,8 +20,9 @@ git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_customma ldap3 channels==1.1.5 python-dateutil -wagtail==1.10.* +wagtail==1.11.* wagtailmenus==2.2.* +wagtail-modeltranslation==0.6.0rc2 django-cors-headers==2.2.0 # Production tools