bifurqué depuis cliss21/radiomoulins-site
Comparer les révisions
10 Révisions
Auteur | SHA1 | Date |
---|---|---|
Antoine | 1c1c964664 | |
Antoine | 6ee43c1029 | |
Antoine | 280045bbaa | |
Antoine | c2f2f0e54b | |
Antoine | 19808387b9 | |
Antoine | 73a11680df | |
Antoine | de0851c5a8 | |
Antoine | a310181879 | |
Antoine | 5279b72795 | |
Antoine | 0cae5faf68 |
Fichier binaire non affiché.
Après Largeur: | Hauteur: | Taille: 1.5 KiB |
Fichier binaire non affiché.
Après Largeur: | Hauteur: | Taille: 2.3 KiB |
|
@ -6,6 +6,7 @@ import './vendor/bootstrap';
|
|||
import Popover from 'bootstrap/popover';
|
||||
import Toast from 'bootstrap/toast';
|
||||
import Tooltip from 'bootstrap/tooltip';
|
||||
import Offcanvas from 'bootstrap/offcanvas';
|
||||
import SelectorEngine from 'bootstrap/dom/selector-engine';
|
||||
|
||||
/**
|
||||
|
@ -34,4 +35,10 @@ window.addEventListener('load', () => {
|
|||
|
||||
toast.show();
|
||||
});
|
||||
const offcanvasElementList = [].slice.call(
|
||||
document.querySelectorAll('.offcanvas')
|
||||
);
|
||||
offcanvasElementList.map(function (offcanvasEl) {
|
||||
return new Offcanvas(offcanvasEl);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// Pour initialiser des boutons sans Bootstrap
|
||||
%btn-custom {
|
||||
user-select: none;
|
||||
border: none;
|
||||
}
|
|
@ -12,19 +12,36 @@ $img-path: '../img';
|
|||
// see: ../../node_modules/bootstrap/scss/_variables.scss
|
||||
|
||||
// Color system
|
||||
// You could generate a color scheme with: https://palx.jxnblk.com
|
||||
|
||||
$blue: #0d6efd;
|
||||
$blue: #47b7ff;
|
||||
$indigo: #6610f2;
|
||||
$purple: #6f42c1;
|
||||
$pink: #d63384;
|
||||
$purple: #1b0d3b;
|
||||
$pink: #e2a1b4;
|
||||
$red: #dc3545;
|
||||
$orange: #fd7e14;
|
||||
$yellow: #ffc107;
|
||||
$green: #198754;
|
||||
$teal: #20c997;
|
||||
$cyan: #0dcaf0;
|
||||
$yellow: #fdc000;
|
||||
$green: #55c96c;
|
||||
$teal: #40c39d;
|
||||
$cyan: #6fbed2;
|
||||
|
||||
$gray-100: #f7f7f7;
|
||||
$gray-600: #6b6b6b;
|
||||
|
||||
$grey: $gray-100;
|
||||
|
||||
$primary: $purple;
|
||||
$secondary: $teal;
|
||||
|
||||
$body-color: $primary;
|
||||
$link-hover-color: $secondary;
|
||||
|
||||
// Options
|
||||
|
||||
$enable-validation-icons: false;
|
||||
$enable-gradients: true;
|
||||
|
||||
// Typo
|
||||
$font-family-monospace: 'Space Mono';
|
||||
$font-family-base: $font-family-monospace;
|
||||
|
||||
$nav-link-font-weight: 700;
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// Font faces declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Space Mono - Colophon | SIL Open Font License v1.10
|
||||
|
||||
@use '@fontsource/space-mono/scss/mixins' as SpaceMono;
|
||||
|
||||
@each $weight in [$font-weight-normal, $font-weight-bold] {
|
||||
@include SpaceMono.fontFace($weight: $weight);
|
||||
}
|
||||
|
||||
@include SpaceMono.fontFace($style: italic);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* Sticky footer layout with flexboxes, inspired by https://css-tricks.com/couple-takes-sticky-footer/#there-is-flexbox */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.main-header,
|
||||
.main-content {
|
||||
flex: 1 0 auto;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
.footer {
|
||||
font-size: 0.8em;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
.main-header {
|
||||
padding: 0.625rem 0;
|
||||
}
|
||||
|
||||
.main-menu {
|
||||
.nav-link {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// override Bootstrap's offcanvas flexbox behaviour
|
||||
.offcanvas {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.btn-menu-close {
|
||||
@extend %btn-custom;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
background-color: $yellow;
|
||||
}
|
||||
|
||||
.mobile-menu-header {
|
||||
background-color: $grey;
|
||||
}
|
||||
|
||||
.offcanvas-body {
|
||||
padding-top: 5rem;
|
||||
text-align: center;
|
||||
}
|
|
@ -2,16 +2,19 @@
|
|||
|
||||
// Configuration and helpers
|
||||
@import 'abstracts/variables';
|
||||
@import 'abstracts/helpers';
|
||||
|
||||
// Vendors
|
||||
@import 'vendor/bootstrap';
|
||||
@import 'vendor/fork-awesome';
|
||||
|
||||
// Base styles
|
||||
@import 'base/fonts';
|
||||
|
||||
// Layout-related sections
|
||||
//@import "layout/header";
|
||||
//@import "layout/footer";
|
||||
@import 'layout/body';
|
||||
@import 'layout/header';
|
||||
@import "layout/footer";
|
||||
|
||||
// Components
|
||||
@import 'components/forms';
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Fork Awesome
|
||||
// ----------------------------------------------------------------------------
|
||||
// see: https://forkaweso.me/
|
||||
$fa-font-path: '~fork-awesome/fonts';
|
||||
|
||||
@import '~fork-awesome/scss/variables';
|
||||
@import '~fork-awesome/scss/mixins';
|
||||
@import '~fork-awesome/scss/functions';
|
||||
@import '~fork-awesome/scss/core';
|
||||
@import '~fork-awesome/scss/larger';
|
||||
@import '~fork-awesome/scss/fixed-width';
|
||||
@import '~fork-awesome/scss/list';
|
||||
@import '~fork-awesome/scss/bordered-pulled';
|
||||
@import '~fork-awesome/scss/animated';
|
||||
@import '~fork-awesome/scss/rotated-flipped';
|
||||
@import '~fork-awesome/scss/stacked';
|
||||
@import '~fork-awesome/scss/icons';
|
||||
@import '~fork-awesome/scss/screen-reader';
|
||||
|
||||
// Overwrite @font-face definition to use only woff and woff2 formats.
|
||||
@font-face {
|
||||
font-family: '#{$fa-font-family}';
|
||||
src: url('#{$fa-font-path}/forkawesome-webfont.woff?v=#{$fa-version}')
|
||||
format('woff'),
|
||||
url('#{$fa-font-path}/forkawesome-webfont.woff2?v=#{$fa-version}')
|
||||
format('woff2');
|
||||
}
|
Fichier diff supprimé car celui-ci est trop grand
Voir la Diff
|
@ -13,9 +13,11 @@
|
|||
"format": "prettier \"assets/**/*.{js,scss}\" --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/space-mono": "^4.5.0",
|
||||
"@popperjs/core": "^2.10.1",
|
||||
"bootstrap": "~5.1.0",
|
||||
"core-js": "~3.17.2"
|
||||
"core-js": "~3.17.2",
|
||||
"fork-awesome": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.5",
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
from .pages import StandardPage
|
||||
from .settings import MenuSettings, SiteSettings
|
||||
|
||||
__all__ = [
|
||||
'MenuSettings',
|
||||
'SiteSettings',
|
||||
'StandardPage',
|
||||
]
|
|
@ -0,0 +1,67 @@
|
|||
from django.utils.functional import cached_property
|
||||
|
||||
from wagtail.core import blocks
|
||||
from wagtail.core.utils import resolve_model_string
|
||||
|
||||
from wagtail_cblocks import blocks as cblocks
|
||||
|
||||
from radiomoulins.utils.blocks import ModelChooserBlock
|
||||
|
||||
RICHTEXT_FEATURES = ('bold', 'italic', 'ol', 'ul', 'link', 'document-link')
|
||||
|
||||
|
||||
class BaseStreamBlock(blocks.StreamBlock):
|
||||
"""
|
||||
Blocks éditoriaux strandards proposés par défaut
|
||||
"""
|
||||
|
||||
title_block = cblocks.HeadingBlock()
|
||||
paragraph_block = cblocks.ParagraphBlock()
|
||||
button_block = cblocks.ButtonBlock()
|
||||
image_block = cblocks.ImageBlock()
|
||||
|
||||
|
||||
class BodyBlock(BaseStreamBlock):
|
||||
columns_block = cblocks.ColumnsBlock(BaseStreamBlock())
|
||||
|
||||
|
||||
class MenuItemBlock(blocks.StructBlock):
|
||||
"""Un item de menu"""
|
||||
|
||||
text = blocks.CharBlock(label="Texte")
|
||||
link = cblocks.LinkBlock()
|
||||
|
||||
class Meta:
|
||||
template = 'menu/menu_item_block.html'
|
||||
|
||||
|
||||
class MenuChooserBlock(ModelChooserBlock):
|
||||
def get_context(self, value, parent_context=None):
|
||||
context = super().get_context(value, parent_context=parent_context)
|
||||
context['menu'] = value.menu
|
||||
return context
|
||||
|
||||
@cached_property
|
||||
def target_model(self):
|
||||
return resolve_model_string('core.MenuSettings')
|
||||
|
||||
class Meta:
|
||||
template = 'menu/menu_list.html'
|
||||
|
||||
|
||||
class FooterContentStreamBlock(blocks.StreamBlock):
|
||||
richtech = blocks.RichTextBlock(
|
||||
label="Texte",
|
||||
features=RICHTEXT_FEATURES,
|
||||
)
|
||||
menu = MenuChooserBlock(label="menu")
|
||||
|
||||
|
||||
class FooterItemBlock(blocks.StructBlock):
|
||||
"""Un item de pied de page"""
|
||||
|
||||
title = blocks.CharBlock(label="Titre")
|
||||
content = FooterContentStreamBlock(label="Contenu")
|
||||
|
||||
class Meta:
|
||||
template = 'footer/footer_item_block.html'
|
|
@ -0,0 +1,26 @@
|
|||
from wagtail.admin.edit_handlers import StreamFieldPanel
|
||||
from wagtail.contrib.settings.models import BaseSetting, register_setting
|
||||
from wagtail.core.fields import StreamField
|
||||
|
||||
from .blocks import MenuItemBlock
|
||||
|
||||
|
||||
@register_setting
|
||||
class MenuSettings(BaseSetting):
|
||||
class Meta:
|
||||
verbose_name = 'menu principal'
|
||||
|
||||
def __str__(self):
|
||||
return 'Menu: {}'.format(
|
||||
', '.join([item.value['text'] for item in self.menu])
|
||||
)
|
||||
|
||||
menu = StreamField(
|
||||
[
|
||||
('item', MenuItemBlock(label="Élément de menu")),
|
||||
],
|
||||
verbose_name="Éléments de menu",
|
||||
)
|
||||
panels = [
|
||||
StreamFieldPanel('menu'),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
from wagtail.admin.edit_handlers import StreamFieldPanel
|
||||
from wagtail.core.fields import StreamField
|
||||
from wagtail.core.models import Page
|
||||
|
||||
from .blocks import BodyBlock
|
||||
|
||||
|
||||
class AbstractPage(Page):
|
||||
"""Toutes les pages du site en hériteront."""
|
||||
|
||||
show_in_menus_default = True
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class StandardPage(AbstractPage):
|
||||
body = StreamField(BodyBlock())
|
||||
|
||||
AbstractPage.content_panels = Page.content_panels + [
|
||||
StreamFieldPanel('body'),
|
||||
]
|
|
@ -0,0 +1,47 @@
|
|||
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
|
||||
from wagtail.contrib.settings.models import BaseSetting, register_setting
|
||||
from wagtail.core.fields import RichTextField, StreamField
|
||||
|
||||
from .blocks import FooterItemBlock, MenuItemBlock
|
||||
|
||||
|
||||
@register_setting
|
||||
class MenuSettings(BaseSetting):
|
||||
class Meta:
|
||||
verbose_name = 'menu principal'
|
||||
|
||||
def __str__(self):
|
||||
return 'Menu: {}'.format(
|
||||
', '.join([item.value['text'] for item in self.menu])
|
||||
)
|
||||
|
||||
menu = StreamField(
|
||||
[
|
||||
('item', MenuItemBlock(label="Élément de menu")),
|
||||
],
|
||||
verbose_name="Éléments de menu",
|
||||
)
|
||||
panels = [
|
||||
StreamFieldPanel('menu'),
|
||||
]
|
||||
|
||||
|
||||
@register_setting
|
||||
class SiteSettings(BaseSetting):
|
||||
class Meta:
|
||||
verbose_name = "Apparence"
|
||||
|
||||
footer_columns = StreamField(
|
||||
[
|
||||
('column', FooterItemBlock(label="Élément de pied de page")),
|
||||
],
|
||||
verbose_name="Éléments du pied de page",
|
||||
)
|
||||
legal_stuff = RichTextField(
|
||||
max_length=255, blank=True, verbose_name="choses légales"
|
||||
)
|
||||
|
||||
panels = [
|
||||
StreamFieldPanel('footer_columns'),
|
||||
FieldPanel('legal_stuff'),
|
||||
]
|
|
@ -80,6 +80,7 @@ DJANGO_APPS = [
|
|||
WAGTAIL_APPS = [
|
||||
'wagtail.contrib.forms',
|
||||
'wagtail.contrib.redirects',
|
||||
'wagtail.contrib.settings',
|
||||
'wagtail.embeds',
|
||||
'wagtail.sites',
|
||||
'wagtail.users',
|
||||
|
@ -94,7 +95,9 @@ WAGTAIL_APPS = [
|
|||
]
|
||||
|
||||
# Project dependencies
|
||||
THIRD_PARTY_APPS = []
|
||||
THIRD_PARTY_APPS = [
|
||||
'wagtail_cblocks',
|
||||
]
|
||||
|
||||
# Project applications
|
||||
LOCAL_APPS = ['radiomoulins.core']
|
||||
|
@ -253,6 +256,10 @@ MESSAGE_TAGS = {
|
|||
messages.ERROR: 'danger',
|
||||
}
|
||||
|
||||
# Don't migrate to BigAutoField
|
||||
# https://docs.djangoproject.com/en/3.2/releases/3.2/#customizing-type-of-auto-created-primary-keys
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||
|
||||
# WAGTAIL
|
||||
# ------------------------------------------------------------------------------
|
||||
# http://docs.wagtail.io/en/stable/advanced_topics/settings.html
|
||||
|
|
|
@ -23,7 +23,16 @@
|
|||
{% block extra_head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="main-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class='col main-menu'>{% include "menu/menu.html" with menu=page.get_site.menusettings.menu %}</div>
|
||||
<div class="col logo"><a href='/'><img src="{% static "./img/logo.png" %}" alt="logo"></a></div>
|
||||
<div class="col search"></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container main-content">
|
||||
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
@ -32,10 +41,10 @@
|
|||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
<p>Utilisez ce modèle pour démarrer rapidement une nouvelle application.</p>
|
||||
{% endblock %}
|
||||
|
||||
</div><!-- .container -->
|
||||
{% include "./footer.html" with settings=page.get_site.sitesettings %}
|
||||
|
||||
{% block javascript %}
|
||||
<script src="{% static "main.js" %}"></script>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
{% block content %}
|
||||
{% for block in page.body %}
|
||||
{% include_block block %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,13 @@
|
|||
{% load wagtailcore_tags %}
|
||||
<footer class="container footer">
|
||||
<div class="row">
|
||||
{% for col in settings.footer_columns %}
|
||||
<div class="col">
|
||||
{% include_block col %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="footer-bottom mt-4">
|
||||
<span class="text-center">{{ settings.legal_stuff|richtext }}</span>
|
||||
</div>
|
||||
</footer>
|
|
@ -0,0 +1,2 @@
|
|||
<h3>{{ value.title }}</h3>
|
||||
{{ value.content }}
|
|
@ -0,0 +1,15 @@
|
|||
<nav class="navbar navbar-expand-lg">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar" aria-controls="navbarOffcanvasLg">
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
|
||||
<div class="offcanvas-body">
|
||||
{% include "./menu_list.html" %}
|
||||
</div>
|
||||
<div class="mobile-menu-header">
|
||||
<button type="button" class="btn-menu-close d-lg-none" data-bs-dismiss="offcanvas" aria-label="Close">
|
||||
<i class="fa fa-times" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
|
@ -0,0 +1 @@
|
|||
<a class="nav-link" href="{{ value.link.href }}">{{ value.text }}</a>
|
|
@ -0,0 +1,6 @@
|
|||
{% load wagtailcore_tags %}
|
||||
<ul class="navbar-nav">
|
||||
{% for item_block in menu %}
|
||||
<li class="nav-item">{% include_block item_block %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
|
@ -0,0 +1,32 @@
|
|||
from django import forms
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from wagtail.core import blocks
|
||||
|
||||
|
||||
class ModelChooserBlock(blocks.ChooserBlock):
|
||||
@cached_property
|
||||
def field(self):
|
||||
return forms.ModelChoiceField(
|
||||
queryset=self.get_queryset(),
|
||||
widget=self.widget,
|
||||
required=self._required,
|
||||
validators=self._validators,
|
||||
help_text=self._help_text,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def widget(self):
|
||||
return forms.Select()
|
||||
|
||||
@cached_property
|
||||
def target_model(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_queryset(self):
|
||||
return self.target_model.objects.all()
|
||||
|
||||
def value_from_form(self, value):
|
||||
if value == '':
|
||||
return None
|
||||
return super().value_from_form(value)
|
|
@ -1,8 +1,9 @@
|
|||
# Django
|
||||
# ------------------------------------------------------------------------------
|
||||
django >=2.2,<2.3
|
||||
django-environ ==0.4.5
|
||||
django >=3.2,<3.3
|
||||
django-environ >=0.7,<0.8
|
||||
|
||||
# Wagtail
|
||||
# ------------------------------------------------------------------------------
|
||||
wagtail >=2.11,<2.12
|
||||
wagtail >=2.14,<2.15
|
||||
wagtail-cblocks >=0.3,<0.4 # https://forge.cliss21.org/cliss21/wagtail-cblocks
|
||||
|
|
|
@ -29,7 +29,7 @@ const CONFIG = {
|
|||
// Path to other assets wich will be copied with copy-webpack-plugin
|
||||
// See: https://www.npmjs.com/package/copy-webpack-plugin
|
||||
COPY_PATTERNS: [
|
||||
// { from: 'assets/img', to: 'img' },
|
||||
{ from: 'assets/img', to: 'img' },
|
||||
],
|
||||
|
||||
// Path to the build output, which can safely be cleaned
|
||||
|
|
Chargement…
Référencer dans un nouveau ticket