ressource type-en-images, php js et css

This commit is contained in:
2025-05-26 12:46:26 +02:00
parent 36f6cebfd5
commit 08d8b37aa2
11 changed files with 560 additions and 61 deletions
File diff suppressed because one or more lines are too long
+112 -4
View File
@@ -2206,11 +2206,11 @@ svg.ext {
width: fit-content;
padding-left: 25%;
}
@media screen and (min-width: 1100px) {
@media (min-width: 1100px) {
.page-node-type-ressource .layout__region--top .block-region-top .block-entity-fieldnodefield-images {
grid-column: 1;
grid-row: 1/span 7; /* Prendre toutes les lignes disponibles */
align-self: start; /* S'assurer qu'il commence en haut */
grid-row: 1/span 7;
align-self: start;
justify-self: end;
margin-left: 2rem;
}
@@ -5585,7 +5585,7 @@ svg.ext {
.path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-content .view-type-slide:not(footer) h3.type-les-projets-en-images {
width: 80%;
border-top: solid 2px rgba(0, 0, 0, 0.3);
padding-top: 4rem;
padding-top: 4 rem;
}
.path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-content .view-type-slide:not(footer) h3.type-les-projets-en-images:before {
content: url("../images/pictos/picto-ressource-projetsimages.svg");
@@ -5634,6 +5634,114 @@ svg.ext {
right: 15%;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top {
display: flex !important;
flex-direction: column;
margin-left: 11%;
}
@media screen and (min-width: 1100px) {
.page-node-type-ressource .type-les-projets-en-images .block-region-top {
display: flex;
}
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block {
margin-left: 0;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images {
padding: 0;
order: 7;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel {
max-width: 60vw;
margin: auto;
text-align: center;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container {
position: relative;
height: 500px;
max-height: 500px;
overflow: hidden;
width: 100%;
object-fit: contain;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container img {
width: 100%;
height: 100%;
object-fit: contain;
transition: transform 0.3s ease-in-out;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container img.animate {
transform: scale(1.02);
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: #00aaff;
border-radius: 50%;
padding: 5px 10px;
color: white;
cursor: pointer;
}
content .page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow.left {
left: 10px;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow.right {
right: 10px;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .caption {
margin-top: 10px;
font-family: sans-serif;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper {
position: relative;
max-width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow {
cursor: pointer;
padding: 5px 10px;
background: #00aaff;
color: white;
border-radius: 50%;
user-select: none;
z-index: 2;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow.left {
margin-right: 10px;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow.right {
margin-left: 10px;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails {
display: flex;
gap: 10px;
overflow-x: auto;
scroll-behavior: smooth;
max-width: 100%;
padding: 10px 0;
scrollbar-width: none;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails::-webkit-scrollbar {
display: none;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails img {
width: 60px;
height: 60px;
object-fit: cover;
border: 2px solid transparent;
cursor: pointer;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails img.active {
border-color: #00aaff;
}
.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .field__items {
display: none;
}
/*partials*/
.layout-container {
position: relative;
+49 -40
View File
@@ -14,9 +14,18 @@ use Drupal\Core\Template\Attribute;
function eql_preprocess_html(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node){
if ($node instanceof NodeInterface) {
$variables['attributes']['class'][] = 'node-type-' . $node->bundle();
$variables['attributes']['class'][] = 'node-id-' . $node->id();
// Pour les ressources : ajoute la classe de type de ressource
if ($node->bundle() === 'ressource' && $node->hasField('field_type_de_ressource')) {
foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) {
$label = $term->label();
$css_class = 'type-' . Html::getClass($label);
$variables['attributes']['class'][] = $css_class;
}
}
}
}
@@ -33,16 +42,7 @@ function eql_preprocess_node(&$variables){
$type_protagoniste = $node->get('field_type_de_protagoniste')->getString();
$variables['attributes']['class'][] = 'type-de-protagoniste-' . $type_protagoniste;
}
// if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) {
// // Récupère la valeur de field_type_de_ressource
// $type_de_ressource_entity = $node->get('field_type_de_ressource')->entity;
// if ($type_de_ressource_entity) {
// $type_de_ressource_name = $type_de_ressource_entity->getName();
// // Ajoute la classe CSS basée sur la valeur du type de ressource
// $variables['attributes']['class'][] = 'type-de-ressource-' . Html::cleanCssIdentifier($type_de_ressource_name);
// }
// }
if ($node->getType() === 'ressource' && $node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) {
foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) {
$label = $term->label(); // ex: "Presse"
@@ -51,6 +51,26 @@ function eql_preprocess_node(&$variables){
}
}
}
function eql_preprocess_page(array &$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface && $node->bundle() === 'ressource') {
if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) {
foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) {
$label = $term->label();
$css_class = 'type-' . \Drupal\Component\Utility\Html::getClass($label);
// S'assurer que les attributs existent
if (!isset($variables['page']['top']['#attributes'])) {
$variables['page']['top']['#attributes'] = ['class' => []];
}
$variables['page']['top']['#attributes']['class'][] = $css_class;
}
}
}
}
function eql_preprocess_field(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
@@ -76,6 +96,7 @@ function eql_preprocess_field(&$variables) {
function eql_preprocess_layout__threecol_25_50_25(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if($node->gettype() == "projet"){
$variables['content']['top_bottom'] = []; /////// déclare les nvx array
$variables['content']['top_right'] = [];
@@ -102,39 +123,27 @@ function eql_preprocess_layout__threecol_25_50_25(&$variables) {
}
}
}
if ($node && $node->getType() === 'ressource') {
if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) {
$terms = $node->get('field_type_de_ressource')->referencedEntities();
if (!empty($terms)) {
$label = $terms[0]->label();
$css_class = 'type-' . Html::cleanCssIdentifier(strtolower($label));
// Appliquer cette classe à la région "top"
if (!isset($variables['region_attributes']['top'])) {
$variables['region_attributes']['top'] = new \Drupal\Core\Template\Attribute();
}
$variables['region_attributes']['top']->addClass($css_class);
}
}
}
}
// function eql_preprocess_views_view_unformatted(&$variables) {
// // On utilise le service de translittération de Drupal
// $transliterator = \Drupal::service('transliteration');
// foreach ($variables['rows'] as &$row) {
// if (isset($row['content']['#node'])) {
// $node = $row['content']['#node'];
// if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) {
// foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) {
// $label = $term->label();
// // Supprimer les accents
// $label_ascii = $transliterator->transliterate($label);
// // Nettoyer pour que ce soit une classe CSS valide
// $class = 'type-' . Html::cleanCssIdentifier(strtolower($label_ascii));
// $row['attributes']->addClass($class);
// }
// }
// }
// }
// }
function eql_preprocess_views_view_unformatted(array &$variables) {
$view = $variables['view'];
+77
View File
@@ -83,6 +83,7 @@ jQuery(function ($) {
});
///// fusion views-type-slide de class identique ////////////
@@ -180,3 +181,79 @@ jQuery(function ($) {
}
});
/////////////////diaporama ressource //////////
document.addEventListener('DOMContentLoaded', function () {
// Attendre que les éléments HTML soient bien présents
const interval = setInterval(() => {
const mainImage = document.getElementById('mainImage');
const prevArrow = document.getElementById('prevArrow');
const nextArrow = document.getElementById('nextArrow');
const caption = document.getElementById('caption');
const thumbsContainer = document.getElementById('thumbnails');
const imagesInDom = document.querySelectorAll('.carousel-items .carousel-item img');
if (mainImage && prevArrow && nextArrow && caption && thumbsContainer && imagesInDom) {
clearInterval(interval); // Tous les éléments sont là, on lance le carrousel
initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer });
}
}, 100); // vérifie toutes les 100ms
});
function initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer }) {
const images = [];
document.querySelectorAll('.carousel-items .carousel-item img').forEach((img) => {
images.push({
src: img.getAttribute('src'),
caption: img.getAttribute('alt') || 'Image sans légende'
});
});
console.log('Images chargées pour le carrousel :', images);
if (!images.length) return;
let currentIndex = 0;
function showImage(index) {
mainImage.src = images[index].src;
caption.textContent = images[index].caption;
const thumbnails = document.querySelectorAll('.thumbnails img');
thumbnails.forEach(img => img.classList.remove('active'));
if (thumbnails[index]) {
thumbnails[index].classList.add('active');
}
}
prevArrow.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + images.length) % images.length;
showImage(currentIndex);
});
nextArrow.addEventListener('click', () => {
currentIndex = (currentIndex + 1) % images.length;
showImage(currentIndex);
});
images.forEach((img, index) => {
const thumb = document.createElement('img');
thumb.src = img.src;
thumb.alt = img.caption;
thumb.onclick = () => {
currentIndex = index;
showImage(index);
};
thumbsContainer.appendChild(thumb);
});
showImage(currentIndex);
const thumbPrev = document.getElementById('thumbPrev');
const thumbNext = document.getElementById('thumbNext');
thumbPrev.addEventListener('click', () => {
thumbsContainer.scrollBy({ left: -150, behavior: 'smooth' });
});
thumbNext.addEventListener('click', () => {
thumbsContainer.scrollBy({ left: 150, behavior: 'smooth' });
});
}
@@ -0,0 +1,147 @@
.page-node-type-ressource{
.type-les-projets-en-images .block-region-top{
display: flex !important;
flex-direction: column;
margin-left: 11%;
@media screen and (min-width:1100px) {
display: flex;
}
.block {
margin-left: 0;
}
.block-entity-fieldnodefield-images{
padding: 0;
order: 7;
.carousel {
max-width: 60vw;
margin: auto;
text-align: center;
.main-image-container {
position: relative;
// background: #e0f5ff;
height: 500px;
max-height: 500px;
overflow: hidden;
width: 100%;
object-fit: contain;
img {
width: 100%;
height: 100%;
object-fit: contain;
transition: transform 0.3s ease-in-out;
// transition: opacity 0.4s ease-in-out; // à réactiver si fade souhaité
&.animate {
transform: scale(1.02); // léger effet smooth sur changement
}
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: #00aaff;
border-radius: 50%;
padding: 5px 10px;
color: white;
cursor: pointer;
content
&.left {
left: 10px;
}
&.right {
right: 10px;
}
}
// #prevArrow{
// &::before{
// content:url("../images/pictos/fleche-droite-dans-rond.png");
// display: block;
// transform: scaleX(-1);
// width: 50px;
// }
// }
// #nextArrow{
// &::before{
// content:url("../images/pictos/fleche-droite-dans-rond.png");
// display: block;
// }
// }
}
.caption {
margin-top: 10px;
font-family: sans-serif;
}
.thumbnails-wrapper {
position: relative;
max-width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
.thumb-arrow {
cursor: pointer;
padding: 5px 10px;
background: #00aaff;
color: white;
border-radius: 50%;
user-select: none;
z-index: 2;
// font-weight: bold;
&.left {
margin-right: 10px;
}
&.right {
margin-left: 10px;
}
}
.thumbnails {
display: flex;
gap: 10px;
overflow-x: auto;
scroll-behavior: smooth;
max-width: 100%;
padding: 10px 0;
scrollbar-width: none; // Firefox
&::-webkit-scrollbar {
display: none; // Chrome, Safari
}
img {
width: 60px;
height: 60px;
object-fit: cover;
border: 2px solid transparent;
cursor: pointer;
&.active {
border-color: #00aaff;
}
}
}
}
}
// Masquer les images Drupal originales (facultatif)
.field__items {
display: none;
}
}
}
// }
}
@@ -10,6 +10,7 @@
@media (max-width: 550px) {
padding-top: 0rem;
}
.block-region-top{
display: flex;
flex-direction: column;
@@ -18,27 +19,31 @@
grid-template-columns: 1fr 2fr; /* 1/3 pour l'image, 2/3 pour le contenu */
gap: 0.5rem;
}
.block-entity-fieldnodefield-images{
.block-entity-fieldnodefield-images {
width: fit-content;
// padding-right: 2rem;
padding-left: 25%;
@media screen and (min-width:1100px) {
grid-column: 1;
grid-row: 1 /span 7; /* Prendre toutes les lignes disponibles */
align-self: start; /* S'assurer qu'il commence en haut */
justify-self: end;
margin-left: 2rem;
@media (min-width: 1100px) {
grid-column: 1;
grid-row: 1 / span 7;
align-self: start;
justify-self: end;
margin-left: 2rem;
}
@media (max-width: 1100px) {
padding-left: 13%;
padding-left: 13%;
}
@media (max-width: 550px) {
width: 100vw;
padding: 0;
width: 100vw;
padding: 0;
}
}
}
.block-block-content4e5df355-e76c-4e44-bec0-e211d94f2640,
.block-entity-fieldnodefield-type-de-ressource,
.block-entity-fieldnodetitle,
@@ -164,6 +169,8 @@
}
.block-region-top:has(.type-de-media-video)
.block-region-top:has(.type-de-media-video){
}
@@ -181,6 +188,7 @@
display: none;
}
}
.layout__region--first{ // menu ancres a gauche
margin-top: 3rem;
position: relative;
@@ -346,7 +346,7 @@
h3.type-les-projets-en-images {
width: 80%;
border-top: solid 2px rgba(0, 0, 0, 0.3);
padding-top: 4rem;
padding-top: 4 rem;
&:before{
content:url("../images/pictos/picto-ressource-projetsimages.svg");
padding-right: 1rem;
+1
View File
@@ -53,6 +53,7 @@
@import "pages/_incubateur";
@import "pages/_lincubateur_newpage";
@import "pages/ressources";
@import "pages/ressource-type-en-images";
@@ -0,0 +1,61 @@
{#
/**
* @file
* Theme override to display a block.
*
* Available variables:
* - plugin_id: The ID of the block implementation.
* - label: The configured label of the block if visible.
* - configuration: A list of the block's configuration values.
* - label: The configured label for the block.
* - label_display: The display settings for the label.
* - provider: The module or other provider that provided this block plugin.
* - Block plugin specific settings will also be stored here.
* - content: The content of this block.
* - attributes: array of HTML attributes populated by modules, intended to
* be added to the main container tag of this template.
* - id: A valid HTML ID and guaranteed unique.
* - title_attributes: Same as attributes, except applied to the main title
* 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.
*
* @see template_preprocess_block()
*/
#}
{%
set classes = [
'block',
'block-' ~ configuration.provider|clean_class,
'block-' ~ plugin_id|clean_class,
]
%}
<div{{ attributes.addClass(classes) }}>
{{ title_prefix }}
{% if label %}
{# <video autoplay muted loop id="myVideo">
<source src="rain.mp4" type="video/mp4">
</video> #}
<span><h2{{ title_attributes }}>{{ label }}</h2></span>
{% endif %}
{{ title_suffix }}
{% block content %}
<div class="carousel">
<div class="main-image-container">
<div class="arrow left" id="prevArrow">←</div>
<img id="mainImage" src="" alt="Image principale">
<div class="arrow right" id="nextArrow">→</div>
</div>
<div class="caption" id="caption"></div>
<div class="thumbnails-wrapper">
<div class="thumb-arrow left" id="thumbPrev">←</div>
<div class="thumbnails" id="thumbnails"></div>
<div class="thumb-arrow right" id="thumbNext">→</div>
</div> </div>
{{ content }}
{% endblock %}
</div>
@@ -0,0 +1,86 @@
{#
/**
* @file
* Theme override 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()
*/
#}
{%
set classes = [
'field',
'field--name-' ~ field_name|clean_class,
'field--type-' ~ field_type|clean_class,
'field--label-' ~ label_display,
label_display == 'inline' ? 'clearfix',
]
%}
{%
set title_classes = [
'field__label',
label_display == 'visually_hidden' ? 'visually-hidden',
]
%}
{% if label_hidden %}
{% if multiple %}
<div{{ attributes.addClass(classes, 'field__items', 'carousel-items') }}>
{% for item in items %}
<div{{ item.attributes.addClass('field__item', 'carousel-item') }}>{{ item.content }}</div>
{% endfor %}
</div>
{% else %}
{% for item in items %}
<div {{ attributes.addClass(classes, 'field__item') }}>{{ item.content }}</div>
{% endfor %}
{% endif %}
{% else %}
<div{{ attributes.addClass(classes) }}>
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% if multiple %}
<div class="field__items">
{% endif %}
{% for item in items %}
<div{{ item.attributes.addClass('field__item', 'carousel-item') }}>{{ item.content }}</div>
{% endfor %}
{% if multiple %}
</div>
{% endif %}
</div>
{% endif %}
@@ -22,7 +22,9 @@
{% if content %}
<div{{ attributes.addClass(classes) }}>
{% if content.top %}
<div {{ region_attributes.top.addClass('layout__region', 'layout__region--top') }}>
<div{{ region_attributes.top.addClass('layout__region', 'layout__region--top') }}>
{# <div {{ region_attributes.top.addClass('layout__region', 'layout__region--top') }}> #}
{{content.top}}
<div class='top_top'>
{{ content.top_left }}