diff --git a/config/sync/block.block.leshed_titre.yml b/config/sync/block.block.leshed_titre.yml deleted file mode 100644 index 89f0e36..0000000 --- a/config/sync/block.block.leshed_titre.yml +++ /dev/null @@ -1,29 +0,0 @@ -uuid: 013d1fb2-1c81-4b8b-93ca-0da2e401fd88 -langcode: fr -status: false -dependencies: - module: - - ctools_block - theme: - - leshed -id: leshed_titre -theme: leshed -region: content -weight: 0 -provider: null -plugin: 'entity_field:node:title' -settings: - id: 'entity_field:node:title' - label: Titre - label_display: '0' - provider: ctools_block - context_mapping: - entity: '@node.node_route_context:node' - formatter: - type: string - weight: 0 - label: above - settings: - link_to_entity: false - third_party_settings: { } -visibility: { } diff --git a/config/sync/block.block.leshed_titredelapage.yml b/config/sync/block.block.leshed_titredelapage.yml new file mode 100644 index 0000000..0f80e8e --- /dev/null +++ b/config/sync/block.block.leshed_titredelapage.yml @@ -0,0 +1,31 @@ +uuid: 60b89953-e159-4815-9c83-f51e13cb9518 +langcode: fr +status: true +dependencies: + module: + - context + - system + theme: + - leshed +id: leshed_titredelapage +theme: leshed +region: header_bottom +weight: -1 +provider: null +plugin: page_title_block +settings: + id: page_title_block + label: 'Titre de la page' + label_display: '0' + provider: core +visibility: + request_path: + id: request_path + negate: false + pages: "/projets/*\r\n/evenements/*" + view_inclusion: + id: view_inclusion + negate: false + view_inclusion: + view-archives-page_1: view-archives-page_1 + view-archives-page_2: view-archives-page_2 diff --git a/config/sync/core.entity_view_display.node.evenement.calendrier.yml b/config/sync/core.entity_view_display.node.evenement.calendrier.yml index 175bdf0..d2304f4 100644 --- a/config/sync/core.entity_view_display.node.evenement.calendrier.yml +++ b/config/sync/core.entity_view_display.node.evenement.calendrier.yml @@ -68,7 +68,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 1 region: content diff --git a/config/sync/core.entity_view_display.node.evenement.full.yml b/config/sync/core.entity_view_display.node.evenement.full.yml index 3d4f9dc..026b373 100644 --- a/config/sync/core.entity_view_display.node.evenement.full.yml +++ b/config/sync/core.entity_view_display.node.evenement.full.yml @@ -114,7 +114,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 1 region: content diff --git a/config/sync/core.entity_view_display.node.evenement.tableau_liste.yml b/config/sync/core.entity_view_display.node.evenement.tableau_liste.yml index ab18d2e..b4da35f 100644 --- a/config/sync/core.entity_view_display.node.evenement.tableau_liste.yml +++ b/config/sync/core.entity_view_display.node.evenement.tableau_liste.yml @@ -85,7 +85,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 3 region: content diff --git a/config/sync/core.entity_view_display.node.evenement.teaser.yml b/config/sync/core.entity_view_display.node.evenement.teaser.yml index a86ba78..ab7d553 100644 --- a/config/sync/core.entity_view_display.node.evenement.teaser.yml +++ b/config/sync/core.entity_view_display.node.evenement.teaser.yml @@ -87,7 +87,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 3 region: content diff --git a/config/sync/core.entity_view_display.node.projet.full.yml b/config/sync/core.entity_view_display.node.projet.full.yml index fc30e21..0d801f1 100644 --- a/config/sync/core.entity_view_display.node.projet.full.yml +++ b/config/sync/core.entity_view_display.node.projet.full.yml @@ -39,7 +39,7 @@ content: label: hidden settings: { } third_party_settings: { } - weight: 3 + weight: 5 region: content field_artiste_s_invite_s: type: entity_reference_label @@ -66,7 +66,7 @@ content: settings: use_description_as_link_text: true third_party_settings: { } - weight: 7 + weight: 9 region: content field_images: type: image_caption @@ -77,7 +77,14 @@ content: image_loading: attribute: lazy third_party_settings: { } - weight: 8 + weight: 10 + region: content + field_infos_pratiques: + type: text_default + label: above + settings: { } + third_party_settings: { } + weight: 4 region: content field_invite_accompagne_curate_p: type: entity_reference_label @@ -93,14 +100,14 @@ content: settings: link: false third_party_settings: { } - weight: 4 + weight: 6 region: content field_portage: type: list_default label: above settings: { } third_party_settings: { } - weight: 5 + weight: 7 region: content field_projet_s_lie_s: type: entity_reference_label @@ -108,11 +115,17 @@ content: settings: link: true third_party_settings: { } - weight: 6 + weight: 8 + region: content + field_type_de_projet: + type: entity_reference_label + label: hidden + settings: + link: true + third_party_settings: { } + weight: 3 region: content hidden: - field_infos_pratiques: true - field_type_de_projet: true langcode: true links: true search_api_excerpt: true diff --git a/config/sync/core.entity_view_display.node.projet.tableau_liste.yml b/config/sync/core.entity_view_display.node.projet.tableau_liste.yml index 69786db..2c3203d 100644 --- a/config/sync/core.entity_view_display.node.projet.tableau_liste.yml +++ b/config/sync/core.entity_view_display.node.projet.tableau_liste.yml @@ -77,7 +77,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 3 region: content diff --git a/config/sync/core.entity_view_display.node.projet.teaser.yml b/config/sync/core.entity_view_display.node.projet.teaser.yml index 2b38889..660b6d8 100644 --- a/config/sync/core.entity_view_display.node.projet.teaser.yml +++ b/config/sync/core.entity_view_display.node.projet.teaser.yml @@ -67,7 +67,7 @@ content: type: entity_reference_label label: hidden settings: - link: false + link: true third_party_settings: { } weight: 2 region: content diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 1d8f587..f668f63 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -60,6 +60,7 @@ module: language: 0 layout_builder: 0 layout_discovery: 0 + leshed_helpers: 0 leshed_svg_export: 0 link: 0 link_attributes: 0 diff --git a/config/sync/views.view.archives.yml b/config/sync/views.view.archives.yml index 94989c9..df4e0c1 100644 --- a/config/sync/views.view.archives.yml +++ b/config/sync/views.view.archives.yml @@ -10,9 +10,11 @@ dependencies: - node.type.projet - system.menu.main module: + - better_exposed_filters - datetime - datetime_range - node + - taxonomy - user id: archives label: Archives @@ -40,7 +42,7 @@ display: options: offset: 0 exposed_form: - type: basic + type: bef options: submit_button: Appliquer reset_button: false @@ -49,6 +51,31 @@ display: expose_sort_order: true sort_asc_label: Asc sort_desc_label: Desc + text_input_required: 'Sélectionner un filtre et cliquer sur Appliquer pour voir les résultats' + text_input_required_format: wysiwyg + bef: + general: + autosubmit: true + autosubmit_exclude_textfield: false + autosubmit_textfield_delay: 500 + autosubmit_hide: true + input_required: false + allow_secondary: false + secondary_label: 'Options avancées' + secondary_open: false + reset_button_always_show: false + filter: + field_type_de_projet_target_id: + plugin_id: bef_links + advanced: + sort_options: false + rewrite: + filter_rewrite_values: '' + filter_rewrite_values_key: false + collapsible: false + collapsible_disable_automatic_open: false + is_secondary: false + select_all_none: false access: type: perm options: @@ -238,6 +265,43 @@ display: multi_type: separator separator: ', ' field_api_classes: false + arguments: + tid: + id: tid + table: taxonomy_index + field: tid + relationship: none + group_type: group + admin_label: '' + plugin_id: taxonomy_index_tid + default_action: ignore + exception: + value: all + title_enable: false + title: All + title_enable: true + title: 'Les projets | {{ arguments.tid }}' + default_argument_type: fixed + default_argument_options: + argument: '' + summary_options: + base_path: '' + count: true + override: false + items_per_page: 25 + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + add_table: false + require_value: false + reduce_duplicates: false filters: status: id: status @@ -318,10 +382,12 @@ display: style: false row: false fields: false + arguments: false filters: false filter_groups: false css_class: 'views-archives views-archives-projets' display_description: '' + exposed_block: true display_extenders: { } path: projets menu: @@ -338,6 +404,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' + - url - 'user.node_grants:view' - user.permissions tags: { } @@ -415,6 +482,43 @@ display: multi_type: separator separator: ', ' field_api_classes: false + arguments: + tid: + id: tid + table: taxonomy_index + field: tid + relationship: none + group_type: group + admin_label: '' + plugin_id: taxonomy_index_tid + default_action: ignore + exception: + value: all + title_enable: false + title: All + title_enable: true + title: 'Les événements | {{ arguments.tid }}' + default_argument_type: fixed + default_argument_options: + argument: '' + summary_options: + base_path: '' + count: true + override: false + items_per_page: 25 + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + add_table: false + require_value: false + reduce_duplicates: false filters: status: id: status @@ -495,6 +599,7 @@ display: style: false row: false fields: false + arguments: false filters: false filter_groups: false css_class: 'views-archives views-archives-evenements' @@ -515,6 +620,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' + - url - 'user.node_grants:view' - user.permissions tags: diff --git a/web/modules/custom/leshed_helpers/leshed_helpers.info.yml b/web/modules/custom/leshed_helpers/leshed_helpers.info.yml new file mode 100644 index 0000000..9b62605 --- /dev/null +++ b/web/modules/custom/leshed_helpers/leshed_helpers.info.yml @@ -0,0 +1,7 @@ +type: module +name: 'Le Shed Helpers' +description: 'Comportements serveur et helpers pour le site Le Shed (alias de taxonomie, reecriture de liens, etc.).' +package: leshed +core_version_requirement: '^10.5 || ^11' +dependencies: + - pathauto:pathauto diff --git a/web/modules/custom/leshed_helpers/leshed_helpers.module b/web/modules/custom/leshed_helpers/leshed_helpers.module new file mode 100644 index 0000000..791667b --- /dev/null +++ b/web/modules/custom/leshed_helpers/leshed_helpers.module @@ -0,0 +1,64 @@ + 'projets', + 'type_d_evenement' => 'evenements', +]; + +/** + * Crée ou met à jour l'alias d'URL pour les termes des vocabulaires gérés. + */ +function leshed_helpers_taxonomy_term_insert(EntityInterface $entity) { + leshed_helpers_ensure_term_alias($entity); +} + +function leshed_helpers_taxonomy_term_update(EntityInterface $entity) { + leshed_helpers_ensure_term_alias($entity); +} + +function leshed_helpers_ensure_term_alias(EntityInterface $entity) { + if (!($entity instanceof TermInterface)) { + return; + } + + $vid = $entity->bundle(); + if (!isset(LESHED_HELPERS_VOCABULARIES[$vid])) { + return; + } + + $base_path = LESHED_HELPERS_VOCABULARIES[$vid]; + $tid = $entity->id(); + $cleaner = \Drupal::service('pathauto.alias_cleaner'); + $slug = $cleaner->cleanString($entity->label()); + $alias_path = '/' . $base_path . '/' . $slug; + $internal_path = '/' . $base_path . '/' . $tid; + + $storage = \Drupal::entityTypeManager()->getStorage('path_alias'); + $langcode = $entity->language()->getId(); + + // Supprime l'ancien alias s'il existe (par internal path). + $existing = $storage->loadByProperties(['path' => $internal_path, 'langcode' => $langcode]); + foreach ($existing as $old) { + $old->delete(); + } + + $storage->create([ + 'path' => $internal_path, + 'alias' => $alias_path, + 'langcode' => $langcode, + ])->save(); +} diff --git a/web/themes/custom/leshed/assets/scss/main.scss b/web/themes/custom/leshed/assets/scss/main.scss index a967411..da21e7f 100644 --- a/web/themes/custom/leshed/assets/scss/main.scss +++ b/web/themes/custom/leshed/assets/scss/main.scss @@ -271,6 +271,11 @@ $variable-title-selectors: ( } +div#block-leshed-titredelapage h1{ + font-size: 1em; + font-weight: $default_fwght; + margin: 0; +} @@ -649,6 +654,22 @@ div.views-archives-projets{ } } +form#views-exposed-form-archives-page-1{ + div.bef-links{ + ul{ + margin:0; padding:0; + display: flex; + flex-direction: row; + flex-wrap: wrap; + li{ + list-style: none; + flex: 0 1 auto; + padding: 0.2em 0.5em; + font-size: 0.756em; + } + } + } +} // __ ___ _ _ _ _____ _ // \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | ____|_ _____ _ __ ___ _ __ ___ ___ _ __ | |_ ___ diff --git a/web/themes/custom/leshed/leshed.theme b/web/themes/custom/leshed/leshed.theme index 0b825b8..e2d0b41 100644 --- a/web/themes/custom/leshed/leshed.theme +++ b/web/themes/custom/leshed/leshed.theme @@ -50,6 +50,45 @@ function leshed_preprocess_page(&$variables) { } +/** + * Rend le titre de base cliquable vers la vue non filtrée sur les pages + * /projets/{term} et /evenements/{term}. Le titre de la vue est "Les Projets" + * ou "Les Événements | Concert" : on sépare sur " | " et on rend la première + * partie en lien vers /projets ou /evenements. + */ +function leshed_preprocess_page_title(&$variables) { + $route_name = \Drupal::routeMatch()->getRouteName(); + $base_paths = [ + 'view.archives.page_1' => '/projets', + 'view.archives.page_2' => '/evenements', + ]; + if (!isset($base_paths[$route_name])) { + return; + } + + $title = $variables['title'] ?? ''; + if (is_array($title)) { + $title = \Drupal::service('renderer')->render($title); + } + $title = (string) $title; + if (empty($title)) { + return; + } + + $parts = explode(' | ', $title, 2); + if (count($parts) < 2) { + return; + } + + $base_title = $parts[0]; + $term_part = $parts[1]; + $base_url = \Drupal\Core\Url::fromUserInput($base_paths[$route_name]); + + $variables['title'] = [ + '#markup' => '' . \Drupal\Component\Utility\Html::escape($base_title) . ' | ' . \Drupal\Component\Utility\Html::escape($term_part), + ]; +} + function leshed_preprocess_region(&$variables) { if (!isset($variables["attributes"]['class'])) { $variables["attributes"]['class'] = []; @@ -152,6 +191,38 @@ function leshed_preprocess_field(&$variables) { } } } + + // Réécrit les liens des termes type_de_projet vers la vue projets filtrée + // par filtre contextuel. Drupal résout automatiquement l'alias + // (/projets/1 -> /projets/expo) depuis la table path_alias. + if ($variables['field_name'] === 'field_type_de_projet') { + foreach ($variables['items'] as &$item) { + $content = &$item['content']; + if (isset($content['#type']) && $content['#type'] === 'link' && isset($content['#url'])) { + /** @var \Drupal\taxonomy\TermInterface $term */ + $term = $content['#entity'] ?? NULL; + if ($term && $term->bundle() === 'type_de_projet') { + $content['#url'] = \Drupal\Core\Url::fromUserInput('/projets/' . $term->id()); + } + } + } + } + + // Réécrit les liens des termes type_d_evenement vers la vue evenements + // filtrée par filtre contextuel. Drupal résout automatiquement l'alias + // (/evenements/14 -> /evenements/concert) depuis la table path_alias. + if ($variables['field_name'] === 'field_type_d_evenement') { + foreach ($variables['items'] as &$item) { + $content = &$item['content']; + if (isset($content['#type']) && $content['#type'] === 'link' && isset($content['#url'])) { + /** @var \Drupal\taxonomy\TermInterface $term */ + $term = $content['#entity'] ?? NULL; + if ($term && $term->bundle() === 'type_d_evenement') { + $content['#url'] = \Drupal\Core\Url::fromUserInput('/evenements/' . $term->id()); + } + } + } + } } function leshed_preprocess_links__language_block(&$variables){