Feat: Livres blancs — nouveau template collection + livre blanc individuel
- Blueprints white-papers / white-paper (intro, cover, PDF, date) - Templates PHP + JSON API (liste avec singleSlug, détail avec fileUrl) - Route POST (:any)/(:any)/download pour le téléchargement gated - Panel : entrée white-papers ajoutée au menu après blog - collection.css : styles partagés extraits de Blog (collection-*) - Blog.svelte : classes renommées blog-* → collection-* - WhitePapers.svelte : vue liste, URLs dynamiques via data.uri - WhitePaper.svelte : vue détail deux colonnes + formulaire de téléchargement - i18n : clés white paper (label, form, consentement, statuts) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
42ee58c18d
commit
d4f05d6157
17 changed files with 870 additions and 183 deletions
61
site/blueprints/pages/white-paper.yml
Normal file
61
site/blueprints/pages/white-paper.yml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
title: Livre blanc
|
||||
icon: file
|
||||
status:
|
||||
draft:
|
||||
label: Brouillon
|
||||
text: Non visible
|
||||
listed:
|
||||
label: Publié
|
||||
text: Visible publiquement
|
||||
tabs:
|
||||
content:
|
||||
label: Contenu
|
||||
icon: text
|
||||
columns:
|
||||
main:
|
||||
width: 2/3
|
||||
sections:
|
||||
header:
|
||||
type: fields
|
||||
fields:
|
||||
intro:
|
||||
label: Description courte
|
||||
type: writer
|
||||
nodes: false
|
||||
marks:
|
||||
- bold
|
||||
- italic
|
||||
- link
|
||||
maxlength: 200
|
||||
sidebar:
|
||||
width: 1/3
|
||||
sections:
|
||||
meta:
|
||||
type: fields
|
||||
fields:
|
||||
published:
|
||||
label: Date de publication
|
||||
type: date
|
||||
display: DD/MM/YYYY
|
||||
required: true
|
||||
default: today
|
||||
translate: false
|
||||
cover:
|
||||
label: Image de couverture
|
||||
type: files
|
||||
layout: cards
|
||||
max: 1
|
||||
accept: image/*
|
||||
translate: false
|
||||
image:
|
||||
cover: true
|
||||
ratio: 3/4
|
||||
uploads:
|
||||
template: image
|
||||
downloadFile:
|
||||
label: Fichier PDF
|
||||
type: files
|
||||
max: 1
|
||||
accept: application/pdf
|
||||
translate: false
|
||||
help: Fichier téléchargé après soumission du formulaire
|
||||
43
site/blueprints/pages/white-papers.yml
Normal file
43
site/blueprints/pages/white-papers.yml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
title: Livres blancs
|
||||
icon: book
|
||||
status:
|
||||
draft:
|
||||
label: Brouillon
|
||||
text: La page est accessible uniquement pour les éditeurs connectés
|
||||
listed:
|
||||
label: Public
|
||||
text: La page est accessible par tout le monde
|
||||
tabs:
|
||||
content:
|
||||
label: Contenu
|
||||
icon: text
|
||||
sections:
|
||||
content:
|
||||
type: fields
|
||||
fields:
|
||||
intro:
|
||||
type: writer
|
||||
marks:
|
||||
- bold
|
||||
- italic
|
||||
- green
|
||||
- pixel
|
||||
- underline
|
||||
- strike
|
||||
- clear
|
||||
- link
|
||||
nodes:
|
||||
- heading
|
||||
headings:
|
||||
- 1
|
||||
help: Section de texte centrée (optionnelle).
|
||||
items:
|
||||
label: Livres blancs
|
||||
type: pages
|
||||
layout: cards
|
||||
sortBy: published desc
|
||||
template: white-paper
|
||||
image:
|
||||
ratio: 3/4
|
||||
cover: true
|
||||
info: "{{ page.published.toDate('d/m/Y') }}"
|
||||
|
|
@ -11,4 +11,27 @@ return [
|
|||
],
|
||||
|
||||
'thumbs' => require __DIR__ . '/thumbs.php',
|
||||
|
||||
'routes' => [
|
||||
[
|
||||
'pattern' => ['(:any)/(:any)/download', 'en/(:any)/(:any)/download'],
|
||||
'method' => 'POST',
|
||||
'action' => function (string $parent, string $slug) {
|
||||
$page = kirby()->page($parent . '/' . $slug);
|
||||
if (!$page || $page->intendedTemplate()->name() !== 'white-paper') {
|
||||
http_response_code(404);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => 'Not found']);
|
||||
exit;
|
||||
}
|
||||
// TODO: store/email form data ($kirby->request()->body())
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'fileUrl' => $page->downloadFile()->toFile()?->url(),
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
]
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ return [
|
|||
'portfolio' => menuItem('portfolio', 'Portfolio','images', 'pages/portfolio'),
|
||||
'jouer' => menuItem('jouer', 'Jouer', 'play', 'pages/jouer'),
|
||||
'a-propos' => menuItem('a-propos', 'À propos', 'users', 'pages/a-propos'),
|
||||
'blog' => menuItem('blog', 'Blog', 'text', 'pages/blog'),
|
||||
'blog' => menuItem('blog', 'Blog', 'text', 'pages/blog'),
|
||||
'white-papers' => menuItem('livres-blancs', 'Livres blancs', 'book', 'pages/livres-blancs'),
|
||||
'-',
|
||||
'users',
|
||||
'system',
|
||||
|
|
|
|||
13
site/templates/white-paper.json.php
Normal file
13
site/templates/white-paper.json.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
$specificData = [
|
||||
'published' => $page->published()->toDate('d/m/Y'),
|
||||
'intro' => $page->intro()->value(),
|
||||
'cover' => $page->cover()->toFile()?->url(),
|
||||
'fileUrl' => $page->downloadFile()->toFile()?->url(),
|
||||
];
|
||||
|
||||
$pageData = array_merge($genericData, $specificData);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($pageData);
|
||||
2
site/templates/white-paper.php
Normal file
2
site/templates/white-paper.php
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?php snippet('header') ?>
|
||||
<?php snippet('footer') ?>
|
||||
26
site/templates/white-papers.json.php
Normal file
26
site/templates/white-papers.json.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
$items = $page->children()->listed()->sortBy('published', 'desc');
|
||||
|
||||
$mapItem = function ($item) {
|
||||
return [
|
||||
'title' => $item->title()->value(),
|
||||
'slug' => $item->slug(),
|
||||
'published' => $item->published()->toDate('d/m/Y'),
|
||||
'intro' => $item->intro()->value(),
|
||||
'cover' => $item->cover()->toFile()?->url(),
|
||||
];
|
||||
};
|
||||
|
||||
$singleSlug = $items->count() === 1 ? $items->first()->slug() : null;
|
||||
|
||||
$specificData = [
|
||||
'intro' => $page->intro()->value(),
|
||||
'items' => $items->map($mapItem)->values(),
|
||||
'singleSlug' => $singleSlug,
|
||||
];
|
||||
|
||||
$pageData = array_merge($genericData, $specificData);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($pageData);
|
||||
2
site/templates/white-papers.php
Normal file
2
site/templates/white-papers.php
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?php snippet('header') ?>
|
||||
<?php snippet('footer') ?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue