Comparer les révisions

...

10 Révisions

29 fichiers modifiés avec 18911 ajouts et 18 suppressions

BIN
assets/img/logo-small.png Normal file

Fichier binaire non affiché.

Après

Largeur:  |  Hauteur:  |  Taille: 1.5 KiB

BIN
assets/img/logo.png Normal file

Fichier binaire non affiché.

Après

Largeur:  |  Hauteur:  |  Taille: 2.3 KiB

Voir le fichier

@ -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);
});
});

Voir le fichier

@ -0,0 +1,5 @@
// Pour initialiser des boutons sans Bootstrap
%btn-custom {
user-select: none;
border: none;
}

Voir le fichier

@ -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;

Voir le fichier

@ -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);

Voir le fichier

@ -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;
}

Voir le fichier

@ -0,0 +1,3 @@
.footer {
font-size: 0.8em;
}

Voir le fichier

@ -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;
}

Voir le fichier

@ -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';

28
assets/scss/vendor/_fork-awesome.scss externe Normal file
Voir le fichier

@ -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');
}

18502
package-lock.json générée Normal file

Fichier diff supprimé car celui-ci est trop grand Voir la Diff

Voir le fichier

@ -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",

Voir le fichier

@ -0,0 +1,8 @@
from .pages import StandardPage
from .settings import MenuSettings, SiteSettings
__all__ = [
'MenuSettings',
'SiteSettings',
'StandardPage',
]

Voir le fichier

@ -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'

Voir le fichier

@ -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'),
]

Voir le fichier

@ -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'),
]

Voir le fichier

@ -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'),
]

Voir le fichier

@ -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

Voir le fichier

@ -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>

Voir le fichier

@ -0,0 +1,8 @@
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block content %}
{% for block in page.body %}
{% include_block block %}
{% endfor %}
{% endblock %}

Voir le fichier

@ -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>

Voir le fichier

@ -0,0 +1,2 @@
<h3>{{ value.title }}</h3>
{{ value.content }}

Voir le fichier

@ -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>

Voir le fichier

@ -0,0 +1 @@
<a class="nav-link" href="{{ value.link.href }}">{{ value.text }}</a>

Voir le fichier

@ -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>

Voir le fichier

@ -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)

Voir le fichier

@ -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

Voir le fichier

@ -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