breadcrumb

This commit is contained in:
2026-01-20 15:46:27 +01:00
parent 3d3d01e653
commit bf3c7a562b
16 changed files with 557 additions and 33 deletions

2
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "cc3d29c7253fdc07cd13d6d07968ca95", "content-hash": "ac9d6b4c23e1156901adb2d3916d33bf",
"packages": [ "packages": [
{ {
"name": "asm89/stack-cors", "name": "asm89/stack-cors",

View File

@@ -0,0 +1,34 @@
uuid: 48a82b35-91a5-4ef6-9411-158ce663b4c3
langcode: fr
status: true
dependencies:
config:
- system.menu.contenu
module:
- menu_block
theme:
- mathallo
id: mathallo_contenu_2
theme: mathallo
region: breadcrumb
weight: 0
provider: null
plugin: 'menu_block:contenu'
settings:
id: 'menu_block:contenu'
label: Contenu
label_display: '0'
provider: menu_block
follow: false
follow_parent: child
display_empty: false
label_link: false
label_type: block
level: 1
depth: 0
expand_all_items: false
parent: 'contenu:'
render_parent: false
suggestion: contenu
hide_on_nonactive: true
visibility: { }

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,6 @@
@import "partials/colors"; @import "partials/colors";
@import "partials/fonts"; @import "partials/fonts";
@import "partials/mixins";
a, a:visited{ a, a:visited{
text-decoration: none; text-decoration: none;
@@ -15,6 +16,15 @@ body{
$header_height: 50px; $header_height: 50px;
// _ _
// | | | |
// | | __ _ _ _ ___ _ _| |_
// | | / _` | | | |/ _ \| | | | __|
// | |___| (_| | |_| | (_) | |_| | |_
// \_____/\__,_|\__, |\___/ \__,_|\__|
// __/ |
// |___/
div.layout-container{ div.layout-container{
// display: flex; // display: flex;
// flex-direction: column; // flex-direction: column;
@@ -29,8 +39,16 @@ div.layout-container{
width: 100vw; width: 100vw;
height: $header_height; height: $header_height;
} }
nav[role="breadcrumb"]{
// flex: 1 1 auto;
position: fixed;
z-index: 90;
top:$header_height + 40px;
left: 20px;
}
main[role="main"]{ main[role="main"]{
// flex: 1 1 auto; // flex: 1 1 auto;
padding:5em 0;
overflow-y: scroll; overflow-y: scroll;
} }
footer[role="contentinfo"]{ footer[role="contentinfo"]{
@@ -44,7 +62,14 @@ div.layout-container{
// _ _ _
// | | | | | |
// | |_| | ___ __ _ __| | ___ _ __
// | _ |/ _ \/ _` |/ _` |/ _ \ '__|
// | | | | __/ (_| | (_| | __/ |
// \_| |_/\___|\__,_|\__,_|\___|_|
header[role="banner"]{ header[role="banner"]{
background-color: #fff; background-color: #fff;
box-shadow: 0 -5px 15px #000; box-shadow: 0 -5px 15px #000;
@@ -130,36 +155,18 @@ header[role="banner"]{
} }
nav#block-mathallo-contenu{ nav#block-mathallo-contenu{
padding: 1em; @include menu-contenus;
ul,li{
padding: 0;
margin:0;
list-style: none;
}
li{ li{
padding:0 0 1em 0; padding:0 0 1em 0;
&:first-child{ &:first-child{
padding:0.25em 0 1em; padding:0.25em 0 1em;
} }
} }
label{
color:$bleu_site;
font-weight: 600;
display: block;
font-size: 0.756em;
padding:0 0 0.25em 0;
&:has(+ a:hover){
color: $rose;
}
}
a{
font-size: 1.13em;
}
&>ul{ // chapitres &>ul{ // chapitres
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 2em; gap: 2em;
>li{ >li{
>ul{ // parties >ul{ // parties
margin:0.75em 0 0; margin:0.75em 0 0;
padding:0 0 0 1em; padding:0 0 0 1em;
@@ -168,7 +175,7 @@ header[role="banner"]{
} }
} }
} }
} }
} }
nav#block-mathallo-navigationprincipale{ nav#block-mathallo-navigationprincipale{
@@ -192,9 +199,58 @@ header[role="banner"]{
} }
} // end of header[role="banner"]{ } // end of header[role="banner"]{
// ______ _ _
// | ___ \ | | | |
// | |_/ /_ __ ___ __ _ __| | ___ _ __ _ _ _ __ ___ | |__
// | ___ \ '__/ _ \/ _` |/ _` |/ __| '__| | | | '_ ` _ \| '_ \
// | |_/ / | | __/ (_| | (_| | (__| | | |_| | | | | | | |_) |
// \____/|_| \___|\__,_|\__,_|\___|_| \__,_|_| |_| |_|_.__/
nav[role="breadcrumb"]{
background-color: #fff;
box-shadow: 0 0 10px rgba(0,0,0,0.25);
padding:0em;
ul{
margin:0;
padding-left: 0.5em;
li{
list-style: none;
}
}
#block-mathallo-contenu-2{
@include menu-contenus;
padding: 0.5em 1em;
li:not(.in-active-trail){
display: none;
}
ul,li{
display: flex;
flex-direction: row;
align-items: baseline;
gap: 1em;
}
a{
font-size: 1em;
}
&>ul>li>ul>li{
padding-left: 1em;
border-left: 2px solid $bleu_site;
}
}
}
// ___ ___ _
// | \/ | (_)
// | . . | __ _ _ _ __
// | |\/| |/ _` | | '_ \
// | | | | (_| | | | | |
// \_| |_/\__,_|_|_| |_|
main[role="main"]{ main[role="main"]{
div.layout-content{ div.layout-content{
padding:5em 0;
article{ article{
position: relative; position: relative;
background-color: #fff; background-color: #fff;
@@ -207,7 +263,8 @@ main[role="main"]{
@include titre_h2; @include titre_h2;
margin:0; margin:0;
} }
div.field-chapitre-num{ div.field-chapitre-num,
div.field-partie-num{
background-color: $bleu_site; background-color: $bleu_site;
color: #fff; color: #fff;
display: inline-flex; display: inline-flex;
@@ -222,6 +279,14 @@ main[role="main"]{
} }
} }
article.node-type-chapitre{
}
section.parties{
display: flex;
gap: 2em;
padding:1em;
}
// HOME // HOME
div.views-home-chapitres{ div.views-home-chapitres{
display: flex; display: flex;
@@ -241,7 +306,13 @@ main[role="main"]{
} }
} }
// ______ _
// | ___| | |
// | |_ ___ ___ | |_ ___ _ __
// | _/ _ \ / _ \| __/ _ \ '__|
// | || (_) | (_) | || __/ |
// \_| \___/ \___/ \__\___|_|
footer[role="contentinfo"]{ footer[role="contentinfo"]{
background-color: #fff; background-color: #fff;
box-shadow: 0 5px 15px #000; box-shadow: 0 5px 15px #000;

View File

@@ -0,0 +1,22 @@
@mixin menu-contenus{
padding: 1em;
ul,li{
padding: 0;
margin:0;
list-style: none;
}
label{
color:$bleu_site;
font-weight: 600;
display: block;
font-size: 0.756em;
padding:0 0 0.25em 0;
&:has(+ a:hover){
color: $rose;
}
}
a{
font-size: 1.13em;
}
}

View File

@@ -37,7 +37,8 @@ function mathallo_preprocess_region(&$variables) {
} }
function mathallo_preprocess_block__mathallo_contenu(&$variables) { // function mathallo_preprocess_block__mathallo_contenu(&$variables) {
function mathallo_preprocess_block__menu_block__contenu(&$variables) {
foreach ($variables['content']['#items'] as $key => $item) { foreach ($variables['content']['#items'] as $key => $item) {
parse_menu_item($variables['content']['#items'], $key); parse_menu_item($variables['content']['#items'], $key);
} }
@@ -47,14 +48,20 @@ function parse_menu_item(&$items, $key){
if ($items[$key]['url']->getRouteName() === "entity.node.canonical") { if ($items[$key]['url']->getRouteName() === "entity.node.canonical") {
$nid = $items[$key]['url']->getRouteParameters()['node']; $nid = $items[$key]['url']->getRouteParameters()['node'];
$node = \Drupal\node\Entity\Node::load($nid); $node = \Drupal\node\Entity\Node::load($nid);
// create prefix (label) for chapitres
if ($node->getType() === "chapitre") { if ($node->getType() === "chapitre") {
$chapitre = $node->get('field_chapitre_num')->getValue()[0]['value']; $chapitre = $node->get('field_chapitre_num')->getValue()[0]['value'];
$items[$key]['prefix'] = "Chapitre {$chapitre}"; $items[$key]['prefix'] = "Chapitre {$chapitre}";
} }
// create prefix (label) for parties
if ($node->getType() === "partie") { if ($node->getType() === "partie") {
$partie = $node->get('field_partie')->getValue()[0]['value']; $partie = $node->get('field_partie')->getValue()[0]['value'];
$items[$key]['prefix'] = "Partie {$partie}"; $items[$key]['prefix'] = "Partie {$partie}";
} }
// add active attribute
if ($items[$key]['in_active_trail']){
$items[$key]['attributes']->offsetSet('class', 'in-active-trail');
}
} }
if (count($items[$key]['below']) > 0) { if (count($items[$key]['below']) > 0) {
foreach ($items[$key]['below'] as $key_b => $item_b) { foreach ($items[$key]['below'] as $key_b => $item_b) {

View File

@@ -0,0 +1,64 @@
{#
/**
* @file
* Default theme implementation for a field.
*
* To override output, copy the "field.html.twig" from the templates directory
* to your theme's directory and customize it, just like customizing other
* Drupal templates such as page.html.twig or node.html.twig.
*
* Instead of overriding the theming for all fields, you can also just override
* theming for a subset of fields using
* @link themeable Theme hook suggestions. @endlink For example,
* here are some theme hook suggestions that can be used for a field_foo field
* on an article node type:
* - field--node--field-foo--article.html.twig
* - field--node--field-foo.html.twig
* - field--node--article.html.twig
* - field--field-foo.html.twig
* - field--text-with-summary.html.twig
* - field.html.twig
*
* Available variables:
* - attributes: HTML attributes for the containing element.
* - label_hidden: Whether to show the field label or not.
* - title_attributes: HTML attributes for the title.
* - label: The label for the field.
* - multiple: TRUE if a field can contain multiple items.
* - items: List of all the field items. Each item contains:
* - attributes: List of HTML attributes for each item.
* - content: The field item's content.
* - entity_type: The entity type to which the field belongs.
* - field_name: The name of the field.
* - field_type: The type of the field.
* - label_display: The display settings for the label.
*
* @see template_preprocess_field()
*
* @ingroup themeable
*/
#}
{%
set title_classes = [
label_display == 'visually_hidden' ? 'visually-hidden',
]
%}
{% if label_hidden %}
{% if multiple %}
<div{{ attributes }}>
{% for item in items %}
<div{{ item.attributes }}>{{ item.content }}</div>
{% endfor %}
</div>
{% else %}
{% for item in items %}
<div{{ attributes }}>{{ item.content }}</div>
{% endfor %}
{% endif %}
{% else %}
<label>{{ label }}</label>
{% for item in items %}
<div{{ item.attributes }}>{{ item.content }}</div>
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,45 @@
{#
/**
* @file
* Default theme implementation for a field.
*
* To override output, copy the "field.html.twig" from the templates directory
* to your theme's directory and customize it, just like customizing other
* Drupal templates such as page.html.twig or node.html.twig.
*
* Instead of overriding the theming for all fields, you can also just override
* theming for a subset of fields using
* @link themeable Theme hook suggestions. @endlink For example,
* here are some theme hook suggestions that can be used for a field_foo field
* on an article node type:
* - field--node--field-foo--article.html.twig
* - field--node--field-foo.html.twig
* - field--node--article.html.twig
* - field--field-foo.html.twig
* - field--text-with-summary.html.twig
* - field.html.twig
*
* Available variables:
* - attributes: HTML attributes for the containing element.
* - label_hidden: Whether to show the field label or not.
* - title_attributes: HTML attributes for the title.
* - label: The label for the field.
* - multiple: TRUE if a field can contain multiple items.
* - items: List of all the field items. Each item contains:
* - attributes: List of HTML attributes for each item.
* - content: The field item's content.
* - entity_type: The entity type to which the field belongs.
* - field_name: The name of the field.
* - field_type: The type of the field.
* - label_display: The display settings for the label.
*
* @see template_preprocess_field()
*
* @ingroup themeable
*/
#}
{% for item in items %}
<div{{ item.attributes }}>{{ item.content }}</div>
{% endfor %}

View File

@@ -38,10 +38,12 @@
{% endif %} {% endif %}
{% for item in items %} {% for item in items %}
<li{{ item.attributes }}> <li{{ item.attributes }}>
{% if item.prefix %} <div class="wrapper">
<label class="link-prefix">{{ item.prefix }}</label> {% if item.prefix %}
{% endif %} <label class="link-prefix">{{ item.prefix }}</label>
{{ link(item.title, item.url) }} {% endif %}
{{ link(item.title, item.url) }}
</div>
{% if item.below %} {% if item.below %}
{{ menus.menu_links(item.below, attributes, menu_level + 1) }} {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
{% endif %} {% endif %}

View File

@@ -0,0 +1,85 @@
{#
/**
* @file
* Default theme implementation to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: (optional) The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: (optional) Themed creation date field.
* - author_name: (optional) Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
*
* @see template_preprocess_node()
*
* @ingroup themeable
*/
#}
<article{{ attributes }}>
<div class="field-chapitre-num">
{{ content.field_chapitre_num }}
</div>
{{ title_prefix }}
{# {% if label and not page %} #}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{# {% endif %} #}
{{ title_suffix }}
<div{{ content_attributes }}>
{{ content|without('field_chapitre_num','field_parties') }}
</div>
</article>
<section class="parties">
{{ content.field_parties }}
<section>

View File

@@ -0,0 +1,82 @@
{#
/**
* @file
* Default theme implementation to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: (optional) The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: (optional) Themed creation date field.
* - author_name: (optional) Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
*
* @see template_preprocess_node()
*
* @ingroup themeable
*/
#}
<article{{ attributes }}>
<div class="field-partie-num">
{{ content.field_partie }}
</div>
{{ title_prefix }}
{% if label and not page %}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
<div{{ content_attributes }}>
{{ content|without('field_partie') }}
</div>
</article>

View File

@@ -0,0 +1,89 @@
{#
/**
* @file
* Default theme implementation to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: (optional) The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: (optional) Themed creation date field.
* - author_name: (optional) Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
*
* @see template_preprocess_node()
*
* @ingroup themeable
*/
#}
<article{{ attributes }}>
{{ title_prefix }}
{% if label and not page %}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
{% if display_submitted %}
<footer>
{{ author_picture }}
<div{{ author_attributes }}>
{% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
{{ metadata }}
</div>
</footer>
{% endif %}
<div{{ content_attributes }}>
{{ content }}
</div>
</article>

View File

@@ -60,8 +60,10 @@
{{ page.primary_menu }} {{ page.primary_menu }}
{{ page.secondary_menu }} {{ page.secondary_menu }}
<nav role="breadcrumb">
{{ page.breadcrumb }} {{ page.breadcrumb }}
</nav>
{{ page.highlighted }} {{ page.highlighted }}
{{ page.help }} {{ page.help }}

View File

@@ -0,0 +1,21 @@
{#
/**
* @file
* Default theme implementation to display a region.
*
* Available variables:
* - content: The content for this region, typically blocks.
* - attributes: HTML attributes for the region <div>.
* - region: The name of the region variable as defined in the theme's
* .info.yml file.
*
* @see template_preprocess_region()
*
* @ingroup themeable
*/
#}
{% if content %}
<div{{ attributes }}>
{{ content }}
</div>
{% endif %}