From c949b4ae36c318ec6a76f331c82b536a3ea30686 Mon Sep 17 00:00:00 2001 From: Liam Morland <liam@openplus.ca> Date: Wed, 15 Jan 2025 16:29:18 -0500 Subject: [PATCH 1/3] Issue #2789105 by liam morland: Make TOC title wrapper element configurable --- config/install/toc_api.toc_type.default.yml | 1 + config/install/toc_api.toc_type.full.yml | 1 + .../install/toc_api.toc_type.full_numbered.yml | 1 + config/install/toc_api.toc_type.simple.yml | 1 + .../install/toc_api.toc_type.simple_numbered.yml | 1 + config/schema/toc_api.toc_type.schema.yml | 3 +++ src/TocTypeForm.php | 16 ++++++++++++++++ templates/toc-tree.html.twig | 4 +++- 8 files changed, 27 insertions(+), 1 deletion(-) diff --git a/config/install/toc_api.toc_type.default.yml b/config/install/toc_api.toc_type.default.yml index 705ec78..e28d547 100644 --- a/config/install/toc_api.toc_type.default.yml +++ b/config/install/toc_api.toc_type.default.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + title_wrapper: h3 top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full.yml b/config/install/toc_api.toc_type.full.yml index dd671e8..6a24b5f 100644 --- a/config/install/toc_api.toc_type.full.yml +++ b/config/install/toc_api.toc_type.full.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + title_wrapper: h3 top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full_numbered.yml b/config/install/toc_api.toc_type.full_numbered.yml index 61961c7..4906130 100644 --- a/config/install/toc_api.toc_type.full_numbered.yml +++ b/config/install/toc_api.toc_type.full_numbered.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + title_wrapper: h3 top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple.yml b/config/install/toc_api.toc_type.simple.yml index 20bfad3..122dde5 100644 --- a/config/install/toc_api.toc_type.simple.yml +++ b/config/install/toc_api.toc_type.simple.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + title_wrapper: h3 top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple_numbered.yml b/config/install/toc_api.toc_type.simple_numbered.yml index bcccb13..cc3f537 100644 --- a/config/install/toc_api.toc_type.simple_numbered.yml +++ b/config/install/toc_api.toc_type.simple_numbered.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + title_wrapper: h3 top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/schema/toc_api.toc_type.schema.yml b/config/schema/toc_api.toc_type.schema.yml index 19bdb58..7197e2b 100644 --- a/config/schema/toc_api.toc_type.schema.yml +++ b/config/schema/toc_api.toc_type.schema.yml @@ -92,3 +92,6 @@ toc_api.toc_type.*: type: ignore h6: type: ignore + title_wrapper: + type: string + label: 'Title wrapper' diff --git a/src/TocTypeForm.php b/src/TocTypeForm.php index 9c1012e..7ba4d6c 100644 --- a/src/TocTypeForm.php +++ b/src/TocTypeForm.php @@ -141,6 +141,12 @@ class TocTypeForm extends EntityForm { '#type' => 'textfield', '#default_value' => $options['title'], ]; + $form['options']['general']['title_wrapper'] = [ + '#title' => $this->t('Wrapper element for title'), + '#type' => 'textfield', + '#default_value' => $options['title_wrapper'] ?? 'h3', + '#required' => TRUE, + ]; // Hide block option since it is up to TOC submodule to decide how to // support it. $form['options']['general']['block'] = [ @@ -335,6 +341,16 @@ class TocTypeForm extends EntityForm { return $form; } + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state): void { + $title_wrapper = $form_state->getValue(['general', 'title_wrapper']); + if (!preg_match('/^[a-zA-Z0-9-]+$/', $title_wrapper)) { + $form_state->setErrorByName('general][title_wrapper', $this->t('Invalid HTML tag name.')); + } + } + /** * {@inheritdoc} */ diff --git a/templates/toc-tree.html.twig b/templates/toc-tree.html.twig index 692ae77..0df74a4 100644 --- a/templates/toc-tree.html.twig +++ b/templates/toc-tree.html.twig @@ -6,6 +6,7 @@ * Returns HTML for a nested list representation of a Table of contents.. * * Available variables: + * - options: An array of configuration options. * - tree: A nested list of header items. Each header item contains: * - list_tag: HTML tag for the list. * - list_attributes: HTML attributes for the list. @@ -27,7 +28,8 @@ <div{{ attributes.addClass(classes) }}> {% if tree.title and not options.block %} - <h3>{{ tree.title }}</h3> + {% set title_wrapper = options.title_wrapper ?? 'h3' %} + <{{ title_wrapper }}>{{ tree.title }}</{{ title_wrapper }}> {% endif %} {{ toc_api_tree.tree_links(tree) }} -- GitLab From 1b0809e4fc0f091911105359134a18d265ee6a34 Mon Sep 17 00:00:00 2001 From: Liam Morland <liam@openplus.ca> Date: Thu, 16 Jan 2025 11:00:58 -0500 Subject: [PATCH 2/3] Issue #2789105 by liam morland: Make TOC wrapper element configurable --- config/install/toc_api.toc_type.default.yml | 1 + config/install/toc_api.toc_type.full.yml | 1 + .../toc_api.toc_type.full_numbered.yml | 1 + config/install/toc_api.toc_type.simple.yml | 1 + .../toc_api.toc_type.simple_numbered.yml | 1 + config/schema/toc_api.toc_type.schema.yml | 3 +++ src/TocTypeForm.php | 19 ++++++++++++++++--- templates/toc-tree.html.twig | 5 +++-- 8 files changed, 27 insertions(+), 5 deletions(-) diff --git a/config/install/toc_api.toc_type.default.yml b/config/install/toc_api.toc_type.default.yml index e28d547..e4dddc2 100644 --- a/config/install/toc_api.toc_type.default.yml +++ b/config/install/toc_api.toc_type.default.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + wrapper: div title_wrapper: h3 top_label: 'Back to top' top_min: 2 diff --git a/config/install/toc_api.toc_type.full.yml b/config/install/toc_api.toc_type.full.yml index 6a24b5f..9218b85 100644 --- a/config/install/toc_api.toc_type.full.yml +++ b/config/install/toc_api.toc_type.full.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + wrapper: div title_wrapper: h3 top_label: 'Back to top' top_min: 2 diff --git a/config/install/toc_api.toc_type.full_numbered.yml b/config/install/toc_api.toc_type.full_numbered.yml index 4906130..5bfcace 100644 --- a/config/install/toc_api.toc_type.full_numbered.yml +++ b/config/install/toc_api.toc_type.full_numbered.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + wrapper: div title_wrapper: h3 top_label: 'Back to top' top_min: 2 diff --git a/config/install/toc_api.toc_type.simple.yml b/config/install/toc_api.toc_type.simple.yml index 122dde5..c4f6a31 100644 --- a/config/install/toc_api.toc_type.simple.yml +++ b/config/install/toc_api.toc_type.simple.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + wrapper: div title_wrapper: h3 top_label: 'Back to top' top_min: 2 diff --git a/config/install/toc_api.toc_type.simple_numbered.yml b/config/install/toc_api.toc_type.simple_numbered.yml index cc3f537..9ad46c2 100644 --- a/config/install/toc_api.toc_type.simple_numbered.yml +++ b/config/install/toc_api.toc_type.simple_numbered.yml @@ -14,6 +14,7 @@ options: header_id: title header_id_prefix: section header_exclude_xpath: '' + wrapper: div title_wrapper: h3 top_label: 'Back to top' top_min: 2 diff --git a/config/schema/toc_api.toc_type.schema.yml b/config/schema/toc_api.toc_type.schema.yml index 7197e2b..7500d66 100644 --- a/config/schema/toc_api.toc_type.schema.yml +++ b/config/schema/toc_api.toc_type.schema.yml @@ -92,6 +92,9 @@ toc_api.toc_type.*: type: ignore h6: type: ignore + wrapper: + type: string + label: 'Wrapper element' title_wrapper: type: string label: 'Title wrapper' diff --git a/src/TocTypeForm.php b/src/TocTypeForm.php index 7ba4d6c..a7ae284 100644 --- a/src/TocTypeForm.php +++ b/src/TocTypeForm.php @@ -147,6 +147,12 @@ class TocTypeForm extends EntityForm { '#default_value' => $options['title_wrapper'] ?? 'h3', '#required' => TRUE, ]; + $form['options']['general']['wrapper'] = [ + '#title' => $this->t('Wrapper element for table of contents'), + '#type' => 'textfield', + '#default_value' => $options['wrapper'] ?? 'div', + '#required' => TRUE, + ]; // Hide block option since it is up to TOC submodule to decide how to // support it. $form['options']['general']['block'] = [ @@ -345,9 +351,16 @@ class TocTypeForm extends EntityForm { * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state): void { - $title_wrapper = $form_state->getValue(['general', 'title_wrapper']); - if (!preg_match('/^[a-zA-Z0-9-]+$/', $title_wrapper)) { - $form_state->setErrorByName('general][title_wrapper', $this->t('Invalid HTML tag name.')); + // Validate HTML tag names. + $elements = [ + 'title_wrapper', + 'wrapper', + ]; + foreach ($elements as $element) { + $tag_name = $form_state->getValue(['general', $element]); + if (!preg_match('/^[a-zA-Z0-9-]+$/', $tag_name)) { + $form_state->setErrorByName('general][' . $element, $this->t('Invalid HTML tag name.')); + } } } diff --git a/templates/toc-tree.html.twig b/templates/toc-tree.html.twig index 0df74a4..0f3c593 100644 --- a/templates/toc-tree.html.twig +++ b/templates/toc-tree.html.twig @@ -25,7 +25,8 @@ {% import _self as toc_api_tree %} {% set classes = ['toc', 'toc-tree'] %} -<div{{ attributes.addClass(classes) }}> +{% set wrapper = options.wrapper ?? 'div' %} +<{{ wrapper }}{{ attributes.addClass(classes) }}> {% if tree.title and not options.block %} {% set title_wrapper = options.title_wrapper ?? 'h3' %} @@ -34,7 +35,7 @@ {{ toc_api_tree.tree_links(tree) }} -</div> +</{{ wrapper }}> {% macro tree_links(item) %} {% import _self as toc_api_tree %} -- GitLab From 937dedd4814abbce67394af425b4895b7c9f81a7 Mon Sep 17 00:00:00 2001 From: Liam Morland <liam@openplus.ca> Date: Thu, 16 Jan 2025 13:10:14 -0500 Subject: [PATCH 3/3] Issue #2789105 by liam morland: Allow toc-tree classes to be customized in preprocess --- templates/toc-tree.html.twig | 3 +-- toc_api.module | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/toc-tree.html.twig b/templates/toc-tree.html.twig index 0f3c593..e582d62 100644 --- a/templates/toc-tree.html.twig +++ b/templates/toc-tree.html.twig @@ -23,10 +23,9 @@ @see http://twig.sensiolabs.org/doc/tags/macro.html #} {% import _self as toc_api_tree %} -{% set classes = ['toc', 'toc-tree'] %} {% set wrapper = options.wrapper ?? 'div' %} -<{{ wrapper }}{{ attributes.addClass(classes) }}> +<{{ wrapper }}{{ attributes }}> {% if tree.title and not options.block %} {% set title_wrapper = options.title_wrapper ?? 'h3' %} diff --git a/toc_api.module b/toc_api.module index cdd60e1..012f1ea 100755 --- a/toc_api.module +++ b/toc_api.module @@ -118,6 +118,11 @@ function template_preprocess_toc_tree(&$variables) { $variables['options'] = $toc->getOptions(); + // Add default classes. + $variables['attributes']['class'] = (array) $variables['attributes']['class']; + $variables['attributes']['class'][] = 'toc'; + $variables['attributes']['class'][] = 'toc-tree'; + $variables['attributes'] = new Attribute($variables['attributes']); $variables['#attached']['library'][] = 'toc_api/toc.tree'; -- GitLab