diff --git a/README.md b/README.md index a223d5cb1f4f7e6a6fa653b1e8ad534c3e300a50..de5d358a16b1f0471833a4c3039d12983b22715d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,17 @@ # The OpenEuropa Whitelabel theme +## Paragraphs + +The paragraphs below are not yet themed therefore not recommended for usage: + +- Contextual navigation +- Document + +Some paragraphs are considered "internal", and only meant to be used inside other paragraphs: + +- Listing item: To be used as item paragraph within 'Listing item block'. +- Fact: To be used as item paragraph within 'Facts and figures'. + ## Requirements This depends on the following software: @@ -18,7 +30,13 @@ composer require openeuropa/oe_whitelabel In order to enable the theme in your project perform the following steps: -- Enable the OpenEuropa Whitelabel Theme and set it as default ```./vendor/bin/drush config-set system.theme default oe_bootstrap_theme``` +- Enable the OpenEuropa Whitelabel Theme and set it as default ```./vendor/bin/drush config-set system.theme default oe_whitelabel_theme``` + +### Integration with oe_paragraphs + +In order to have full working integration with paragraphs in your project, you must enable oe_whitelabel_paragraphs module: + +```./vendor/bin/drush en oe_whitelabel_paragraphs``` ## Development setup @@ -129,3 +147,25 @@ To run the phpunit tests: ```bash docker-compose exec web ./vendor/bin/phpunit ``` + +## Upgrade from older versions + +### Upgrade to 1.0.0-alpha6 + +#### Paragraphs migration + +Paragraphs-related theming and functionality has been moved from the [OpenEuropa Bootstrap base theme](https://github.com/openeuropa/oe_bootstrap_theme) to [OpenEuropa Whitelabel](https://github.com/openeuropa/oe_whitelabel). + +Special paragraphs fields that were introduced in `oe_bootstrap_theme_paragraphs` are being renamed in `oe_whitelabel_paragraphs`. + +If you have the `oe_paragraphs` module enabled, you should create a `hook_post_update_NAME()` in your code, to enable the `oe_whitelabel_paragraphs` module during deployment. + +```php +function EXAMPLE_post_update_00001(): void { + \Drupal::service('module_installer')->install(['oe_whitelabel_paragraphs']); +} +``` + +This is needed to make sure that the install hook for `oe_whitelabel_paragraphs` runs _before_ config-import during a deployment. + +Note that `drush updb` will also trigger update hooks in `oe_bootstrap_theme_helper`, which will uninstall the legacy module `oe_bootstrap_theme_paragraphs`. diff --git a/composer.json b/composer.json index 0017f4492c9f30c1aec8593766a4b6ca1ee4fe3a..f8c79040962f39ad372fcc2ffe805bcf9f22e8aa 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,9 @@ "drupal/core-composer-scaffold": "^9.2", "drupal/core-dev": "^9.2", "drupal/ctools": "^3.7", + "drupal/description_list_field": "^1.0@alpha", "drupal/drupal-extension": "~4.1", - "drupal/file_link": "^2.0.4", + "drupal/file_link": "^2.0.6", "drupal/pathauto": "^1.8", "drupal/search_api": "^1.21", "drupal/search_api_autocomplete": "^1.5", @@ -36,7 +37,9 @@ "openeuropa/oe_contact_forms": "~1.1", "openeuropa/oe_content": "^2.8.0", "openeuropa/oe_corporate_blocks": "^4.4", + "openeuropa/oe_media": "^1.14", "openeuropa/oe_multilingual": "^1.9", + "openeuropa/oe_paragraphs": "^1.12", "openeuropa/oe_starter_content": "1.x-dev", "openeuropa/task-runner-drupal-project-symlink": "^1.0-beta5", "phpspec/prophecy-phpunit": "^1 || ^2", @@ -67,6 +70,11 @@ } } }, + "patches": { + "openeuropa/oe_bootstrap_theme" : { + "1.x latest": "https://github.com/openeuropa/oe_bootstrap_theme/compare/0.1.202203290731..1.x.diff" + } + }, "drupal-scaffold": { "locations": { "web-root": "./build" diff --git a/includes/paragraphs.inc b/includes/paragraphs.inc new file mode 100644 index 0000000000000000000000000000000000000000..5e2d923ad7a3aad721a432eed159156fa85b07cd --- /dev/null +++ b/includes/paragraphs.inc @@ -0,0 +1,21 @@ +<?php + +/** + * @file + * Theme functions for paragraphs. + */ + +declare(strict_types = 1); + +/** + * Implements hook_theme_suggestions_HOOK_alter(). + */ +function oe_whitelabel_theme_suggestions_paragraph_alter(array &$suggestions, array $variables): void { + /** @var \Drupal\paragraphs\ParagraphInterface $paragraph */ + $paragraph = $variables['elements']['#paragraph']; + + if ($paragraph->bundle() === 'oe_content_row') { + $variant = $paragraph->get('oe_paragraphs_variant')->first()->value; + $suggestions[] = 'paragraph__' . $paragraph->bundle() . '__variant_' . $variant; + } +} diff --git a/modules/oe_whitelabel_helper/oe_whitelabel_helper.install b/modules/oe_whitelabel_helper/oe_whitelabel_helper.install new file mode 100644 index 0000000000000000000000000000000000000000..f7f14615c47f6cc5b50191f9b4560d4f4ee4c162 --- /dev/null +++ b/modules/oe_whitelabel_helper/oe_whitelabel_helper.install @@ -0,0 +1,25 @@ +<?php + +/** + * @file + * Install and update functions for the OE Whitelabel Helper module. + */ + +declare(strict_types = 1); + +/** + * Implements hook_requirements(). + */ +function oe_whitelabel_helper_requirements($phase): array { + $requirements = []; + + if (\Drupal::moduleHandler()->moduleExists('oe_paragraphs') && !\Drupal::moduleHandler()->moduleExists('oe_whitelabel_paragraphs')) { + $requirements['oe_whitelabel_paragraphs'] = [ + 'title' => 'OpenEuropa Whitelabel Paragraphs', + 'description' => t('OpenEuropa Whitelabel Paragraphs is required if OpenEuropa Paragraphs is enabled.'), + 'severity' => REQUIREMENT_ERROR, + ]; + } + + return $requirements; +} diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_description_list.oe_w_orientation.yml b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_description_list.oe_w_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..1e4485067b688200c42911900ab62475a4b6bdb3 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_description_list.oe_w_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_w_orientation + - paragraphs.paragraphs_type.oe_description_list + module: + - options +id: paragraph.oe_description_list.oe_w_orientation +field_name: oe_w_orientation +entity_type: paragraph +bundle: oe_description_list +label: Orientation +description: 'Sets the orientation (vertical|horizontal) for the paragraph.' +required: true +translatable: false +default_value: + - + value: horizontal +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_facts_figures.oe_w_n_columns.yml b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_facts_figures.oe_w_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..0165929a535a538b03fa540f3e04559de6f79196 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_facts_figures.oe_w_n_columns.yml @@ -0,0 +1,24 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_w_n_columns + - paragraphs.paragraphs_type.oe_facts_figures +id: paragraph.oe_facts_figures.oe_w_n_columns +field_name: oe_w_n_columns +entity_type: paragraph +bundle: oe_facts_figures +label: 'Number of columns' +description: 'Sets the number of grid columns. Minimum number is 1 column and maximum is 3.' +required: false +translatable: false +default_value: + - + value: 1 +default_value_callback: '' +settings: + min: 1 + max: 3 + prefix: '' + suffix: '' +field_type: integer diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_background.yml b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..5ac9c7283d806caea21c96d50c30e23a1638478f --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_w_links_block_background + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_w_links_block_background +field_name: oe_w_links_block_background +entity_type: paragraph +bundle: oe_links_block +label: Background +description: 'Allows to select the background color of the links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..2b3bf721cd4d0977d63d9d4704a4de7bf6651abc --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_links_block.oe_w_links_block_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_w_links_block_orientation + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_w_links_block_orientation +field_name: oe_w_links_block_orientation +entity_type: paragraph +bundle: oe_links_block +label: Orientation +description: 'Allows to select the direction of the links block.' +required: false +translatable: false +default_value: + - + value: vertical +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_social_media_follow.oe_w_links_block_background.yml b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_social_media_follow.oe_w_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..2d8fae0997a07142a7c96abde650945242f4e174 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.field.paragraph.oe_social_media_follow.oe_w_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_w_links_block_background + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - options +id: paragraph.oe_social_media_follow.oe_w_links_block_background +field_name: oe_w_links_block_background +entity_type: paragraph +bundle: oe_social_media_follow +label: Background +description: 'Allows to select the background color of the Social Media Links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_background.yml b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..289994964b5e648b871e282b6401cc5eea15e1c2 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_background.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_w_links_block_background +field_name: oe_w_links_block_background +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: gray + label: Gray + - + value: transparent + label: Transparent + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..afdf66e7c4492520eca3363e353f96de3a01728d --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_links_block_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_w_links_block_orientation +field_name: oe_w_links_block_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: horizontal + label: Horizontal + - + value: vertical + label: Vertical + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_n_columns.yml b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..3a1a9cbc933ff4161eceafc3b82e011e6d27650e --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_n_columns.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - paragraphs +id: paragraph.oe_w_n_columns +field_name: oe_w_n_columns +entity_type: paragraph +type: integer +settings: + unsigned: false + size: normal +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_orientation.yml b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..f277e814004868e566513e2f99b0967d2353bc43 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/install/field.storage.paragraph.oe_w_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_w_orientation +field_name: oe_w_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: vertical + label: Vertical + - + value: horizontal + label: Horizontal + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_accordion_item.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_accordion_item.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..3b7368e64cbba5a66750ac514b72b55ba4be3d6d --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_accordion_item.default.yml @@ -0,0 +1,36 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_accordion_item.field_oe_icon + - field.field.paragraph.oe_accordion_item.field_oe_text + - field.field.paragraph.oe_accordion_item.field_oe_text_long + - paragraphs.paragraphs_type.oe_accordion_item + module: + - text +id: paragraph.oe_accordion_item.default +targetEntityType: paragraph +bundle: oe_accordion_item +mode: default +content: + field_oe_text: + weight: 0 + settings: + size: 60 + placeholder: '' + third_party_settings: { } + type: string_textfield + region: content + field_oe_text_long: + weight: 1 + settings: + rows: 5 + placeholder: '' + third_party_settings: { } + type: text_textarea + region: content +hidden: + created: true + field_oe_icon: true + status: true + uid: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_description_list.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_description_list.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..0391e2563c5e154fe620db0d956c779898120dcc --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_description_list.default.yml @@ -0,0 +1,38 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_description_list.field_oe_description_list_items + - field.field.paragraph.oe_description_list.field_oe_title + - field.field.paragraph.oe_description_list.oe_w_orientation + - paragraphs.paragraphs_type.oe_description_list + module: + - description_list_field +id: paragraph.oe_description_list.default +targetEntityType: paragraph +bundle: oe_description_list +mode: default +content: + field_oe_description_list_items: + weight: 2 + settings: { } + third_party_settings: { } + type: description_list_widget + region: content + field_oe_title: + weight: 1 + settings: + size: 60 + placeholder: '' + third_party_settings: { } + type: string_textfield + region: content + oe_w_orientation: + type: options_select + weight: 0 + region: content + settings: { } + third_party_settings: { } +hidden: + created: true + status: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_facts_figures.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_facts_figures.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..d12c53635d2c77c6c32100fac6d0d685ededd07b --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_facts_figures.default.yml @@ -0,0 +1,61 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_facts_figures.field_oe_link + - field.field.paragraph.oe_facts_figures.field_oe_paragraphs + - field.field.paragraph.oe_facts_figures.field_oe_title + - field.field.paragraph.oe_facts_figures.oe_w_n_columns + - paragraphs.paragraphs_type.oe_facts_figures + module: + - link + - oe_paragraphs +id: paragraph.oe_facts_figures.default +targetEntityType: paragraph +bundle: oe_facts_figures +mode: default +content: + field_oe_link: + type: link_default + weight: 2 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_oe_paragraphs: + type: oe_paragraphs_variants + weight: 8 + region: content + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: open + add_mode: dropdown + form_display_mode: default + default_paragraph_type: '' + closed_mode: summary + autocollapse: none + closed_mode_threshold: 0 + features: + collapse_edit_all: collapse_edit_all + duplicate: duplicate + third_party_settings: { } + field_oe_title: + type: string_textfield + weight: 1 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + oe_w_n_columns: + weight: 6 + settings: + placeholder: '' + third_party_settings: { } + type: number + region: content +hidden: + created: true + status: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_links_block.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_links_block.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..0e2b032e74278f92682b0096ed2233083b517129 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_links_block.default.yml @@ -0,0 +1,48 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_links_block.field_oe_links + - field.field.paragraph.oe_links_block.oe_w_links_block_background + - field.field.paragraph.oe_links_block.oe_w_links_block_orientation + - field.field.paragraph.oe_links_block.field_oe_text + - paragraphs.paragraphs_type.oe_links_block + module: + - link +id: paragraph.oe_links_block.default +targetEntityType: paragraph +bundle: oe_links_block +mode: default +content: + field_oe_links: + weight: 3 + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + type: link_default + region: content + oe_w_links_block_background: + weight: 1 + settings: { } + third_party_settings: { } + type: options_select + region: content + oe_w_links_block_orientation: + weight: 0 + settings: { } + third_party_settings: { } + type: options_select + region: content + field_oe_text: + weight: 2 + settings: + size: 60 + placeholder: '' + third_party_settings: { } + type: string_textfield + region: content +hidden: + created: true + status: true + uid: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..a80ab7071e5dce0520213b47ff64699517e6fc23 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item.default.yml @@ -0,0 +1,71 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_list_item.field_oe_date + - field.field.paragraph.oe_list_item.field_oe_image + - field.field.paragraph.oe_list_item.field_oe_link + - field.field.paragraph.oe_list_item.field_oe_meta + - field.field.paragraph.oe_list_item.field_oe_text_long + - field.field.paragraph.oe_list_item.field_oe_title + - image.style.thumbnail + - paragraphs.paragraphs_type.oe_list_item + module: + - allowed_formats + - image + - link + - text +id: paragraph.oe_list_item.default +targetEntityType: paragraph +bundle: oe_list_item +mode: default +content: + field_oe_image: + type: image_image + weight: 3 + region: content + settings: + progress_indicator: throbber + preview_image_style: thumbnail + third_party_settings: { } + field_oe_link: + type: link_default + weight: 0 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_oe_meta: + type: string_textfield + weight: 4 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + field_oe_text_long: + type: text_textarea + weight: 2 + region: content + settings: + rows: 3 + placeholder: '' + third_party_settings: + allowed_formats: + hide_help: '1' + hide_guidelines: '1' + field_oe_title: + type: string_textfield + weight: 1 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } +hidden: + created: true + field_oe_date: true + status: true + translation: true + uid: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..6497f1fd68ed773d1041bb78ecfd57d63cc1bc91 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.default.yml @@ -0,0 +1,67 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_list_item_block.field_oe_link + - field.field.paragraph.oe_list_item_block.field_oe_list_item_block_layout + - field.field.paragraph.oe_list_item_block.field_oe_paragraphs + - field.field.paragraph.oe_list_item_block.field_oe_title + - paragraphs.paragraphs_type.oe_list_item_block + module: + - link + - paragraphs +id: paragraph.oe_list_item_block.default +targetEntityType: paragraph +bundle: oe_list_item_block +mode: default +content: + field_oe_link: + type: link_default + weight: 3 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_oe_list_item_block_layout: + type: options_select + weight: 0 + region: content + settings: { } + third_party_settings: { } + field_oe_paragraphs: + type: paragraphs + weight: 2 + region: content + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: closed + closed_mode: summary + autocollapse: none + closed_mode_threshold: 0 + add_mode: dropdown + form_display_mode: default + default_paragraph_type: oe_list_item + features: + add_above: '0' + collapse_edit_all: collapse_edit_all + duplicate: duplicate + third_party_settings: { } + field_oe_title: + type: string_textfield + weight: 1 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + translation: + weight: 4 + region: content + settings: { } + third_party_settings: { } +hidden: + created: true + status: true + uid: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.highlight.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.highlight.yml new file mode 100644 index 0000000000000000000000000000000000000000..28e0a334f75d1213de8a45ffd1edc543d710b3fe --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_list_item_block.highlight.yml @@ -0,0 +1,68 @@ +langcode: en +status: true +dependencies: + config: + - core.entity_form_mode.paragraph.highlight + - field.field.paragraph.oe_list_item_block.field_oe_link + - field.field.paragraph.oe_list_item_block.field_oe_list_item_block_layout + - field.field.paragraph.oe_list_item_block.field_oe_paragraphs + - field.field.paragraph.oe_list_item_block.field_oe_title + - paragraphs.paragraphs_type.oe_list_item_block + module: + - link + - paragraphs +id: paragraph.oe_list_item_block.highlight +targetEntityType: paragraph +bundle: oe_list_item_block +mode: highlight +content: + field_oe_link: + type: link_default + weight: 3 + region: content + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + field_oe_list_item_block_layout: + type: options_select + weight: 0 + region: content + settings: { } + third_party_settings: { } + field_oe_paragraphs: + type: paragraphs + weight: 2 + region: content + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: closed + closed_mode: summary + autocollapse: none + closed_mode_threshold: 0 + add_mode: dropdown + form_display_mode: highlight + default_paragraph_type: oe_list_item + features: + add_above: '0' + collapse_edit_all: collapse_edit_all + duplicate: duplicate + third_party_settings: { } + field_oe_title: + type: string_textfield + weight: 1 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + translation: + weight: 4 + region: content + settings: { } + third_party_settings: { } +hidden: + created: true + status: true + uid: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_social_media_follow.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_social_media_follow.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..95a3846901360edb5e74ae1e74add620785ad8db --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_form_display.paragraph.oe_social_media_follow.default.yml @@ -0,0 +1,57 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_social_media_follow.oe_w_links_block_background + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_links + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_see_more + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant + - field.field.paragraph.oe_social_media_follow.field_oe_title + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - link + - typed_link +id: paragraph.oe_social_media_follow.default +targetEntityType: paragraph +bundle: oe_social_media_follow +mode: default +content: + oe_w_links_block_background: + type: options_select + weight: 1 + region: content + settings: { } + third_party_settings: { } + field_oe_social_media_links: + weight: 3 + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + type: typed_link + region: content + field_oe_social_media_see_more: + weight: 4 + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + type: link_default + region: content + field_oe_social_media_variant: + weight: 0 + settings: { } + third_party_settings: { } + type: options_select + region: content + field_oe_title: + weight: 2 + settings: + size: 60 + placeholder: '' + third_party_settings: { } + type: string_textfield + region: content +hidden: + created: true + status: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_accordion_item.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_accordion_item.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..8c3a67f6a8eb54e91907ed324a6cc13b39d354ab --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_accordion_item.default.yml @@ -0,0 +1,32 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_accordion_item.field_oe_icon + - field.field.paragraph.oe_accordion_item.field_oe_text + - field.field.paragraph.oe_accordion_item.field_oe_text_long + - paragraphs.paragraphs_type.oe_accordion_item + module: + - text +id: paragraph.oe_accordion_item.default +targetEntityType: paragraph +bundle: oe_accordion_item +mode: default +content: + field_oe_text: + weight: 0 + label: above + settings: + link_to_entity: false + third_party_settings: { } + type: string + region: content + field_oe_text_long: + weight: 1 + label: above + settings: { } + third_party_settings: { } + type: text_default + region: content +hidden: + field_oe_icon: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_description_list.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_description_list.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..b303a9e948f2afefed72a181681a3b630806259f --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_description_list.default.yml @@ -0,0 +1,32 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_description_list.oe_w_orientation + - field.field.paragraph.oe_description_list.field_oe_description_list_items + - field.field.paragraph.oe_description_list.field_oe_title + - paragraphs.paragraphs_type.oe_description_list + module: + - description_list_field +id: paragraph.oe_description_list.default +targetEntityType: paragraph +bundle: oe_description_list +mode: default +content: + field_oe_description_list_items: + weight: 1 + label: hidden + settings: { } + third_party_settings: { } + type: description_list_formatter + region: content + field_oe_title: + weight: 0 + label: hidden + settings: + link_to_entity: false + third_party_settings: { } + type: string + region: content +hidden: + oe_w_orientation: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_facts_figures.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_facts_figures.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..6b3d6961e433fcc76b6cdd48466e6fb9e1f10a63 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_facts_figures.default.yml @@ -0,0 +1,48 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_facts_figures.field_oe_link + - field.field.paragraph.oe_facts_figures.field_oe_paragraphs + - field.field.paragraph.oe_facts_figures.field_oe_title + - field.field.paragraph.oe_facts_figures.oe_w_n_columns + - paragraphs.paragraphs_type.oe_facts_figures + module: + - entity_reference_revisions + - link +id: paragraph.oe_facts_figures.default +targetEntityType: paragraph +bundle: oe_facts_figures +mode: default +content: + field_oe_link: + weight: 2 + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + type: link + region: content + field_oe_paragraphs: + weight: 1 + label: above + settings: + view_mode: default + link: '' + third_party_settings: { } + type: entity_reference_revisions_entity_view + region: content + field_oe_title: + weight: 0 + label: above + settings: + link_to_entity: false + third_party_settings: { } + type: string + region: content +hidden: + oe_w_n_columns: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_links_block.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_links_block.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..0d927d07494e95fdfc6b4b8c7acb9cfe479221fc --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_links_block.default.yml @@ -0,0 +1,39 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_links_block.field_oe_links + - field.field.paragraph.oe_links_block.field_oe_links_block_background + - field.field.paragraph.oe_links_block.field_oe_links_block_orientation + - field.field.paragraph.oe_links_block.field_oe_text + - paragraphs.paragraphs_type.oe_links_block + module: + - link +id: paragraph.oe_links_block.default +targetEntityType: paragraph +bundle: oe_links_block +mode: default +content: + field_oe_links: + weight: 1 + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + type: link + region: content + field_oe_text: + weight: 0 + label: above + settings: + link_to_entity: false + third_party_settings: { } + type: string + region: content +hidden: + field_oe_links_block_background: true + field_oe_links_block_orientation: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_social_media_follow.default.yml b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_social_media_follow.default.yml new file mode 100644 index 0000000000000000000000000000000000000000..1177db68e7a9422cc1724e9af370f54eb2257ba7 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/core.entity_view_display.paragraph.oe_social_media_follow.default.yml @@ -0,0 +1,53 @@ +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.oe_social_media_follow.oe_w_links_block_background + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_links + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_see_more + - field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant + - field.field.paragraph.oe_social_media_follow.field_oe_title + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - link + - typed_link +id: paragraph.oe_social_media_follow.default +targetEntityType: paragraph +bundle: oe_social_media_follow +mode: default +content: + field_oe_social_media_links: + weight: 1 + label: hidden + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + type: typed_link + region: content + field_oe_social_media_see_more: + weight: 2 + label: hidden + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + type: link + region: content + field_oe_title: + weight: 0 + label: hidden + settings: + link_to_entity: false + third_party_settings: { } + type: string + region: content +hidden: + oe_w_links_block_background: true + field_oe_social_media_variant: true diff --git a/modules/oe_whitelabel_paragraphs/config/overrides/field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant.yml b/modules/oe_whitelabel_paragraphs/config/overrides/field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant.yml new file mode 100755 index 0000000000000000000000000000000000000000..ecf09e79bba7735bac6ef639e4ee10889593bcb7 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/config/overrides/field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.field_oe_social_media_variant + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - options +id: paragraph.oe_social_media_follow.field_oe_social_media_variant +field_name: field_oe_social_media_variant +entity_type: paragraph +bundle: oe_social_media_follow +label: Orientation +description: '' +required: true +translatable: false +default_value: + - + value: horizontal +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.info.yml b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..8495f5f43041949235949ca7e5e72a206bb6d526 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.info.yml @@ -0,0 +1,23 @@ +name: OpenEuropa Whitelabel Paragraphs +type: module +description: Companion module to add support and customisations for oe_paragraphs. +package: OpenEuropa Whitelabel Theme +core_version_requirement: ^9.2 +dependencies: + - drupal:description_list_field + - oe_content:oe_content_timeline_field + - oe_paragraphs:oe_paragraphs + - oe_paragraphs:oe_paragraphs_description_list + - oe_paragraphs:oe_paragraphs_timeline + - oe_whitelabel:oe_whitelabel_helper +config_devel: + install: + - field.field.paragraph.oe_description_list.oe_w_orientation + - field.field.paragraph.oe_facts_figures.oe_w_n_columns + - field.field.paragraph.oe_links_block.oe_w_links_block_background + - field.field.paragraph.oe_links_block.oe_w_links_block_orientation + - field.field.paragraph.oe_social_media_follow.oe_w_links_block_background + - field.storage.paragraph.oe_w_links_block_background + - field.storage.paragraph.oe_w_links_block_orientation + - field.storage.paragraph.oe_w_n_columns + - field.storage.paragraph.oe_w_orientation diff --git a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install new file mode 100644 index 0000000000000000000000000000000000000000..0479caf550404e4163efd873c974a9d3c2182591 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install @@ -0,0 +1,193 @@ +<?php + +/** + * @file + * Install and update functions for the OE Whitelabel Paragraphs module. + */ + +declare(strict_types = 1); + +use Drupal\field\Entity\FieldConfig; +use Drupal\oe_bootstrap_theme\ConfigImporter; + +/** + * Implements hook_install(). + * + * Customizes paragraphs fields and display configuration. + * + * If oe_bootstrap_theme_paragraphs was installed in the past, this will also + * migrate field data and clean up fields that have been renamed. + */ +function oe_whitelabel_paragraphs_install(bool $is_syncing): void { + // Find legacy fields from oe_bootstrap_theme_paragraphs. + // This needs to happen at the start, to allow for early abort. + $field_names_by_bundle = _oe_whitelabel_paragraphs_install_get_legacy_fields_map(); + + if ($is_syncing) { + // The module is being installed as part of a config import. + if ($field_names_by_bundle) { + // There is data to be migrated. This should not happen as a side effect + // of config-import. Instead, the installation should be enacted from an + // update hook. + throw new \Exception('This module should be installed through an update hook, not through config-import, if there is still leftover data from oe_bootstrap_theme_paragraphs to migrate.'); + } + // No data needs to be migrated, but still, no configuration should be + // imported in hook_install() during config-import. + return; + } + + // The module is being installed explicitly, e.g. via a hook_update_N(). + // Configuration needs to be imported explicitly. + _oe_whitelabel_paragraphs_install_config(); + + if (!$field_names_by_bundle) { + // No fields to migrate and clean up - finished. + return; + } + + _oe_whitelabel_paragraphs_install_migrate_field_data($field_names_by_bundle); + _oe_whitelabel_paragraphs_install_drop_legacy_fields($field_names_by_bundle); +} + +/** + * Imports configuration on module install. + */ +function _oe_whitelabel_paragraphs_install_config(): void { + $configs = [ + 'core.entity_form_display.paragraph.oe_accordion_item.default', + 'core.entity_form_display.paragraph.oe_description_list.default', + 'core.entity_form_display.paragraph.oe_facts_figures.default', + 'core.entity_form_display.paragraph.oe_links_block.default', + 'core.entity_form_display.paragraph.oe_list_item.default', + 'core.entity_form_display.paragraph.oe_list_item_block.default', + 'core.entity_form_display.paragraph.oe_list_item_block.highlight', + 'core.entity_form_display.paragraph.oe_social_media_follow.default', + 'core.entity_view_display.paragraph.oe_accordion_item.default', + 'core.entity_view_display.paragraph.oe_description_list.default', + 'core.entity_view_display.paragraph.oe_facts_figures.default', + 'core.entity_view_display.paragraph.oe_links_block.default', + 'core.entity_view_display.paragraph.oe_social_media_follow.default', + 'field.field.paragraph.oe_social_media_follow.field_oe_social_media_variant', + ]; + + ConfigImporter::importMultiple('oe_whitelabel_paragraphs', '/config/overrides/', $configs); +} + +/** + * Gets a map of legacy fields to be migrated on install. + * + * @return string[][] + * Legacy field names, indexed by paragraph type and destination field name. + * Only contains entries where both the legacy field name and the destination + * field name do exist. + * Empty, if oe_bootstrap_theme_paragraphs was not installed in the past. + */ +function _oe_whitelabel_paragraphs_install_get_legacy_fields_map(): array { + /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */ + $entity_field_manager = \Drupal::service('entity_field.manager'); + $fields_map = $entity_field_manager->getFieldMap()['paragraph'] ?? []; + + $field_names_by_bundle = [ + 'oe_description_list' => [ + 'oe_w_orientation' => 'oe_bt_orientation', + ], + 'oe_facts_figures' => [ + 'oe_w_n_columns' => 'oe_bt_n_columns', + ], + 'oe_links_block' => [ + 'oe_w_links_block_background' => 'oe_bt_links_block_background', + 'oe_w_links_block_orientation' => 'oe_bt_links_block_orientation', + ], + 'oe_social_media_follow' => [ + 'oe_w_links_block_background' => 'oe_bt_links_block_background', + ], + ]; + + foreach ($field_names_by_bundle as $bundle => $field_names) { + foreach ($field_names as $dest_field_name => $source_field_name) { + if (!isset($fields_map[$source_field_name]['bundles'][$bundle])) { + // The legacy field does not exist. + // Perhaps the field or the paragraph type were removed manually. + unset($field_names_by_bundle[$bundle][$dest_field_name]); + continue; + } + if (!isset($fields_map[$dest_field_name]['bundles'][$bundle])) { + // A destination field is missing, that should have been created + // earlier. This could happen if a paragraph type was removed manually, + // but in that case the install should have already failed earlier. + // Either way, this case is not supported. + throw new \RuntimeException("Destination field 'paragraph.$bundle.$dest_field_name' was not properly created."); + } + } + } + + return $field_names_by_bundle; +} + +/** + * Migrates field data from the old oe_bootstrap_theme_paragraphs module. + * + * This should happen through a batch process, e.g. via $sandbox in a + * hook_update_N(). Unfortunately, hook_install() does not support batch + * processes. + * + * @param string[][] $field_names_by_bundle + * Legacy field names, indexed by paragraph type and destination field name. + */ +function _oe_whitelabel_paragraphs_install_migrate_field_data(array $field_names_by_bundle): void { + $paragraphs_storage = \Drupal::entityTypeManager()->getStorage('paragraph'); + + // Load all the paragraph ids. + $query = $paragraphs_storage->getQuery(); + $query->allRevisions(); + $query->condition('type', array_keys($field_names_by_bundle), 'IN'); + $paragraph_ids = $query->execute(); + + foreach ($paragraph_ids as $revision_id => $paragraph_id) { + // Revision can't be NULL. + /** @var \Drupal\paragraphs\ParagraphInterface $paragraph_revision */ + $paragraph_revision = $paragraphs_storage->loadRevision($revision_id); + $field_names_map = $field_names_by_bundle[$paragraph_revision->bundle()]; + $modified = FALSE; + foreach ($field_names_map as $dest_field_name => $source_field_name) { + if ($paragraph_revision->get($source_field_name)->isEmpty()) { + // Source field has no data. + continue; + } + if (!$paragraph_revision->get($dest_field_name)->isEmpty()) { + // Destination already has data. + continue; + } + // Copy the field value. + // For these simple field types, magic __set() does the job. + $paragraph_revision->$dest_field_name = $paragraph_revision->$source_field_name; + // Do not unset the old field, because it might be required. + // Remember that the revision needs saving. + $modified = TRUE; + } + if (!$modified) { + // No saving is needed. + continue; + } + $paragraph_revision->setNewRevision(FALSE); + $paragraph_revision->save(); + } +} + +/** + * Removes legacy field instances from oe_bootstrap_theme_paragraphs module. + * + * @param string[][] $field_names_by_bundle + * Legacy field names, indexed by paragraph type and destination field name. + */ +function _oe_whitelabel_paragraphs_install_drop_legacy_fields(array $field_names_by_bundle): void { + foreach ($field_names_by_bundle as $bundle => $legacy_field_names) { + foreach ($legacy_field_names as $legacy_field_name) { + $field_config = FieldConfig::loadByName('paragraph', $bundle, $legacy_field_name); + if ($field_config === NULL) { + throw new \RuntimeException("Legacy field 'paragraph.$bundle.$legacy_field_name' not found."); + } + $field_config->delete(); + } + } +} diff --git a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.module b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.module new file mode 100644 index 0000000000000000000000000000000000000000..e8a17b933c8fedf45fa7806932095cfa9a5f68f2 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.module @@ -0,0 +1,538 @@ +<?php + +/** + * @file + * OE Whitelabel Paragraphs module. + * + * Preprocess hooks are implemented on behalf of the oe_whitelabel theme. + * This prevents hooks from running if oe_whitelabel is not the active theme. + */ + +declare(strict_types = 1); + +use Drupal\Component\Utility\Html; +use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Entity\Entity\EntityViewDisplay; +use Drupal\Core\Render\Element; +use Drupal\Core\Url; +use Drupal\media\Entity\Media; +use Drupal\media\MediaInterface; +use Drupal\media\MediaSourceInterface; +use Drupal\media\Plugin\media\Source\Image; +use Drupal\media\Plugin\media\Source\OEmbed; +use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalPhotoSource; +use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalSourceInterface; +use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalVideoSource; +use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject; +use Drupal\oe_media_iframe\Plugin\media\Source\Iframe; +use Drupal\paragraphs\Entity\Paragraph; + +/** + * Implements hook_theme_suggestions_HOOK_alter(). + * + * Adds a bare, markup-free template suggestion to all paragraph fields. + */ +function oe_whitelabel_paragraphs_theme_suggestions_field_alter(array &$suggestions, array $variables): void { + $element = $variables['element']; + + // Do not output field labels and wrapping markup for paragraph fields. + if (isset($element['#entity_type']) && $element['#entity_type'] === 'paragraph') { + // Prepend the new suggestion to the list. This will put it right after the + // default field template. By doing this we allow to override single + // fields, while keeping all the rest markup-free. + array_unshift($suggestions, 'field__bare'); + } +} + +/** + * Implements hook_preprocess_paragraph(). + */ +function oe_whitelabel_preprocess_paragraph__oe_links_block(array &$variables): void { + /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + $variables['orientation'] = $paragraph->get('oe_w_links_block_orientation')->value; + $variables['background'] = $paragraph->get('oe_w_links_block_background')->value; + if (!$paragraph->get('field_oe_text')->isEmpty()) { + $variables['title'] = $paragraph->get('field_oe_text')->value; + } + + foreach (Element::children($variables['content']['field_oe_links']) as $index) { + $variables['links'][] = [ + 'label' => $variables['content']['field_oe_links'][$index]['#title'], + 'path' => $variables['content']['field_oe_links'][$index]['#url']->toString(), + ]; + } +} + +/** + * Implements hook_preprocess_paragraph() for oe_social_media_follow paragraph. + */ +function oe_whitelabel_preprocess_paragraph__oe_social_media_follow(array &$variables): void { + /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + $variables['orientation'] = $paragraph->get('field_oe_social_media_variant')->value; + $variables['background'] = $paragraph->get('oe_w_links_block_background')->value; + if (!$paragraph->get('field_oe_title')->isEmpty()) { + $variables['title'] = $paragraph->get('field_oe_title')->value; + } + $links = $paragraph->get('field_oe_social_media_links')->getValue(); + $variables['links'] = []; + foreach ($links as $key => $link) { + $variables['links'][$key]['icon_position'] = 'before'; + $variables['links'][$key]['icon']['path'] = $variables['bcl_icon_path']; + $variables['links'][$key]['icon']['name'] = $link['link_type']; + $variables['links'][$key]['label'] = $link['title']; + $variables['links'][$key]['path'] = Url::fromUri($link['uri'])->toString(); + } + if (!$paragraph->get('field_oe_social_media_see_more')->isEmpty()) { + $other_link = $paragraph->get('field_oe_social_media_see_more') + ->first() + ->getValue(); + $variables['links'][] = [ + 'label' => $other_link['title'], + 'path' => Url::fromUri($other_link['uri'])->toString(), + ]; + } +} + +/** + * Implements hook_preprocess_paragraph__oe_accordion(). + */ +function oe_whitelabel_preprocess_paragraph__oe_accordion(array &$variables): void { + // Massage data to be compliant with OE Bootstrap Theme accordion pattern + // data structure. + $builder = \Drupal::entityTypeManager()->getViewBuilder('paragraph'); + $variables['items'] = []; + + /** @var \Drupal\entity_reference_revisions\Plugin\Field\FieldType\EntityReferenceRevisionsItem $field_item */ + foreach ($variables['paragraph']->get('field_oe_paragraphs') as $field_item) { + $paragraph = \Drupal::service('entity.repository')->getTranslationFromContext($field_item->entity); + $variables['items'][] = [ + 'title' => $builder->viewField($paragraph->get('field_oe_text')), + 'content' => $builder->viewField($paragraph->get('field_oe_text_long')), + ]; + } +} + +/** + * Implements hook_preprocess_paragraph() for paragraph--oe-text-feature-media.html.twig. + */ +function oe_whitelabel_preprocess_paragraph__oe_text_feature_media(array &$variables): void { + /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + + // Bail out if there is no media present. + if ($paragraph->get('field_oe_media')->isEmpty()) { + return; + } + + /** @var \Drupal\media\Entity\Media $media */ + $media = $paragraph->get('field_oe_media')->entity; + if (!$media instanceof MediaInterface) { + // The media entity is not available anymore, bail out. + return; + } + + // Retrieve the correct media translation. + /** @var \Drupal\media\Entity\Media $media */ + $media = \Drupal::service('entity.repository')->getTranslationFromContext($media, $paragraph->language()->getId()); + + // Caches are handled by the formatter usually. Since we are not rendering + // the original render arrays, we need to propagate our caches to the + // paragraph template. + $cacheability = CacheableMetadata::createFromRenderArray($variables); + $cacheability->addCacheableDependency($media); + + // Run access checks on the media entity. + $access = $media->access('view', $variables['user'], TRUE); + $cacheability->addCacheableDependency($access); + if (!$access->isAllowed()) { + $cacheability->applyTo($variables); + return; + } + + // Get the media source. + $source = $media->getSource(); + + $is_image = $source instanceof MediaAvPortalPhotoSource || $source instanceof Image; + $is_video = $source instanceof MediaAvPortalVideoSource || $source instanceof OEmbed || $source instanceof Iframe; + + // If it's not an image and not a video, bail out. + if (!$is_image && !$is_video) { + $cacheability->applyTo($variables); + return; + } + + $variant = $paragraph->get('oe_paragraphs_variant')->value ?? 'default'; + $variables['text_position'] = str_replace([ + '_featured', + '_simple', + ], '', $variant); + + if ($is_image) { + $thumbnail = $media->get('thumbnail')->first(); + $variables['image'] = ImageValueObject::fromStyledImageItem($thumbnail, 'oe_bootstrap_theme_medium_no_crop'); + } + elseif ($is_video) { + _oe_whitelabel_featured_media_set_embedded_media($variables, $media, $cacheability, $source); + } + + $cacheability->applyTo($variables); + + if (empty($paragraph->get('field_oe_link')->first())) { + return; + } + + /** @var \Drupal\link\Plugin\Field\FieldType\LinkItem $link_item */ + $link_item = $paragraph->get('field_oe_link')->first(); + $variables['link'] = [ + 'path' => $link_item->getUrl()->toString(), + 'label' => $link_item->get('title')->getValue(), + ]; +} + +/** + * Implements hook_preprocess_paragraph() for paragraph--oe-list-item-block.html.twig. + */ +function oe_whitelabel_preprocess_paragraph__oe_list_item_block(array &$variables): void { + /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + + // @todo Use ->isEmpty() as in other preprocess functions. + // In the OpenEuropa team it was decided that ->isEmpty() calls should be + // the preferred way to deal with empty field values. + // This function instead relies on ->value or ->first() returning NULL for + // empty fields, which the team is not fully confident about, and which does + // not follow the team convention. + // It was agreed to keep it like this for now in this function, but refactor + // it in the future. + // See also https://www.drupal.org/project/drupal/issues/3268137. + $variables['variant'] = $paragraph->get('oe_paragraphs_variant')->value; + $variables['title'] = $paragraph->get('field_oe_title')->value; + + $layout_name = $paragraph->get('field_oe_list_item_block_layout')->value; + $variables['columns'] = ['two_columns' => '2', 'three_columns' => '3'][$layout_name] ?? '1'; + + $variables['items'] = []; + foreach ($variables['paragraph']->get('field_oe_paragraphs') as $card_paragraph_item) { + /** @var \Drupal\paragraphs\ParagraphInterface $card_paragraph */ + $card_paragraph = $card_paragraph_item->entity; + + /** @var \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $card_image_items */ + $card_image_items = $card_paragraph->get('field_oe_image'); + /** @var \Drupal\file\FileInterface|null $card_image_file */ + $card_image_file = $card_image_items->entity; + $card_image = $card_image_file ? [ + 'path' => file_url_transform_relative(file_create_url($card_image_file->getFileUri())), + 'alt' => $card_image_items->alt, + ] : []; + + // Prepare the metas if available. + $card_badges = []; + foreach ($card_paragraph->get('field_oe_meta') as $meta_item) { + $card_badges[] = $meta_item->value; + } + + $card_title = $card_paragraph->get('field_oe_title')->value; + /** @var \Drupal\link\LinkItemInterface|null $card_link_item */ + $card_link_item = $card_paragraph->get('field_oe_link')->first(); + $variables['items'][] = [ + 'title' => $card_title, + 'url' => $card_link_item ? $card_link_item->getUrl() : '', + 'text' => $card_paragraph->get('field_oe_text_long')->value, + 'image' => $card_image, + 'badges' => $card_badges, + ]; + } + + // Prepare the button variables if a link has been specified. + /** @var \Drupal\link\Plugin\Field\FieldType\LinkItem $link_item */ + $link_item = $paragraph->get('field_oe_link')->first(); + $variables['link'] = $link_item ? [ + 'path' => $link_item->getUrl()->toString(), + 'label' => $link_item->title, + 'icon' => [ + 'path' => $variables['bcl_icon_path'], + 'name' => 'chevron-right', + ], + ] : NULL; +} + +/** + * Implements hook_preprocess_paragraph() for oe_banner paragraph. + */ +function oe_whitelabel_preprocess_paragraph__oe_banner(array &$variables): void { + /** @var Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + $variables['title'] = $paragraph->get('field_oe_title')->value; + $variables['description'] = $paragraph->get('field_oe_text')->value; + $variables['full_width'] = (bool) $paragraph->get('field_oe_banner_full_width')->value; + _oe_whitelabel_set_banner_link($paragraph, $variables); + + // The alignment field value contains the information regarding the pattern + // type and centering. + $alignment = $paragraph->get('field_oe_banner_type')->value; + [$banner_type, $banner_alignment] = explode('_', $alignment); + // The beginning of the string determines the pattern. + $variables['pattern'] = 'banner_' . $banner_type; + // The end of the string determines the position. + $variables['alignment'] = $banner_alignment; + + $variant = $paragraph->get('oe_paragraphs_variant')->value ?? 'default'; + $variables['variant'] = str_replace('oe_banner_', '', $variant); + + if ($variables['variant'] === 'default' || $variables['variant'] === 'primary') { + return; + } + + // Bail out if there is no media present. + if ($paragraph->get('field_oe_media')->isEmpty()) { + return; + } + $cacheability = CacheableMetadata::createFromRenderArray($variables); + + /** @var \Drupal\media\Entity\Media $media */ + $media = $paragraph->get('field_oe_media')->entity; + if (!$media instanceof MediaInterface) { + // The media entity is not available anymore, bail out. + return; + } + + // Retrieve the correct translation to display. + $media = \Drupal::service('entity.repository')->getTranslationFromContext($media, $paragraph->language()->getId()); + + // Caches are handled by the formatter usually. Since we are not rendering + // the original render arrays, we need to propagate our caches to the + // paragraph template. + $cacheability->addCacheableDependency($media); + + // Run access checks on the media entity. + $access = $media->access('view', $variables['user'], TRUE); + $cacheability->addCacheableDependency($access); + if (!$access->isAllowed()) { + $cacheability->applyTo($variables); + return; + } + + $source = $media->getSource(); + // We only support images and AV Portal photos for now. + if (!$source instanceof MediaAvPortalSourceInterface && !$source instanceof Image) { + $cacheability->applyTo($variables); + return; + } + + $uri = _oe_whitelabel_get_media_uri($source, $media, $cacheability); + + // The uri might be empty if the source is of type Image and the file entity + // was deleted. + if (empty($uri)) { + $cacheability->applyTo($variables); + return; + } + + $variables['image'] = ImageValueObject::fromArray([ + 'src' => file_create_url($uri), + 'alt' => $source->getMetadata($media, 'thumbnail_alt_value') ?? $media->label(), + 'name' => $media->getName(), + ]); + $cacheability->applyTo($variables); +} + +/** + * Implements hook_preprocess_paragraph() for timeline paragraph. + */ +function oe_whitelabel_preprocess_paragraph__oe_timeline(array &$variables): void { + $paragraph = $variables['paragraph']; + if (!$paragraph->get('field_oe_title')->isEmpty()) { + $variables['heading'] = $paragraph->get('field_oe_title')->value; + } + + if (!isset($variables['content']['field_oe_timeline']['#items'])) { + return; + } + // Adapting body to content as defined in pattern. + foreach ($variables['content']['field_oe_timeline']['#items'] as &$timeline_item) { + $timeline_item['content'] = $timeline_item['body']; + unset($timeline_item['body']); + $variables['content']['items'][] = $timeline_item; + } + $variables['hide_from'] = $paragraph->get('field_oe_timeline_expand')->value; +} + +/** + * Implements hook_preprocess_paragraph() for paragraph--oe-content-row--variant-inpage-navigation.html.twig. + */ +function oe_whitelabel_preprocess_paragraph__oe_content_row__variant_inpage_navigation(array &$variables): void { + /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + + if ($paragraph->get('field_oe_paragraphs')->isEmpty()) { + return; + } + + $variables['attributes']['id'] = Html::getUniqueId('bcl-inpage-navigation-pid-' . $paragraph->id()); + + $variables['title'] = t('Page contents'); + if (!$paragraph->get('field_oe_title')->isEmpty()) { + $variables['title'] = $paragraph->get('field_oe_title')->value; + } + + $field_render = &$variables['content']['field_oe_paragraphs']; + $links = []; + foreach ($paragraph->get('field_oe_paragraphs')->referencedEntities() as $delta => $sub_paragraph) { + /** @var \Drupal\paragraphs\Entity\Paragraph $sub_paragraph */ + if (!$sub_paragraph->hasField('field_oe_title') || $sub_paragraph->get('field_oe_title')->isEmpty()) { + continue; + } + + $unique_id = Html::getUniqueId('bcl-inpage-item-' . $sub_paragraph->id()); + $field_render[$delta]['#theme_wrappers']['container'] = [ + '#attributes' => ['id' => $unique_id], + ]; + + $sub_paragraph = \Drupal::service('entity.repository') + ->getTranslationFromContext($sub_paragraph, $paragraph->language()->getId()); + + $links[] = [ + 'path' => '#' . $unique_id, + 'label' => $sub_paragraph->get('field_oe_title')->first()->value, + ]; + } + + $variables['links'] = $links; +} + +/** + * Implements hook_preprocess_paragraph() for oe_description-list paragraph. + */ +function oe_whitelabel_preprocess_paragraph__oe_description_list(array &$variables): void { + /** @var Drupal\paragraphs\Entity\Paragraph $paragraph */ + $paragraph = $variables['paragraph']; + $variables['title'] = $paragraph->get('field_oe_title')->value ?? ''; + $variables['orientation'] = $paragraph->get('oe_w_orientation')->value; + + foreach ($paragraph->get('field_oe_description_list_items') as $item) { + $variables['items'][] = [ + 'term' => $item->term, + 'definition' => $item->description, + ]; + } +} + +/** + * Implements hook_preprocess_paragraph(). + */ +function oe_whitelabel_preprocess_paragraph__oe_facts_figures(array &$variables): void { + /** @var \Drupal\paragraphs\ParagraphInterface $paragraph */ + $paragraph = $variables['paragraph']; + if (!$paragraph->get('field_oe_title')->isEmpty()) { + $variables['title'] = $paragraph->get('field_oe_title')->value; + } + + if (!$paragraph->get('field_oe_link')->isEmpty()) { + $link_item = $paragraph->get('field_oe_link')->first(); + $variables['link_more']['path'] = $link_item->getUrl()->toString(); + $variables['link_more']['label'] = $link_item->get('title')->getValue(); + } + $variables['items'] = []; + + /** @var \Drupal\paragraphs\Entity\Paragraph $sub_paragraph */ + foreach ($paragraph->get('field_oe_paragraphs')->referencedEntities() as $sub_paragraph) { + // Get the paragraph translation. + $sub_paragraph = \Drupal::service('entity.repository') + ->getTranslationFromContext($sub_paragraph, $paragraph->language()->getId()); + $description = ''; + if (!$sub_paragraph->get('field_oe_plain_text_long')->isEmpty()) { + $description = $sub_paragraph->get('field_oe_plain_text_long')->value; + } + $variables['items'][] = [ + 'icon' => $sub_paragraph->get('field_oe_icon')->value, + 'title' => $sub_paragraph->get('field_oe_title')->value, + 'subtitle' => $sub_paragraph->get('field_oe_subtitle')->value, + 'description' => $description, + ]; + } + + if (!$paragraph->get('oe_w_n_columns')->isEmpty()) { + $variables['columns'] = $paragraph->get('oe_w_n_columns')->value; + } +} + +/** + * Sets link variable for banner paragraph. + * + * @param \Drupal\paragraphs\Entity\Paragraph $paragraph + * The paragraph. + * @param array $variables + * The render array. + */ +function _oe_whitelabel_set_banner_link(Paragraph $paragraph, array &$variables): void { + if ($paragraph->get('field_oe_link')->isEmpty()) { + return; + } + + $link = $paragraph->get('field_oe_link')->first(); + $variables['url'] = $link->getUrl()->toString(); + $variables['label'] = $link->get('title')->getValue(); +} + +/** + * Gets the uri from a media object. + * + * @param \Drupal\media\MediaSourceInterface $source + * The media source. + * @param \Drupal\media\Entity\Media $media + * The media object. + * @param \Drupal\Core\Cache\CacheableMetadata $cacheability + * The cacheability object. + * + * @return string + * The uri string. + */ +function _oe_whitelabel_get_media_uri(MediaSourceInterface $source, Media $media, CacheableMetadata $cacheability): string { + $field_name = $source->getConfiguration()['source_field']; + + if ($source instanceof Image && ($file_entity = $media->get($field_name)->entity)) { + $cacheability->addCacheableDependency($file_entity); + return $file_entity->getFileUri(); + } + + if ($source instanceof MediaAvPortalSourceInterface) { + $resource_ref = $media->get($field_name)->value; + return 'avportal://' . $resource_ref . '.jpg'; + } + + return ''; +} + +/** + * Prepares embedded media variables for "text with featured media" paragraph. + * + * @param array $variables + * The render array. + * @param \Drupal\media\MediaInterface $media + * Media object. + * @param \Drupal\Core\Cache\CacheableMetadata $cacheability + * CacheableMetadata object. + * @param \Drupal\media\MediaSourceInterface $source + * Media source. + */ +function _oe_whitelabel_featured_media_set_embedded_media(array &$variables, MediaInterface $media, CacheableMetadata $cacheability, MediaSourceInterface $source): void { + // Default video aspect ratio is set to 16x9. + $variables['ratio'] = '16x9'; + + // Load information about the media and the display. + $media_type = \Drupal::entityTypeManager()->getStorage('media_type')->load($media->bundle()); + $cacheability->addCacheableDependency($media_type); + $source_field = $source->getSourceFieldDefinition($media_type); + $display = EntityViewDisplay::collectRenderDisplay($media, 'default'); + $cacheability->addCacheableDependency($display); + $display_options = $display->getComponent($source_field->getName()); + + $variables['embedded_media'] = $media->{$source_field->getName()}->view($display_options); + + if ($media->bundle() === 'video_iframe') { + $ratio = $media->get('oe_media_iframe_ratio')->value; + $variables['ratio'] = str_replace('_', 'x', $ratio); + } +} diff --git a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.services.yml b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.services.yml new file mode 100644 index 0000000000000000000000000000000000000000..5dfebd8df61f745e482f6c0940c9b5c145573723 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.services.yml @@ -0,0 +1,5 @@ +services: + oe_whitelabel_paragraphs.icon_options_subscriber: + class: 'Drupal\oe_whitelabel_paragraphs\EventSubscriber\IconOptionsSubscriber' + tags: + - { name: 'event_subscriber' } diff --git a/modules/oe_whitelabel_paragraphs/src/EventSubscriber/IconOptionsSubscriber.php b/modules/oe_whitelabel_paragraphs/src/EventSubscriber/IconOptionsSubscriber.php new file mode 100644 index 0000000000000000000000000000000000000000..38785ea5ba0d0797601e9d7545f49afe6ff8bf6b --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/src/EventSubscriber/IconOptionsSubscriber.php @@ -0,0 +1,57 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\oe_whitelabel_paragraphs\EventSubscriber; + +use Drupal\oe_paragraphs\Event\IconOptionsEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Provides options for the icon field. + * + * @see \Drupal\oe_paragraphs\EventSubscriber\OptionsSubscriber + * @see _oe_paragraphs_allowed_values_icons() + */ +class IconOptionsSubscriber implements EventSubscriberInterface { + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array { + return [ + IconOptionsEvent::class => ['getIconOptions', -1], + ]; + } + + /** + * Gets the icon options. + * + * @param \Drupal\oe_paragraphs\Event\IconOptionsEvent $event + * Allowed format event object. + */ + public function getIconOptions(IconOptionsEvent $event): void { + $event->setIconOptions([ + 'arrow-down' => 'Arrow down', + 'box-arrow-up' => 'External', + 'arrow-up' => 'Arrow up', + 'book' => 'Book', + 'camera' => 'Camera', + 'check' => 'Check', + 'download' => 'Download', + 'currency-euro' => 'Euro', + 'facebook' => 'Facebook', + 'file' => 'File', + 'image' => 'Image', + 'info' => 'Info', + 'linkedin' => 'LinkedIn', + 'files' => 'Multiple files', + 'rss' => 'RSS', + 'search' => 'Search', + 'share' => 'Share', + 'twitter' => 'Twitter', + 'camera-video' => 'Video', + ]); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/fixtures/example_1.jpeg b/modules/oe_whitelabel_paragraphs/tests/fixtures/example_1.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..e04cde60ca8fa8d23a3668010a40f976abb78e8b Binary files /dev/null and b/modules/oe_whitelabel_paragraphs/tests/fixtures/example_1.jpeg differ diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..73b09a472d8fca82e66e5c1a1ccda494d88fb33c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_orientation + - paragraphs.paragraphs_type.oe_description_list + module: + - options +id: paragraph.oe_description_list.oe_bt_orientation +field_name: oe_bt_orientation +entity_type: paragraph +bundle: oe_description_list +label: Orientation +description: 'Sets the orientation (vertical|horizontal) for the paragraph.' +required: true +translatable: false +default_value: + - + value: horizontal +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..eec70a14e1e037db51893287df01d018fc6b868e --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml @@ -0,0 +1,24 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_n_columns + - paragraphs.paragraphs_type.oe_facts_figures +id: paragraph.oe_facts_figures.oe_bt_n_columns +field_name: oe_bt_n_columns +entity_type: paragraph +bundle: oe_facts_figures +label: 'Number of columns' +description: 'Sets the number of grid columns. Minimum number is 1 column and maximum is 3.' +required: false +translatable: false +default_value: + - + value: 1 +default_value_callback: '' +settings: + min: 1 + max: 3 + prefix: '' + suffix: '' +field_type: integer diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..de66c69713d5ed89c8815b1dbdb3f599a21eb2cd --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_background + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +bundle: oe_links_block +label: Background +description: 'Allows to select the background color of the links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..610c35d3739f035f44364e2852bebd7247e1698c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_orientation + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_bt_links_block_orientation +field_name: oe_bt_links_block_orientation +entity_type: paragraph +bundle: oe_links_block +label: Orientation +description: 'Allows to select the direction of the links block.' +required: false +translatable: false +default_value: + - + value: vertical +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..8e167195da6f02c6d387c8ad0c0426a04a6123cb --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_background + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - options +id: paragraph.oe_social_media_follow.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +bundle: oe_social_media_follow +label: Background +description: 'Allows to select the background color of the Social Media Links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..1a7dbec06489349b31b105c506d6256d6ca9d4f8 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: gray + label: Gray + - + value: transparent + label: Transparent + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..d582eb8126c744b0643c987431a6cc6dfa4cbd20 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_links_block_orientation +field_name: oe_bt_links_block_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: horizontal + label: Horizontal + - + value: vertical + label: Vertical + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..f2a740718db02227ad37f1ae65b8a425745e32e1 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - paragraphs +id: paragraph.oe_bt_n_columns +field_name: oe_bt_n_columns +entity_type: paragraph +type: integer +settings: + unsigned: false + size: normal +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..94f290a8e681aa0e93bef75192d167d80ea24ae5 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_orientation +field_name: oe_bt_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: vertical + label: Vertical + - + value: horizontal + label: Horizontal + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..4cb09829c9ca4f6105cbd9ca32deef9ca7f258d5 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml @@ -0,0 +1,9 @@ +name: OE Whitelabel - Legacy Paragraphs Test +type: module +description: Provides legacy configuration as in oe_bootstrap_theme_paragraphs. +package: Testing +hidden: true +dependencies: + - drupal:description_list_field + - oe_paragraphs:oe_paragraphs + - oe_paragraphs:oe_paragraphs_description_list diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e6a20318f1f4f0c372696edcb19f4ec561651a8c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php @@ -0,0 +1,218 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Functional; + +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\BrowserTestBase; + +/** + * Tests installation of oe_whitelabel_paragraphs. + * + * @see oe_whitelabel_paragraphs_install() + */ +class InstallTest extends BrowserTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'oe_whitelabel_legacy_paragraphs_test', + ]; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * Test installation with legacy fields and data present. + */ + public function testInstallWithLegacyParagraphs(): void { + $paragraphs_data = []; + $paragraphs_data['oe_description_list'] = [ + 'type' => 'oe_description_list', + 'field_oe_title' => 'Description list paragraph', + // This field will be renamed. + 'oe_bt_orientation' => 'horizontal', + 'field_oe_description_list_items' => [ + // One item is enough for this test. + [ + 'term' => 'Aliquam ultricies', + 'description' => 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + ], + ], + ]; + $paragraphs_data['oe_facts_figures'] = [ + 'type' => 'oe_facts_figures', + 'field_oe_title' => 'Fact and figures block', + 'field_oe_link' => [ + 'uri' => 'https://www.readmore.com', + 'title' => 'Read more', + ], + // This field will be renamed. + 'oe_bt_n_columns' => 3, + 'field_oe_paragraphs' => [ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '1529 JIRA Ticket', + 'field_oe_subtitle' => 'Jira Tickets', + 'field_oe_plain_text_long' => 'Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.', + ], + ]; + $paragraphs_data['oe_links_block'] = [ + 'type' => 'oe_links_block', + 'field_oe_text' => 'More information', + // These fields will be renamed. + 'oe_bt_links_block_orientation' => 'vertical', + 'oe_bt_links_block_background' => 'gray', + 'field_oe_links' => [ + // One link is enough for this test. + [ + 'title' => 'European Commission', + 'uri' => 'https://example.com', + ], + ], + ]; + $paragraphs_data['oe_social_media_follow'] = [ + 'type' => 'oe_social_media_follow', + 'field_oe_title' => 'Social media title', + 'field_oe_social_media_variant' => 'horizontal', + // This field will be renamed. + 'oe_bt_links_block_background' => 'gray', + // One link is enough for this test. + 'field_oe_social_media_links' => [ + [ + 'title' => 'Email', + 'uri' => 'mailto:example@com', + 'link_type' => 'email', + ], + ], + 'field_oe_social_media_see_more' => [ + 'title' => 'Other social networks', + 'uri' => 'https://europa.eu/european-union/contact/social-networks_en', + ], + ]; + + $revision_ids = []; + foreach ($paragraphs_data as $name => $paragraph_data) { + $paragraph = Paragraph::create($paragraph_data); + $paragraph->save(); + $revision_ids[$name] = $paragraph->getRevisionId(); + if ($name !== 'oe_links_block') { + // Don't create a revision for most of the paragraphs. + continue; + } + // Make this paragraph a revision. + $paragraph->setNewRevision(); + $paragraph->oe_bt_links_block_orientation = 'horizontal'; + $paragraph->save(); + $revision_ids[$name . ':modified'] = $paragraph->getRevisionId(); + } + + $legacy_field_config_ids = [ + 'paragraph.oe_description_list.oe_bt_orientation', + 'paragraph.oe_facts_figures.oe_bt_n_columns', + 'paragraph.oe_links_block.oe_bt_links_block_background', + 'paragraph.oe_links_block.oe_bt_links_block_orientation', + 'paragraph.oe_social_media_follow.oe_bt_links_block_background', + ]; + $legacy_field_storage_ids = [ + 'paragraph.oe_bt_links_block_background', + 'paragraph.oe_bt_links_block_orientation', + 'paragraph.oe_bt_n_columns', + 'paragraph.oe_bt_orientation', + ]; + $this->assertEqualsCanonicalizing( + $legacy_field_config_ids, + array_keys(FieldConfig::loadMultiple($legacy_field_config_ids)), + ); + $this->assertEqualsCanonicalizing( + $legacy_field_storage_ids, + array_keys(FieldStorageConfig::loadMultiple($legacy_field_storage_ids)), + ); + + /** @var \Drupal\Core\Extension\ModuleInstallerInterface $installer */ + $installer = \Drupal::service('module_installer'); + $installer->install(['oe_whitelabel_paragraphs']); + + $this->assertTrue( + \Drupal::moduleHandler()->moduleExists('oe_whitelabel_paragraphs'), + "Module 'oe_whitelabel_paragraphs was successfully installed."); + + $this->assertEmpty(FieldConfig::loadMultiple($legacy_field_config_ids)); + $this->assertEmpty(FieldStorageConfig::loadMultiple($legacy_field_storage_ids)); + + $expected_created = [ + 'oe_description_list' => [ + 'oe_w_orientation' => 'horizontal', + ], + 'oe_facts_figures' => [ + 'oe_w_n_columns' => '3', + ], + 'oe_links_block' => [ + 'oe_w_links_block_orientation' => 'vertical', + 'oe_w_links_block_background' => 'gray', + ], + 'oe_links_block:modified' => [ + 'oe_w_links_block_orientation' => 'horizontal', + 'oe_w_links_block_background' => 'gray', + ], + 'oe_social_media_follow' => [ + 'oe_w_links_block_background' => 'gray', + ], + ]; + + $expected_deleted = [ + 'oe_description_list' => [ + 'oe_bt_orientation' => TRUE, + ], + 'oe_facts_figures' => [ + 'oe_bt_n_columns' => TRUE, + ], + 'oe_links_block' => [ + 'oe_bt_links_block_orientation' => TRUE, + 'oe_bt_links_block_background' => TRUE, + ], + 'oe_links_block:modified' => [ + 'oe_bt_links_block_orientation' => TRUE, + 'oe_bt_links_block_background' => TRUE, + ], + 'oe_social_media_follow' => [ + 'oe_bt_links_block_background' => TRUE, + ], + ]; + + $storage = \Drupal::entityTypeManager()->getStorage('paragraph'); + + // Produce reports instead of many individual assertions. This is less + // simple in code, but produces more useful output on test failure. + $actual_updated = []; + $actual_deleted = []; + foreach ($revision_ids as $name => $revision_id) { + $updated_revision = $storage->loadRevision($revision_id); + $this->assertNotNull($updated_revision); + foreach ($expected_created[$name] as $field_name => $value) { + if (!$updated_revision->hasField($field_name)) { + // The expected field was not created. + // Omit this entry in $actual_updated, to cause a fail below. + continue; + } + // The expected field was created, but the value might be wrong. + $actual_updated[$name][$field_name] = $updated_revision->get($field_name)->value; + } + foreach ($expected_deleted[$name] as $field_name => $deleted) { + $actual_deleted[$name][$field_name] = !$updated_revision->hasField($field_name); + } + } + + // Compare the reports to the expected values. + $this->assertSame($expected_created, $actual_updated); + $this->assertSame($expected_deleted, $actual_deleted); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Functional/ParagraphsTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Functional/ParagraphsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..879560768c13361acddd02af035af3ca2e52af2f --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Functional/ParagraphsTest.php @@ -0,0 +1,330 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Functional; + +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\Tests\BrowserTestBase; + +/** + * Tests paragraphs forms. + */ +class ParagraphsTest extends BrowserTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'oe_whitelabel_paragraphs', + ]; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->createTestContentType(); + $this->drupalLogin($this->drupalCreateUser([], '', TRUE)); + } + + /** + * Test Links Block paragraphs form. + */ + public function testLinksBlockParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $this->getSession()->getPage()->pressButton('Add Links block'); + + // Assert the Links Block fields appears. + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_links][0][uri]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_links][0][title]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_text][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][oe_w_links_block_background]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][oe_w_links_block_orientation]'); + + $this->submitForm([], 'Add another item'); + + $values = [ + 'title[0][value]' => 'Test Links block node title', + 'oe_w_paragraphs[0][subform][field_oe_text][0][value]' => 'EU Links', + 'oe_w_paragraphs[0][subform][field_oe_links][0][uri]' => 'https://www.example.com', + 'oe_w_paragraphs[0][subform][field_oe_links][0][title]' => 'Example link number 1', + 'oe_w_paragraphs[0][subform][field_oe_links][1][uri]' => 'https://www.more-example.com', + 'oe_w_paragraphs[0][subform][field_oe_links][1][title]' => 'Example link number 2', + 'oe_w_paragraphs[0][subform][oe_w_links_block_background]' => 'gray', + 'oe_w_paragraphs[0][subform][oe_w_links_block_orientation]' => 'vertical', + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are printed. + $this->assertSession()->pageTextContains('EU Links'); + $this->assertSession()->pageTextContains('Example link number 1'); + $this->assertSession()->pageTextContains('Example link number 2'); + } + + /** + * Test Social media follow paragraphs form. + */ + public function testSocialMediaFollowParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $this->getSession()->getPage()->pressButton('Add Social media follow'); + + // Assert the Social Media Follow fields appears. + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_links][0][uri]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_links][0][title]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_links][0][link_type]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_title][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][oe_w_links_block_background]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_variant]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_see_more][0][uri]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_social_media_see_more][0][title]'); + + $this->submitForm([], 'Add another item'); + + $values = [ + 'title[0][value]' => 'Test Social Media follow Links node title', + 'oe_w_paragraphs[0][subform][field_oe_title][0][value]' => 'EU Social Media Follow Links', + 'oe_w_paragraphs[0][subform][field_oe_social_media_links][0][uri]' => 'https://www.facebook.com', + 'oe_w_paragraphs[0][subform][field_oe_social_media_links][0][title]' => 'Example Facebook', + 'oe_w_paragraphs[0][subform][field_oe_social_media_links][0][link_type]' => 'facebook', + 'oe_w_paragraphs[0][subform][oe_w_links_block_background]' => 'transparent', + 'oe_w_paragraphs[0][subform][field_oe_social_media_variant]' => 'horizontal', + 'oe_w_paragraphs[0][subform][field_oe_social_media_see_more][0][uri]' => 'https://example.com', + 'oe_w_paragraphs[0][subform][field_oe_social_media_see_more][0][title]' => 'More channels', + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are printed. + $this->assertSession()->pageTextContains('EU Social Media Follow Links'); + $this->assertSession()->pageTextContains('Example Facebook'); + $this->assertSession()->pageTextContains('More channels'); + } + + /** + * Test Accordion paragraphs form. + */ + public function testAccordionParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $page = $this->getSession()->getPage(); + $page->pressButton('Add Accordion'); + + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text_long][0][value]'); + // Assert the Icon field is not shown. + $this->assertSession()->fieldNotExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_icon][0][value]'); + + $values = [ + 'title[0][value]' => 'Test Accordion', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text][0][value]' => 'Title item 1', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text_long][0][value]' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are displayed correctly. + $this->assertSession()->pageTextContains('Title item 1'); + $this->assertSession()->pageTextContains('Lorem ipsum dolor sit amet, consectetur adipiscing elit.'); + } + + /** + * Test Facts and figures paragraphs form. + */ + public function testFactsFiguresParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $page = $this->getSession()->getPage(); + $page->pressButton('Add Facts and figures'); + // Assert the Facts and figures fields are present. + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_link][0][uri]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_link][0][title]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_title][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][oe_w_n_columns][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_title][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_subtitle][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_plain_text_long][0][value]'); + + $values = [ + 'title[0][value]' => 'Test Fact and figures node title', + 'oe_w_paragraphs[0][subform][field_oe_title][0][value]' => 'Fact and figures block', + 'oe_w_paragraphs[0][subform][field_oe_link][0][uri]' => 'https://www.google.com', + 'oe_w_paragraphs[0][subform][field_oe_link][0][title]' => 'Read more', + 'oe_w_paragraphs[0][subform][oe_w_n_columns][0][value]' => 2, + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_title][0][value]' => "1529 JIRA Ticket", + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_subtitle][0][value]' => "Jira Tickets", + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_plain_text_long][0][value]' => "Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.", + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are displayed correctly. + $this->assertSession()->pageTextContains('Fact and figures block'); + $this->assertSession()->pageTextContains('Read more'); + $this->assertSession()->pageTextContains('1529 JIRA Ticket'); + $this->assertSession()->pageTextContains('Jira Tickets'); + $this->assertSession()->pageTextContains('Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.'); + } + + /** + * Test icon options event subscriber. + */ + public function testIconOptionsEventsubscriber(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $page = $this->getSession()->getPage(); + $page->pressButton('Add Fact'); + + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_icon]'); + $allowed_values = [ + '_none', + 'arrow-down', + 'box-arrow-up', + 'arrow-up', + 'book', + 'camera', + 'check', + 'download', + 'currency-euro', + 'facebook', + 'file', + 'image', + 'info', + 'linkedin', + 'files', + 'rss', + 'search', + 'share', + 'twitter', + 'camera-video', + ]; + foreach ($allowed_values as $allowed_value) { + $this->assertSession()->elementsCount('css', 'option[value="' . $allowed_value . '"]', 1); + } + $this->assertSession()->elementsCount('css', 'select#edit-oe-w-paragraphs-0-subform-field-oe-icon option', 20); + + } + + /** + * Test Description list paragraphs form. + */ + public function testDescriptionListParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $this->getSession()->getPage()->pressButton('Add Description list'); + + $assert_session = $this->assertSession(); + $assert_session->fieldExists('oe_w_paragraphs[0][subform][field_oe_title][0][value]'); + $this->assertEquals([ + 'horizontal' => 'Horizontal', + 'vertical' => 'Vertical', + ], $this->getOptions('oe_w_paragraphs[0][subform][oe_w_orientation]')); + $assert_session->fieldExists('oe_w_paragraphs[0][subform][field_oe_description_list_items][0][term]'); + $assert_session->fieldExists('oe_w_paragraphs[0][subform][field_oe_description_list_items][0][description][value]'); + + $values = [ + 'title[0][value]' => 'Test Description list node title', + 'oe_w_paragraphs[0][subform][field_oe_title][0][value]' => 'Description list paragraph', + 'oe_w_paragraphs[0][subform][oe_w_orientation]' => 'horizontal', + 'oe_w_paragraphs[0][subform][field_oe_description_list_items][0][term]' => 'Aliquam ultricies', + 'oe_w_paragraphs[0][subform][field_oe_description_list_items][0][description][value]' => 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are displayed correctly. + $assert_session->pageTextContains('Description list paragraph'); + $assert_session->pageTextContains('Aliquam ultricies'); + $assert_session->pageTextContains('Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.'); + } + + /** + * Test Links Block paragraphs form. + */ + public function testListingParagraph(): void { + $this->drupalGet('/node/add/paragraphs_test'); + $page = $this->getSession()->getPage(); + $page->pressButton('Add Listing item block'); + + // Assert the Listing fields appears. + $this->assertSession()->fieldExists('oe_w_paragraphs[0][variant]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_title][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_list_item_block_layout]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_link][0][uri]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_title][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text_long][0][value]'); + $this->assertSession()->fieldExists('oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_meta][0][value]'); + $this->assertSession()->fieldExists('files[oe_w_paragraphs_0_subform_field_oe_paragraphs_0_subform_field_oe_image_0]'); + + $this->submitForm([], 'Add another item'); + + $values = [ + 'title[0][value]' => 'Listing node title', + 'oe_w_paragraphs[0][variant]' => 'default', + 'oe_w_paragraphs[0][subform][field_oe_title][0][value]' => 'Listing example', + 'oe_w_paragraphs[0][subform][field_oe_list_item_block_layout]' => 'two_columns', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_link][0][uri]' => 'https://www.example.com', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_title][0][value]' => 'Card title', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_text_long][0][value]' => 'Lorem Ipsum dolor sit amet.', + 'oe_w_paragraphs[0][subform][field_oe_paragraphs][0][subform][field_oe_meta][0][value]' => 'label1', + ]; + + $this->submitForm($values, 'Save'); + $this->drupalGet('/node/1'); + + // Assert paragraph values are displayed correctly. + $this->assertSession()->pageTextContains('Listing example'); + $this->assertSession()->pageTextContains('Card title'); + $this->assertSession()->pageTextContains('Lorem Ipsum dolor sit amet.'); + $this->assertSession()->pageTextContains('label1'); + } + + /** + * Creates a node type with a paragraphs field. + */ + protected function createTestContentType() { + $this->drupalCreateContentType([ + 'type' => 'paragraphs_test', + 'name' => 'Paragraphs Test', + ]); + + // Add a paragraphs field. + $field_storage = FieldStorageConfig::create([ + 'field_name' => 'oe_w_paragraphs', + 'entity_type' => 'node', + 'type' => 'entity_reference_revisions', + 'cardinality' => '-1', + 'settings' => [ + 'target_type' => 'paragraph', + ], + ]); + $field_storage->save(); + FieldConfig::create([ + 'field_storage' => $field_storage, + 'bundle' => 'paragraphs_test', + 'settings' => [ + 'handler' => 'default:paragraph', + 'handler_settings' => ['target_bundles' => NULL], + ], + ])->save(); + + $form_display = \Drupal::service('entity_display.repository')->getFormDisplay('node', 'paragraphs_test'); + $form_display = $form_display->setComponent('oe_w_paragraphs', ['type' => 'oe_paragraphs_variants']); + $form_display->save(); + + $view_display = \Drupal::service('entity_display.repository')->getViewDisplay('node', 'paragraphs_test'); + $view_display->setComponent('oe_w_paragraphs', ['type' => 'entity_reference_revisions_entity_view']); + $view_display->save(); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/AbstractKernelTestBase.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/AbstractKernelTestBase.php new file mode 100644 index 0000000000000000000000000000000000000000..437d1e649702dadc2a576cfd1ed7d2e3ae9c0706 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/AbstractKernelTestBase.php @@ -0,0 +1,104 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel; + +use Drupal\Core\Plugin\ContextAwarePluginInterface; +use Drupal\KernelTests\KernelTestBase; +use Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Traits\RenderTrait; +use Symfony\Component\Yaml\Yaml; + +/** + * Base class for theme's kernel tests. + */ +abstract class AbstractKernelTestBase extends KernelTestBase { + + use RenderTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'breakpoint', + 'image', + 'oe_bootstrap_theme_helper', + 'oe_whitelabel_helper', + 'responsive_image', + 'system', + 'ui_patterns', + 'ui_patterns_settings', + 'ui_patterns_library', + 'user', + 'node', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installSchema('system', 'sequences'); + $this->installConfig(['user']); + $this->installConfig([ + 'system', + 'image', + 'responsive_image', + 'oe_bootstrap_theme_helper', + 'oe_whitelabel_helper', + ]); + + $this->container->get('theme_installer')->install(['oe_whitelabel']); + $this->config('system.theme')->set('default', 'oe_whitelabel')->save(); + $this->container->set('theme.registry', NULL); + + // Call the install hook of the User module which creates the Anonymous user + // and User 1. This is needed because the Anonymous user is loaded to + // provide the current User context which is needed in places like route + // enhancers. + // @see CurrentUserContext::getRuntimeContexts(). + // @see EntityConverter::convert(). + module_load_include('install', 'user'); + user_install(); + } + + /** + * Get fixture content. + * + * @param string $filepath + * File path. + * + * @return array + * A set of test data. + */ + protected function getFixtureContent(string $filepath): array { + return Yaml::parse(file_get_contents(__DIR__ . "/fixtures/{$filepath}")); + } + + /** + * Builds and returns the renderable array for a block. + * + * @param string $block_id + * The ID of the block. + * @param array $config + * An array of configuration. + * + * @return array + * A renderable array representing the content of the block. + */ + protected function buildBlock(string $block_id, array $config): array { + /** @var \Drupal\Core\Block\BlockBase $plugin */ + $plugin = $this->container->get('plugin.manager.block')->createInstance($block_id, $config); + + // Inject runtime contexts. + if ($plugin instanceof ContextAwarePluginInterface) { + $contexts = $this->container->get('context.repository')->getRuntimeContexts($plugin->getContextMapping()); + $this->container->get('context.handler')->applyContextMapping($plugin, $contexts); + } + + return $plugin->build(); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bbd451ed3a54f536926ac0a4379219d92ccc3eda --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php @@ -0,0 +1,184 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\Entity\Paragraph; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the "Content row" paragraph, "Inpage navigation" variant. + */ +class ContentRowTest extends ParagraphsTestBase { + + /** + * Tests the rendering of the paragraph type. + */ + public function testWithInpageNavigationRendering(): void { + $paragraph_fact = [ + Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '1529 JIRA Ticket', + 'field_oe_subtitle' => 'Jira Tickets', + 'field_oe_plain_text_long' => 'Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.', + ]), + Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '337 Features', + 'field_oe_subtitle' => 'Feature tickets', + 'field_oe_plain_text_long' => 'Turpis varius congue venenatis, erat dui feugiat felis.', + ]), + Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '107 Tests', + 'field_oe_subtitle' => 'Test tickets', + 'field_oe_plain_text_long' => 'Cras vestibulum efficitur mi, quis porta tellus rutrum ut. Quisque at pulvinar sem.', + ]), + ]; + + $paragraph_accordion = [ + Paragraph::create([ + 'type' => 'oe_accordion_item', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_text' => 'Accordion item 1', + 'field_oe_text_long' => 'Aenean at viverra tellus. Donec egestas ut ligula a condimentum. Cras sapien nulla, ornare eget lobortis vulputate, bibendum nec tellus. Fusce tristique diam quis mauris vehicula eleifend. Maecenas vitae luctus mi. Sed accumsan fermentum fermentum. Ut tristique quam at aliquam viverra. Suspendisse pulvinar risus tristique augue elementum, nec blandit sem mattis', + ]), + Paragraph::create([ + 'type' => 'oe_accordion_item', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_text' => 'Accordion item 2', + 'field_oe_text_long' => 'Morbi pretium efficitur dolor, a vulputate sem vulputate quis. Sed dictum massa eu nulla finibus, et porta dolor efficitur. Mauris pharetra dui sed consequat faucibus. Pellentesque felis nisi, fringilla non tortor ac, laoreet feugiat ante. Curabitur vel gravida augue. Nullam erat dui, viverra a arcu non, tincidunt pulvinar tortor. Maecenas non libero consequat massa ornare posuere. Quisque ultrices ullamcorper leo, non vulputate felis vestibulum a. Nam eu tellus enim.', + ]), + Paragraph::create([ + 'type' => 'oe_accordion_item', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_text' => 'Accordion item 3', + 'field_oe_text_long' => 'Mauris accumsan vulputate imperdiet. Aenean nec metus sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum maximus placerat orci, a placerat dolor iaculis vel. Nam pulvinar elementum odio ut tempor. In fermentum neque ut placerat rutrum.', + ]), + ]; + + $sub_paragraphs = [ + Paragraph::create([ + 'type' => 'oe_rich_text', + 'field_oe_title' => 'Title rich text test 1', + 'field_oe_text_long' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ornare et elit a dictum. Maecenas lacinia eros quis eros iaculis, sit amet bibendum massa facilisis. Integer arcu nisl, fringilla nec quam vel, tincidunt maximus ex. Suspendisse ac arcu efficitur, feugiat tellus vel, viverra sapien. Etiam vitae condimentum lorem. Nulla congue ligula lacinia efficitur tempus. Duis vitae auctor enim. Nulla iaculis, diam et sagittis scelerisque, est mauris luctus sem, a imperdiet lacus diam eu dui. Morbi accumsan, augue eu gravida elementum, libero mi blandit odio, eu fringilla nunc ipsum non tellus. Suspendisse dapibus elit at lobortis pretium. Quisque vestibulum ut purus sit amet molestie. Sed eget volutpat justo, vel varius augue. Vestibulum vel risus facilisis, feugiat sem aliquam, lobortis ante.', + ]), + Paragraph::create([ + 'type' => 'oe_links_block', + 'field_oe_text' => 'Links block test', + 'oe_w_links_block_orientation' => 'vertical', + 'oe_w_links_block_background' => 'gray', + 'field_oe_links' => [ + [ + 'title' => 'Example 2', + 'uri' => 'https://example2.com', + ], + [ + 'title' => 'Example 3', + 'uri' => 'https://example3.com', + ], + [ + 'title' => 'Example 4', + 'uri' => 'https://example4.com', + ], + ], + ]), + Paragraph::create([ + 'type' => 'oe_facts_figures', + 'field_oe_title' => 'Facts and Figures test', + 'field_oe_link' => [ + 'uri' => 'https://www.readmore.com', + 'title' => 'Read more', + ], + 'field_oe_paragraphs' => $paragraph_fact, + 'field_oe_list_item_block_layout' => 3, + ]), + Paragraph::create([ + 'type' => 'oe_quote', + 'field_oe_text' => 'Quote 1', + 'field_oe_plain_text_long' => 'Maecenas id urna eleifend, elementum sapien vitae, semper massa. Curabitur mi leo, sagittis eget euismod egestas, ornare nec justo.', + ]), + Paragraph::create([ + 'type' => 'oe_social_media_follow', + 'field_oe_title' => 'Social media block', + 'field_oe_social_media_variant' => 'horizontal', + 'oe_w_links_block_background' => 'gray', + 'field_oe_social_media_links' => [ + [ + 'title' => 'Email', + 'uri' => 'mailto:example@com', + 'link_type' => 'email', + ], + [ + 'title' => 'Facebook', + 'uri' => 'https://facebook.com', + 'link_type' => 'facebook', + ], + ], + 'field_oe_social_media_see_more' => [ + 'title' => 'Other social networks', + 'uri' => 'https://europa.eu/european-union/contact/social-networks_en', + ], + ]), + Paragraph::create([ + 'type' => 'oe_accordion', + 'field_oe_paragraphs' => $paragraph_accordion, + ]), + ]; + + $paragraph = Paragraph::create([ + 'type' => 'oe_content_row', + 'field_oe_title' => 'Page content', + 'field_oe_paragraphs' => $sub_paragraphs, + 'oe_paragraphs_variant' => 'inpage_navigation', + ]); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row > div > nav.bcl-inpage-navigation')); + $this->assertCount(8, $crawler->filter('p')); + // Assert the left column navigation. + $left = $crawler->filter('div.col-md-3.d-none.d-md-block'); + $nav = $left->filter('nav.bcl-inpage-navigation'); + $this->assertCount(1, $nav); + $h5 = $nav->filter('h5'); + $this->assertSame('Page content', $h5->text()); + $ul = $left->filter('ul.nav.nav-pills.flex-column'); + $this->assertCount(1, $ul); + $links = $ul->filter('li.nav-item a.nav-link'); + $this->assertCount(3, $links); + $this->assertSame('Title rich text test 1', $links->eq(0)->text()); + $this->assertSame('Facts and Figures test', $links->eq(1)->text()); + $this->assertSame('Social media block', $links->eq(2)->text()); + // Assert the paragraphs where added into the right side column. + $content = $crawler->filter('div.col-md-9'); + $this->assertCount(1, $content); + $rich_text_title = $content->filter('h4.fw-bold.mb-4'); + $this->assertSame('Title rich text test 1', trim($rich_text_title->text())); + $links_block_title = $content->filter('h2.fw-bold.pb-3.mb-3.border-bottom'); + $this->assertSame('Links block test', $links_block_title->text()); + $facts_figures = $content->filter('div.bcl-fact-figures--default'); + $this->assertStringContainsString('Facts and Figures test', $facts_figures->filter('h2.fw-bold')->text()); + $blockquote_blockquote = $content->filter('blockquote.blockquote'); + $this->assertStringContainsString('Maecenas id urna eleifend', $blockquote_blockquote->text()); + $blockquote_footer = $content->filter('figcaption.blockquote-footer'); + $this->assertSame('Quote 1', trim($blockquote_footer->text())); + $social_media_title = $content->filter('h2.fw-bold.pb-3.mb-3.border-bottom')->eq(1); + $this->assertStringContainsString('Social media block', $social_media_title->text()); + $accordion_items = $content->filter('.accordion-item'); + $this->assertStringContainsString('Accordion item 1', $accordion_items->eq(0)->text()); + $this->assertStringContainsString('Accordion item 2', $accordion_items->eq(1)->text()); + $this->assertStringContainsString('Accordion item 3', $accordion_items->eq(2)->text()); + // Check that the wrappers where added to the correct paragraphs. + $this->assertSame('bcl-inpage-item-1', $rich_text_title->parents()->eq(0)->attr('id')); + $this->assertSame('bcl-inpage-item-6', $facts_figures->parents()->eq(0)->attr('id')); + $this->assertSame('bcl-inpage-item-8', $social_media_title->parents()->eq(1)->attr('id')); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d96781b19d9c9b1c5cdcadc5b9fcdf5859b1c1dd --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\Entity\Paragraph; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the "Description list" paragraphs. + */ +class DescriptionListTest extends ParagraphsTestBase { + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + // Create Description list paragraph with horizontal variant. + $paragraph = Paragraph::create([ + 'type' => 'oe_description_list', + 'field_oe_title' => 'Description list paragraph', + 'oe_w_orientation' => 'horizontal', + 'field_oe_description_list_items' => [ + 0 => [ + 'term' => 'Aliquam ultricies', + 'description' => 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + ], + 1 => [ + 'term' => 'Etiam lacinia', + 'description' => 'Quisque tempor sollicitudin lacinia. Morbi imperdiet nulla et nunc aliquet, vel lobortis nunc cursus. Mauris vitae hendrerit felis.', + ], + ], + ]); + $paragraph->save(); + + // Testing: Description list paragraph with horizontal variant. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('h4')); + $this->assertCount(1, $crawler->filter('dl.d-md-grid.grid-3-9')); + $this->assertCount(2, $crawler->filter('dd')); + $this->assertCount(2, $crawler->filter('dt')); + + $title = $crawler->filter('h4.fw-bold.mb-4'); + $this->assertEquals('Description list paragraph', $title->text()); + + $term_1 = $crawler->filter('dl > div:nth-child(1) > dt'); + $this->assertEquals('Aliquam ultricies', $term_1->text()); + $description_1 = $crawler->filter('dl > div:nth-child(1) + dd'); + $this->assertEquals( + 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + $description_1->text() + ); + + $term_2 = $crawler->filter('dl > div:nth-child(3) > dt'); + $this->assertEquals('Etiam lacinia', $term_2->text()); + $description_2 = $crawler->filter('dl > div:nth-child(3) + dd'); + $this->assertEquals( + 'Quisque tempor sollicitudin lacinia. Morbi imperdiet nulla et nunc aliquet, vel lobortis nunc cursus. Mauris vitae hendrerit felis.', + $description_2->text() + ); + + // Testing: Description list paragraph with vertical variant. + $paragraph->get('oe_w_orientation')->setValue('vertical'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $title = $crawler->filter('h4.fw-bold.mb-4'); + $this->assertEquals('Description list paragraph', $title->text()); + + $term_1 = $crawler->filter('dl > dt:nth-child(1)'); + $this->assertEquals('Aliquam ultricies', $term_1->text()); + $description_1 = $crawler->filter('dl > dt:nth-child(1) + dd'); + $this->assertEquals( + 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + $description_1->text() + ); + + $term_2 = $crawler->filter('dl > dt:nth-child(3)'); + $this->assertEquals('Etiam lacinia', $term_2->text()); + $description_2 = $crawler->filter('dl > dt:nth-child(3) + dd'); + $this->assertEquals( + 'Quisque tempor sollicitudin lacinia. Morbi imperdiet nulla et nunc aliquet, vel lobortis nunc cursus. Mauris vitae hendrerit felis.', + $description_2->text() + ); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/EntityReferenceRevisionTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/EntityReferenceRevisionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9f7e0668028a098635fd4aaa57ab13bc53a197a1 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/EntityReferenceRevisionTest.php @@ -0,0 +1,107 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\node\Entity\Node; +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\node\Traits\ContentTypeCreationTrait; +use Drupal\Tests\user\Traits\UserCreationTrait; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the rendering of the entity reference fields for paragraphs. + */ +class EntityReferenceRevisionTest extends ParagraphsTestBase { + + use ContentTypeCreationTrait; + use UserCreationTrait; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + + $this->createContentType([ + 'type' => 'paragraphs_test', + 'name' => 'Paragraphs Test', + ]); + $field_storage = FieldStorageConfig::create([ + 'field_name' => 'test_paragraphs', + 'entity_type' => 'node', + 'type' => 'entity_reference_revisions', + 'cardinality' => '-1', + 'settings' => [ + 'target_type' => 'paragraph', + ], + ]); + $field_storage->save(); + FieldConfig::create([ + 'field_storage' => $field_storage, + 'bundle' => 'paragraphs_test', + 'settings' => [ + 'handler' => 'default:paragraph', + 'handler_settings' => ['target_bundles' => NULL], + ], + ])->save(); + + $this->container->get('theme_installer')->install(['oe_whitelabel']); + $this->config('system.theme')->set('default', 'oe_whitelabel')->save(); + + $this->setCurrentUser($this->createUser([], '', TRUE)); + } + + /** + * Test the rendering of an entity reference revision field. + */ + public function testEntityReferenceRevisionField(): void { + $paragraph1 = Paragraph::create([ + 'type' => 'oe_links_block', + 'field_oe_text' => 'More information', + 'oe_w_links_block_orientation' => 'vertical', + 'oe_w_links_block_background' => 'gray', + 'field_oe_links' => [ + [ + 'title' => 'European Commission', + 'uri' => 'https://example.com', + ], + ], + ]); + $paragraph1->save(); + + $paragraph2 = Paragraph::create([ + 'type' => 'oe_rich_text', + 'field_oe_title' => 'Rich text example', + ]); + $paragraph2->save(); + + /** @var \Drupal\node\Entity\Node $node */ + $node = Node::create([ + 'type' => 'paragraphs_test', + 'title' => 'Test node', + 'test_paragraphs' => [$paragraph1, $paragraph2], + 'uid' => 0, + 'status' => 1, + ]); + $node->save(); + + $build = $node->get('test_paragraphs')->view(); + $html = $this->render($build); + $crawler = new Crawler($html); + + $wrappers = $crawler->filter('div.my-4'); + $this->assertCount(2, $wrappers); + $rich_text = $wrappers->eq(1); + // Assert the paragraphs where rendered. + $this->assertStringContainsString('European Commission', $wrappers->eq(0)->text()); + $this->assertStringContainsString('Rich text example', $rich_text->text()); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php new file mode 100644 index 0000000000000000000000000000000000000000..23633bad9dd45c4a7f2d8ad93965115ad1cb1021 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php @@ -0,0 +1,211 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Symfony\Component\DomCrawler\Crawler; +use Drupal\paragraphs\Entity\Paragraph; + +/** + * Tests the "Facts and Figures" paragraphs. + */ +class FactsFiguresTest extends ParagraphsTestBase { + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + // Create Fact paragraphs. + $paragraph_fact = + [ + 0 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '1529 JIRA Ticket', + 'field_oe_subtitle' => 'Jira Tickets', + 'field_oe_plain_text_long' => 'Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.', + ]), + 1 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '337 Features', + 'field_oe_subtitle' => 'Feature tickets', + 'field_oe_plain_text_long' => 'Turpis varius congue venenatis, erat dui feugiat felis.', + ]), + 2 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '107 Tests', + 'field_oe_subtitle' => 'Test tickets', + 'field_oe_plain_text_long' => 'Cras vestibulum efficitur mi, quis porta tellus rutrum ut. Quisque at pulvinar sem.', + ]), + 3 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '5670 Variants', + 'field_oe_subtitle' => 'Test variants', + 'field_oe_plain_text_long' => 'Aliquam lacinia diam eu sem malesuada, in interdum ante bibendum.', + ]), + 4 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '345 Dev Ticket', + 'field_oe_subtitle' => 'Jira ticket', + 'field_oe_plain_text_long' => 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis nec lectus tortor.', + ]), + 5 => Paragraph::create([ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '43 Components', + 'field_oe_subtitle' => 'Figma components', + 'field_oe_plain_text_long' => 'Sed efficitur bibendum rutrum. Nunc feugiat congue augue ac consectetur.', + ]), + ]; + // Create Facts and figures paragraph. + $paragraph = Paragraph::create([ + 'type' => 'oe_facts_figures', + 'field_oe_title' => 'Fact and figures block', + 'field_oe_link' => [ + 'uri' => 'https://www.readmore.com', + 'title' => 'Read more', + ], + 'oe_w_n_columns' => 3, + 'field_oe_paragraphs' => $paragraph_fact, + ]); + $paragraph->save(); + + // Testing: Facts and figures - Default layout. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.bcl-fact-figures.bcl-fact-figures--default')); + $this->assertCount(1, $crawler->filter('h2.fw-bold')); + $this->assertCount(1, $crawler->filter('div.row-cols-md-3.row')); + $this->assertCount(6, $crawler->filter('svg.bi.icon--l')); + $this->assertCount(6, $crawler->filter('h4.fw-bold')); + $this->assertCount(6, $crawler->filter('h5.fw-bold')); + $this->assertCount(6, $crawler->filter('div.col')); + + $link = $crawler->filter('a[href="https://www.readmore.com"]'); + $this->assertStringContainsString( + 'Read more', + $link->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '1529 JIRA Ticket', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) > h5.fw-bold'); + $this->assertStringContainsString( + 'Jira Tickets', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) > p'); + $this->assertStringContainsString( + 'Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.', + $description_fact->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '337 Features', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) > h5.fw-bold'); + $this->assertStringContainsString( + 'Feature tickets', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) > p'); + $this->assertStringContainsString( + 'Turpis varius congue venenatis, erat dui feugiat felis.', + $description_fact->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '107 Tests', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) > h5.fw-bold'); + $this->assertStringContainsString( + 'Test tickets', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) > p'); + $this->assertStringContainsString( + 'Cras vestibulum efficitur mi, quis porta tellus rutrum ut. Quisque at pulvinar sem.', + $description_fact->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '5670 Variants', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > h5.fw-bold'); + $this->assertStringContainsString( + 'Test variants', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > p'); + $this->assertStringContainsString( + 'Aliquam lacinia diam eu sem malesuada, in interdum ante bibendum.', + $description_fact->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '345 Dev Ticket', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > h5.fw-bold'); + $this->assertStringContainsString( + 'Jira ticket', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > p'); + $this->assertStringContainsString( + 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis nec lectus tortor.', + $description_fact->html() + ); + + $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > h4.text-capitalize.fw-bold'); + $this->assertStringContainsString( + '43 Components', + $title_fact->html() + ); + $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > h5.fw-bold'); + $this->assertStringContainsString( + 'Figma components', + $subtitle_fact->html() + ); + $description_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > p'); + $this->assertStringContainsString( + 'Sed efficitur bibendum rutrum. Nunc feugiat congue augue ac consectetur.', + $description_fact->html() + ); + + // Testing: 2 columns. + $paragraph->get('oe_w_n_columns')->setValue('2'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row-cols-md-2.row')); + + // Testing: 1 columns. + $paragraph->get('oe_w_n_columns')->setValue('1'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row-cols-md-1.row')); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/LinksBlockTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/LinksBlockTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e3cf89e73b72fe0ef1446ef1397b2a8501dc4742 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/LinksBlockTest.php @@ -0,0 +1,73 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\oe_whitelabel_paragraphs\Kernel\PatternAssertions\LinksBlockAssertion; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the "Social media follow" paragraphs. + */ +class LinksBlockTest extends LinksBlockAssertion { + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + // Create Links Block paragraph. + $paragraph = Paragraph::create([ + 'type' => 'oe_links_block', + 'field_oe_text' => 'More information', + 'oe_w_links_block_orientation' => 'vertical', + 'oe_w_links_block_background' => 'gray', + 'field_oe_links' => $this->getBlockLinks(), + ]); + $paragraph->save(); + + // Testing: LinksBlock vertical gray. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundGray($crawler); + $this->assertLinksBlockRendering($crawler); + $this->assertVerticalLinks($crawler); + + // Testing: LinksBlock horizontal gray. + $paragraph->get('oe_w_links_block_orientation')->setValue('horizontal'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundGray($crawler); + $this->assertLinksBlockRendering($crawler); + $this->assertHorizontalLinks($crawler, FALSE); + + // Testing: LinksBlock vertical transparent. + $paragraph->get('oe_w_links_block_orientation')->setValue('vertical'); + $paragraph->get('oe_w_links_block_background')->setValue('transparent'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundTransparent($crawler); + $this->assertLinksBlockRendering($crawler); + $this->assertVerticalLinks($crawler); + + // Testing: LinksBlock horizontal transparent. + $paragraph->get('oe_w_links_block_orientation')->setValue('horizontal'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundTransparent($crawler); + $this->assertLinksBlockRendering($crawler); + $this->assertHorizontalLinks($crawler, FALSE); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2fe6ab379fddbf50e35a73265d5e1ffc9277e747 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php @@ -0,0 +1,194 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\node\Entity\Node; +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\oe_whitelabel_paragraphs\Kernel\PatternAssertions\ListingAssertion; +use Drupal\Tests\TestFileCreationTrait; +use Symfony\Component\DomCrawler\Crawler; +use Drupal\Tests\node\Traits\NodeCreationTrait; +use Drupal\Tests\node\Traits\ContentTypeCreationTrait; +use Drupal\file\Entity\File; + +/** + * Tests the rendering of paragraph Listing. + */ +class ListingParagraphsTest extends ParagraphsTestBase { + + use NodeCreationTrait; + use ContentTypeCreationTrait; + use TestFileCreationTrait; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installEntitySchema('node'); + $this->installSchema('node', ['node_access']); + } + + /** + * Test List Items Block paragraph rendering. + */ + public function testListing(): void { + + // Create a sample media entity to be embedded. + $image_file = File::create([ + 'uri' => $this->getTestFiles('image')[0]->uri, + ]); + $image_file->setPermanent(); + $image_file->save(); + + $this->createContentType([ + 'type' => 'article', + 'name' => 'Article', + ]); + + $node = $this->createNode([ + 'created' => 1636977600, + 'type' => 'article', + ]); + $nid = (int) $node->id(); + + $paragraph_storage = $this->container->get('entity_type.manager')->getStorage('paragraph'); + $paragraph = $paragraph_storage->create([ + 'type' => 'oe_list_item_block', + 'oe_paragraphs_variant' => 'default', + 'field_oe_list_item_block_layout' => 'one_column', + 'field_oe_title' => 'Listing item block title', + 'field_oe_paragraphs' => $this->createListItems($image_file, $node), + ]); + $paragraph->save(); + + // Testing Default 1 col. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert = new ListingAssertion(); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertDefaultListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--default-1-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1')); + $this->assertCount(6, $crawler->filter('div.col-md-3.col-lg-2.rounded')); + $this->assertCount(6, $crawler->filter('div.col-md-9.col-lg-10')); + + // Testing Default 2 col. + $paragraph->get('field_oe_list_item_block_layout')->setValue('two_columns'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertDefaultListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--default-2-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-2')); + $this->assertCount(6, $crawler->filter('div.col-xl-3.col-md-5')); + $this->assertCount(6, $crawler->filter('div.col-xl-9.col-md-7')); + + // Testing Default 3 col. + $paragraph->get('field_oe_list_item_block_layout')->setValue('three_columns'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertDefaultListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--default-3-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-2.row-cols-xl-3')); + $this->assertCount(6, $crawler->filter('div.col-lg-4.col-md-6')); + $this->assertCount(6, $crawler->filter('div.col-lg-8.col-md-6')); + + // Testing Highlight 1 col. + $paragraph->get('oe_paragraphs_variant')->setValue('highlight'); + $paragraph->get('field_oe_list_item_block_layout')->setValue('one_column'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertHighlightListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--highlight-1-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1')); + $this->assertCount(6, $crawler->filter('div.col.mt-4-5')); + $this->assertCount(6, $crawler->filter('div.card-body')); + + // Testing Highlight 2 col. + $paragraph->get('field_oe_list_item_block_layout')->setValue('two_columns'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertHighlightListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--highlight-2-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-2')); + $this->assertCount(6, $crawler->filter('div.listing-item--highlight')); + $this->assertCount(6, $crawler->filter('div.card-body')); + + // Testing Highlight 3 col. + $paragraph->get('field_oe_list_item_block_layout')->setValue('three_columns'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $assert->assertListingRendering($crawler, $nid); + $assert->assertHighlightListingRendering($crawler, $image_file); + $this->assertCount(1, $crawler->filter('div.bcl-listing--highlight-3-col')); + $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-3')); + $this->assertCount(6, $crawler->filter('div.listing-item--highlight')); + $this->assertCount(6, $crawler->filter('div.card-body')); + } + + /** + * Assert default variant of Listing is rendering correctly. + * + * @param \Drupal\file\Entity\File $image_file + * Image file to be added to the list item. + * @param \Drupal\node\Entity\Node $node + * A Node entity. + */ + protected function createListItems(File $image_file, Node $node): array { + $items = []; + for ($i = 1; $i <= 6; $i++) { + $paragraph = Paragraph::create([ + 'type' => 'oe_list_item', + 'oe_paragraphs_variant' => 'default', + 'field_oe_title' => 'Item title ' . $i, + 'field_oe_text_long' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ut ex tristique, dignissim sem ac, bibendum est. ' . $i, + 'field_oe_link' => [ + 'uri' => 'entity:node/' . $node->id(), + 'title' => 'Example ' . $i, + ], + 'field_oe_image' => [ + 'alt' => 'Alt for image ' . $i, + 'target_id' => $image_file->id(), + ], + 'field_oe_date' => '2011-11-13', + 'field_oe_meta' => [ + 0 => [ + 'value' => 'Label 1 - ' . $i, + ], + 1 => [ + 'value' => 'Label 2 - ' . $i, + ], + ], + ]); + $paragraph->save(); + $items[$i] = $paragraph; + } + + return $items; + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b434cda9af393e61c16a8b5cb6f70e31e2e6bd3c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php @@ -0,0 +1,644 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\Core\Url; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the rendering of paragraph types with media fields. + */ +class MediaParagraphsTest extends ParagraphsTestBase { + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->container->get('module_handler')->loadInclude('oe_paragraphs_media_field_storage', 'install'); + oe_paragraphs_media_field_storage_install(FALSE); + $this->installEntitySchema('media'); + $this->installConfig([ + 'media', + 'oe_media', + 'oe_paragraphs_media', + 'media_avportal', + 'oe_media_avportal', + 'oe_paragraphs_banner', + 'oe_paragraphs_iframe_media', + 'options', + 'oe_media_iframe', + ]); + // Call the install hook of the Media module. + module_load_include('install', 'media'); + media_install(); + } + + /** + * Test 'text with featured media' paragraph rendering. + */ + public function testFeaturedMedia(): void { + $image_file = file_save_data(file_get_contents(drupal_get_path('module', 'oe_whitelabel_paragraphs') . '/tests/fixtures/example_1.jpeg'), 'public://example_1.jpeg'); + $image_file->setPermanent(); + $image_file->save(); + + $media_storage = $this->container->get('entity_type.manager')->getStorage('media'); + $media = $media_storage->create([ + 'bundle' => 'image', + 'name' => 'test image', + 'oe_media_image' => [ + 'target_id' => $image_file->id(), + 'alt' => 'Alt en', + ], + ]); + $media->save(); + + $paragraph_storage = $this->container->get('entity_type.manager')->getStorage('paragraph'); + $paragraph = $paragraph_storage->create([ + 'type' => 'oe_text_feature_media', + 'field_oe_title' => 'Media Title', + 'field_oe_plain_text_long' => 'Media Caption', + 'field_oe_media' => [ + 'target_id' => $media->id(), + ], + ]); + $paragraph->save(); + + // Testing: Image without wrapper. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(0, $crawler->filter('h3')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(1, $figure->filter('img.img-fluid')); + $this->assertCount(0, $figure->filter('iframe')); + $this->assertStringContainsString( + $image_file->getFilename(), + $figure->html() + ); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Testing: Image with wrapper aligned to left. + $paragraph->get('field_oe_text_long')->setValue('Media Full Text'); + $paragraph->get('oe_paragraphs_variant')->setValue('left_featured'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(1, $crawler->filter('h3')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(1, $figure->filter('img.img-fluid')); + $this->assertCount(0, $figure->filter('iframe')); + $this->assertStringContainsString( + $image_file->getFilename(), + $figure->html() + ); + $full_text = $crawler->filter('div.col-12.col-md-6.order-md-1'); + $this->assertEquals('Media Full Text', trim($full_text->text())); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Testing: Image with wrapper aligned to right. + $paragraph->get('field_oe_text_long')->setValue('Media Full Text'); + $paragraph->get('oe_paragraphs_variant')->setValue('right_featured'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(1, $crawler->filter('h3')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(1, $figure->filter('img.img-fluid')); + $this->assertCount(0, $figure->filter('iframe')); + $this->assertStringContainsString( + $image_file->getFilename(), + $figure->html() + ); + $full_text = $crawler->filter('div.col-12.col-md-6.order-md-2'); + $this->assertEquals('Media Full Text', trim($full_text->text())); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Create a remote video and add it to the paragraph. + $media = $media_storage->create([ + 'bundle' => 'remote_video', + 'oe_media_oembed_video' => [ + 'value' => 'https://www.youtube.com/watch?v=1-g73ty9v04', + ], + ]); + $media->save(); + $paragraph->set('field_oe_media', ['target_id' => $media->id()]); + $paragraph->save(); + + $paragraph_storage = $this->container->get('entity_type.manager')->getStorage('paragraph'); + $paragraph = $paragraph_storage->create([ + 'type' => 'oe_text_feature_media', + 'field_oe_title' => 'Media Title', + 'field_oe_plain_text_long' => 'Media Caption', + 'field_oe_media' => [ + 'target_id' => $media->id(), + ], + ]); + $paragraph->save(); + + // Testing: Iframe without wrapper. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(0, $crawler->filter('h3')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(0, $figure->filter('img.img-fluid')); + $this->assertCount(1, $figure->filter('iframe')); + // Assert remote video is rendered properly. + $video_iframe = $crawler->filter('iframe'); + $partial_iframe_url = Url::fromRoute('media.oembed_iframe', [], [ + 'query' => [ + 'url' => 'https://www.youtube.com/watch?v=1-g73ty9v04', + ], + ])->toString(); + $this->assertStringContainsString($partial_iframe_url, $video_iframe->attr('src')); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Testing: Iframe with wrapper aligned to left. + $paragraph->get('field_oe_text_long')->setValue('Media Full Text'); + $paragraph->get('oe_paragraphs_variant')->setValue('left_featured'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(1, $crawler->filter('h3')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(0, $figure->filter('img.img-fluid')); + $this->assertCount(1, $figure->filter('iframe')); + // Assert remote video is rendered properly. + $video_iframe = $crawler->filter('iframe'); + $partial_iframe_url = Url::fromRoute('media.oembed_iframe', [], [ + 'query' => [ + 'url' => 'https://www.youtube.com/watch?v=1-g73ty9v04', + ], + ])->toString(); + $this->assertStringContainsString($partial_iframe_url, $video_iframe->attr('src')); + $full_text = $crawler->filter('div.col-12.col-md-6.order-md-1'); + $this->assertEquals('Media Full Text', trim($full_text->text())); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Testing: Iframe with wrapper aligned to right. + $paragraph->get('field_oe_text_long')->setValue('Media Full Text'); + $paragraph->get('oe_paragraphs_variant')->setValue('right_featured'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(1, $crawler->filter('h3')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(0, $figure->filter('img.img-fluid')); + $this->assertCount(1, $figure->filter('iframe')); + // Assert remote video is rendered properly. + $video_iframe = $crawler->filter('iframe'); + $partial_iframe_url = Url::fromRoute('media.oembed_iframe', [], [ + 'query' => [ + 'url' => 'https://www.youtube.com/watch?v=1-g73ty9v04', + ], + ])->toString(); + $this->assertStringContainsString($partial_iframe_url, $video_iframe->attr('src')); + $full_text = $crawler->filter('div.col-12.col-md-6.order-md-2'); + $this->assertEquals('Media Full Text', trim($full_text->text())); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Create an avportal video and add it to the paragraph. + $media = $media_storage->create([ + 'bundle' => 'av_portal_video', + 'oe_media_avportal_video' => 'I-163162', + ]); + $media->save(); + $paragraph->set('field_oe_media', ['target_id' => $media->id()]); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $this->assertCount(1, $crawler->filter('h3')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1')); + $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2')); + $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9')); + $figure = $crawler->filter('figure'); + $this->assertCount(1, $figure); + $this->assertCount(0, $figure->filter('img.img-fluid')); + $this->assertCount(1, $figure->filter('iframe')); + // Assert remote video is rendered properly. + $video_iframe = $crawler->filter('iframe'); + $this->assertStringContainsString('ec.europa.eu/avservices/play.cfm?ref=I-163162', $video_iframe->attr('src')); + $full_text = $crawler->filter('div.col-12.col-md-6.order-md-2'); + $this->assertEquals('Media Full Text', trim($full_text->text())); + $this->assertEquals('Media Caption', trim($figure->filter('figcaption.bg-light.p-3')->text())); + + // Testing: Link and media title. + $paragraph->get('field_oe_text_long')->setValue('Media Full Text'); + $paragraph->get('oe_paragraphs_variant')->setValue('right_featured'); + $paragraph->get('field_oe_feature_media_title')->setValue('Text title'); + $paragraph->get('field_oe_link')->setValue([ + 'uri' => 'https://example1', + 'title' => 'Example 1', + ]); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('div.row')); + $this->assertCount(0, $crawler->filter('div.col-12.col-md-4')); + $media_title_text = $crawler->filter('h5.text-secondary'); + $this->assertEquals('Text title', trim($media_title_text->text())); + $link = $crawler->filter('a[href="https://example1"]'); + $this->assertCount(1, $link); + $this->assertEquals('Example 1', trim($link->text())); + } + + /** + * Test 'banner' paragraph rendering. + */ + public function testBanner(): void { + // Create English file. + $en_file = file_save_data(file_get_contents(drupal_get_path('module', 'oe_whitelabel_paragraphs') . '/tests/fixtures/example_1.jpeg'), 'public://example_1_en.jpeg'); + $en_file->setPermanent(); + $en_file->save(); + + // Create a media. + $media_storage = $this->container->get('entity_type.manager')->getStorage('media'); + $media = $media_storage->create([ + 'bundle' => 'image', + 'name' => 'test image en', + 'oe_media_image' => [ + 'target_id' => $en_file->id(), + 'alt' => 'Alt en', + ], + ]); + $media->save(); + + $paragraph_storage = $this->container->get('entity_type.manager')->getStorage('paragraph'); + $paragraph = $paragraph_storage->create([ + 'type' => 'oe_banner', + 'oe_paragraphs_variant' => 'oe_banner_image', + 'field_oe_title' => 'Banner', + 'field_oe_text' => 'Description', + 'field_oe_link' => [ + 'uri' => 'http://www.example.com/', + 'title' => 'Example', + ], + 'field_oe_media' => [ + 'target_id' => $media->id(), + ], + 'field_oe_banner_type' => 'hero_center', + ]); + $paragraph->save(); + + // Variant - image / Modifier - hero_center / Full width - No. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.overlay.text-center.hero')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image / Modifier - hero_left / Full width - No. + $paragraph->get('field_oe_banner_type')->setValue('hero_left'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(0, $crawler->filter('.bcl-banner.bg-lighter.text-dark.overlay.text-center.hero')); + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.overlay.hero')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image / Modifier - page_center / Full width - No. + $paragraph->get('field_oe_banner_type')->setValue('page_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.overlay.text-center')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image / Modifier - page_left / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('page_left'); + $paragraph->get('field_oe_banner_full_width')->setValue('1'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.overlay.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image-shade / Modifier - hero_center / Full width - Yes. + $paragraph->get('oe_paragraphs_variant')->setValue('oe_banner_image_shade'); + $paragraph->get('field_oe_banner_type')->setValue('hero_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.shade.text-center.hero.full-width')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image-shade / Modifier - hero_left / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('hero_left'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.shade.hero.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image-shade / Modifier - page_center / Full width - No. + $paragraph->get('field_oe_banner_type')->setValue('page_center'); + $paragraph->get('field_oe_banner_full_width')->setValue('0'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.shade.text-center')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - image-shade / Modifier - page_left / Full width - No. + $paragraph->get('field_oe_banner_type')->setValue('page_left'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.shade')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . file_create_url($en_file->getFileUri()) . ')', + $image_element->attr('style') + ); + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - default / Modifier - hero_center / Full width - No. + $paragraph->get('oe_paragraphs_variant')->setValue('default'); + $paragraph->get('field_oe_banner_type')->setValue('hero_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.text-center.hero')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Variant - default / Modifier - hero_left / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('hero_left'); + $paragraph->get('field_oe_banner_full_width')->setValue('1'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.hero.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - default / Modifier - page_center / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('page_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.text-center.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - default / Modifier - page_left / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('page_left'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-lighter.text-dark.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - primary / Modifier - hero_center / Full width - Yes. + $paragraph->get('oe_paragraphs_variant')->setValue('oe_banner_primary'); + $paragraph->get('field_oe_banner_type')->setValue('hero_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-primary.text-white.text-center.hero.full-width')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - primary / Modifier - hero_left / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('hero_left'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-primary.text-white.hero.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - primary / Modifier - page_center / Full width - Yes. + $paragraph->get('field_oe_banner_type')->setValue('page_center'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-primary.text-white.text-center.full-width')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(1, $crawler->filter('.bcl-banner.full-width')); + + // Variant - primary / Modifier - page_left / Full width - No. + $paragraph->get('field_oe_banner_type')->setValue('page_left'); + $paragraph->get('field_oe_banner_full_width')->setValue('0'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('.bcl-banner.bg-primary.text-white')); + $this->assertCount(0, $crawler->filter('.bcl-banner.hero')); + $this->assertCount(0, $crawler->filter('.bcl-banner.text-center')); + + // No image should be displayed on 'default' variant. + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(0, $image_element); + + $this->assertBannerRendering($crawler); + $this->assertCount(0, $crawler->filter('.bcl-banner.full-width')); + + // Create a media using AV Portal image and add it to the paragraph. + $media = $media_storage->create([ + 'bundle' => 'av_portal_photo', + 'oe_media_avportal_photo' => 'P-038924/00-15', + 'uid' => 0, + 'status' => 1, + ]); + + $media->save(); + + $paragraph = $paragraph_storage->create([ + 'type' => 'oe_banner', + 'oe_paragraphs_variant' => 'oe_banner_image', + 'field_oe_text' => 'Description', + 'field_oe_media' => [ + 'target_id' => $media->id(), + ], + 'field_oe_banner_type' => 'hero_center', + ]); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $image_element = $crawler->filter('.bcl-banner__image'); + $this->assertCount(1, $image_element); + $this->assertStringContainsString( + 'url(' . (file_create_url('avportal://P-038924/00-15.jpg')) . ')', + $image_element->attr('style') + ); + } + + /** + * Assert Banner is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertBannerRendering(Crawler $crawler): void { + $this->assertEquals('Banner', trim($crawler->filter('.bcl-banner__content div')->text())); + $this->assertEquals('Description', trim($crawler->filter('.bcl-banner__content p')->text())); + $this->assertCount(1, $crawler->filter('svg.bi.icon--fluid')); + $this->assertStringContainsString('Example', trim($crawler->filter('a.btn')->text())); + $this->assertStringContainsString('#chevron-right', trim($crawler->filter('a.btn')->html())); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ParagraphsTestBase.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ParagraphsTestBase.php new file mode 100644 index 0000000000000000000000000000000000000000..d40d2b5e1095f249844e7871a51526a7346b3961 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ParagraphsTestBase.php @@ -0,0 +1,97 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\ParagraphInterface; +use Drupal\Tests\oe_whitelabel_paragraphs\Kernel\AbstractKernelTestBase; + +/** + * Base class for paragraphs tests. + */ +abstract class ParagraphsTestBase extends AbstractKernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'allowed_formats', + 'datetime', + 'description_list_field', + 'entity_browser', + 'entity_reference_revisions', + 'field', + 'file', + 'file_link', + 'filter', + 'language', + 'link', + 'locale', + 'media', + 'media_avportal', + 'media_avportal_mock', + 'node', + 'oe_media', + 'oe_media_avportal', + 'oe_media_iframe', + 'oe_paragraphs', + 'oe_paragraphs_banner', + 'oe_paragraphs_description_list', + 'oe_paragraphs_iframe_media', + 'oe_paragraphs_media', + 'oe_paragraphs_media_field_storage', + 'oe_whitelabel_paragraphs', + 'options', + 'paragraphs', + 'text', + 'typed_link', + 'user', + 'views', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installEntitySchema('paragraph'); + $this->installEntitySchema('file'); + $this->installSchema('file', ['file_usage']); + $this->installSchema('locale', [ + 'locales_location', + 'locales_source', + 'locales_target', + ]); + $this->installConfig([ + 'oe_paragraphs', + 'oe_paragraphs_description_list', + 'oe_whitelabel_paragraphs', + 'filter', + 'locale', + 'language', + 'node', + ]); + } + + /** + * Render a paragraph. + * + * @param \Drupal\paragraphs\ParagraphInterface $paragraph + * Paragraph entity. + * + * @return string + * Rendered output. + * + * @throws \Exception + */ + protected function renderParagraph(ParagraphInterface $paragraph): string { + $render = \Drupal::entityTypeManager() + ->getViewBuilder('paragraph') + ->view($paragraph, 'default'); + + return $this->renderRoot($render); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/QuoteTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/QuoteTest.php new file mode 100644 index 0000000000000000000000000000000000000000..21a0dee2f6f50bb87a106281ef49500933259827 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/QuoteTest.php @@ -0,0 +1,40 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\Entity\Paragraph; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the quote paragraphs. + */ +class QuoteTest extends ParagraphsTestBase { + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + $paragraph = Paragraph::create([ + 'type' => 'oe_quote', + 'field_oe_plain_text_long' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.', + 'field_oe_text' => 'Cicero', + ]); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertCount(1, $crawler->filter('figure.text-left')); + $quote = $crawler->filter('blockquote.blockquote'); + $this->assertCount(1, $quote); + $this->assertEquals( + 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.', + trim($quote->text()) + ); + $caption = $crawler->filter('figcaption.blockquote-footer'); + $this->assertEquals('Cicero', trim($caption->text())); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..609a5bb08702ba6a5e04f611ec3345dff883696d --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php @@ -0,0 +1,121 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\filter\Entity\FilterFormat; +use Drupal\paragraphs\Entity\Paragraph; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the "Rich text" paragraphs. + */ +class RichTextTest extends ParagraphsTestBase { + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->filterFormat = FilterFormat::create([ + 'format' => 'filtered_html', + 'name' => 'Filtered HTML', + 'weight' => 0, + ]); + $this->filterFormat->save(); + } + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + $text_original = '<p id="paragraph-1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ornare et elit a dictum. Maecenas lacinia eros quis eros iaculis, sit amet bibendum massa facilisis. Integer arcu nisl, fringilla nec quam vel, tincidunt maximus ex. Suspendisse ac arcu efficitur, feugiat tellus vel, viverra sapien. Etiam vitae condimentum lorem. Nulla congue ligula lacinia efficitur tempus. Duis vitae auctor enim. Nulla iaculis, diam et sagittis scelerisque, est mauris luctus sem, a imperdiet lacus diam eu dui. Morbi accumsan, augue eu gravida elementum, libero mi blandit odio, eu fringilla nunc ipsum non tellus. Suspendisse dapibus elit at lobortis pretium. Quisque vestibulum ut purus sit amet molestie. Sed eget volutpat justo, vel varius augue. Vestibulum vel risus facilisis, feugiat sem aliquam, lobortis ante.</p><p id="paragraph-2"><strong>Bold</strong></p><p id="paragraph-3"><em>Italic</em></p><p id="paragraph-4"><a href="https://www.example-1.com">Link</a></p><p id="paragraph-5">List:</p><ul><li>option a</li><li">option b</li></ul><p id="paragraph-6">Numbered list:</p><ol><li>first option</li><li>second option</li></ol><p id="paragraph-7">Block quote:</p><blockquote><p>I am a block quote</p></blockquote>'; + $paragraph = Paragraph::create([ + 'type' => 'oe_rich_text', + 'field_oe_title' => 'Rich text example', + 'field_oe_text_long' => [ + 'value' => $text_original, + 'format' => 'filtered_html', + ], + ]); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $title = $crawler->filter('h4'); + $this->assertCount(1, $title); + $this->assertStringContainsString( + 'Rich text example', + $title->html() + ); + // Simple text. + $text = $crawler->filter('p#paragraph-1'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ornare et elit a dictum. Maecenas lacinia eros quis eros iaculis, sit amet bibendum massa facilisis. Integer arcu nisl, fringilla nec quam vel, tincidunt maximus ex. Suspendisse ac arcu efficitur, feugiat tellus vel, viverra sapien. Etiam vitae condimentum lorem. Nulla congue ligula lacinia efficitur tempus. Duis vitae auctor enim. Nulla iaculis, diam et sagittis scelerisque, est mauris luctus sem, a imperdiet lacus diam eu dui. Morbi accumsan, augue eu gravida elementum, libero mi blandit odio, eu fringilla nunc ipsum non tellus. Suspendisse dapibus elit at lobortis pretium. Quisque vestibulum ut purus sit amet molestie. Sed eget volutpat justo, vel varius augue. Vestibulum vel risus facilisis, feugiat sem aliquam, lobortis ante.', + $text->html() + ); + // Bold format. + $text = $crawler->filter('p#paragraph-2 strong'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'Bold', + $text->html() + ); + // Italic. + $text = $crawler->filter('p#paragraph-3 em'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'Italic', + $text->html() + ); + // Link. + $text = $crawler->filter('p#paragraph-4 a'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'Link', + $text->html() + ); + $this->assertStringContainsString( + 'https://www.example-1.com', + $text->attr('href') + ); + // Unordered list. + $text = $crawler->filter('ul li:nth-child(1)'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'option a', + $text->html() + ); + $text = $crawler->filter('ul li:nth-child(2)'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'option b', + $text->html() + ); + // Ordered list. + $text = $crawler->filter('ol li:nth-child(1)'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'first option', + $text->html() + ); + $text = $crawler->filter('ol li:nth-child(2)'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'second option', + $text->html() + ); + // Blcokquote. + $text = $crawler->filter('blockquote p'); + $this->assertCount(1, $text); + $this->assertStringContainsString( + 'I am a block quote', + $text->html() + ); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/SocialMediaFollowTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/SocialMediaFollowTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6834eafb575e70df09eec32c641f8dbe66977b6c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/SocialMediaFollowTest.php @@ -0,0 +1,90 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\oe_whitelabel_paragraphs\Kernel\PatternAssertions\LinksBlockAssertion; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the "Social media follow" paragraphs. + */ +class SocialMediaFollowTest extends LinksBlockAssertion { + + /** + * Tests the rendering of the paragraph type. + */ + public function testRendering(): void { + // Create social media follow paragraph with horizontal variant. + $paragraph = Paragraph::create([ + 'type' => 'oe_social_media_follow', + 'field_oe_title' => 'Social media title', + 'field_oe_social_media_variant' => 'horizontal', + 'oe_w_links_block_background' => 'gray', + 'field_oe_social_media_links' => $this->getSocialMediaLinks(), + 'field_oe_social_media_see_more' => [ + 'title' => 'Other social networks', + 'uri' => 'https://europa.eu/european-union/contact/social-networks_en', + ], + ]); + $paragraph->save(); + + // Testing: SocialMediaFollow horizontal gray. + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundGray($crawler); + $this->assertSocialMediaLinksBlockRendering($crawler); + $this->assertHorizontalLinks($crawler); + + // Verify that links are rendered. + $this->assertSocialLinks($crawler); + + // Testing: SocialMediaFollow vertical gray. + $paragraph->get('field_oe_social_media_variant')->setValue('vertical'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundGray($crawler); + $this->assertSocialMediaLinksBlockRendering($crawler); + $this->assertVerticalLinks($crawler); + + // Verify that the paragraph contains all the links. + $this->assertSocialLinks($crawler); + + // Testing: SocialMediaFollow horizontal transparent. + $paragraph->get('field_oe_social_media_variant')->setValue('horizontal'); + $paragraph->get('oe_w_links_block_background')->setValue('transparent'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundTransparent($crawler); + $this->assertSocialMediaLinksBlockRendering($crawler); + $this->assertHorizontalLinks($crawler); + + // Verify that the paragraph contains all the links. + $this->assertSocialLinks($crawler); + + // Testing: SocialMediaFollow vertical transparent. + $paragraph->get('field_oe_social_media_variant')->setValue('vertical'); + $paragraph->get('oe_w_links_block_background')->setValue('transparent'); + $paragraph->save(); + + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + $this->assertBackgroundTransparent($crawler); + $this->assertSocialMediaLinksBlockRendering($crawler); + $this->assertVerticalLinks($crawler); + + // Verify that the paragraph contains all the links. + $this->assertSocialLinks($crawler); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/TimelineParagraphTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/TimelineParagraphTest.php new file mode 100644 index 0000000000000000000000000000000000000000..490a6598af0f4bb27012b121c132d6bd6d0dae31 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/TimelineParagraphTest.php @@ -0,0 +1,157 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Paragraphs; + +use Drupal\filter\Entity\FilterFormat; +use Drupal\paragraphs\Entity\Paragraph; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Tests the rendering for timeline paragraph type. + */ +class TimelineParagraphTest extends ParagraphsTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'oe_paragraphs_timeline', + 'oe_content_timeline_field', + 'node', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->installConfig([ + 'oe_paragraphs_timeline', + 'oe_content_timeline_field', + 'node', + ]); + + // Remove the auto-paragraph and url-to-link filters from the plain text. + /** @var \Drupal\filter\Entity\FilterFormat $format */ + $format = FilterFormat::load('plain_text'); + $format->filters(); + $format->removeFilter('filter_url'); + $format->removeFilter('filter_autop'); + $format->save(); + + FilterFormat::create([ + 'format' => 'filtered_html', + 'name' => 'Filtered HTML', + 'filters' => [ + 'filter_html' => [ + 'status' => 1, + 'settings' => [ + 'allowed_html' => '<strong>', + ], + ], + ], + ])->save(); + + FilterFormat::create([ + 'format' => 'full_html', + 'name' => 'Full HTML', + ])->save(); + + $this->container->get('theme_installer')->install(['oe_whitelabel']); + $this->config('system.theme')->set('default', 'oe_whitelabel')->save(); + $this->container->set('theme.registry', NULL); + } + + /** + * Test 'timeline' paragraph rendering. + */ + public function testTimeline(): void { + $paragraph = Paragraph::create([ + 'type' => 'oe_timeline', + 'field_oe_timeline_expand' => '3', + 'field_oe_timeline' => [ + [ + 'label' => 'Label 1', + 'title' => 'Title 1', + 'body' => 'Description 1', + ], + [ + 'label' => 'Label 2', + 'title' => 'Title 2', + 'body' => '<p>Description 2</p>', + ], + [ + 'label' => 'Label 3', + 'title' => 'Title 3', + 'body' => '<p>Description <strong>3</strong></p>', + 'format' => 'plain_text', + ], + [ + 'label' => 'Label 4', + 'title' => 'Title 4', + 'body' => '<p>Description <strong>4</strong></p>', + 'format' => 'filtered_html', + ], + [ + 'label' => 'Label 5', + 'title' => 'Title 5', + 'body' => '<p>Description <strong>5</strong></p>', + 'format' => 'full_html', + ], + [ + 'label' => 'Label 6', + 'title' => 'Title 6', + 'body' => 'Description 6', + ], + ], + ]); + + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + // No heading should be rendered if the paragraph has no heading set. + $this->assertCount(0, $crawler->filter('h2.ecl-u-type-heading-2')); + $this->assertCount(1, $crawler->filter('ol.bcl-timeline')); + $this->assertCount(7, $crawler->filter('ol.bcl-timeline li')); + $this->assertCount(1, $crawler->filter('ol.bcl-timeline li .label-collapsed')); + $this->assertCount(1, $crawler->filter('ol.bcl-timeline li.bcl-timeline__item--toggle')); + $this->assertEquals('Label 1', trim($crawler->filter('ol.bcl-timeline li:nth-child(1) h5')->html())); + $this->assertEquals('Title 1', trim($crawler->filter('ol.bcl-timeline li:nth-child(1) h6')->html())); + $this->assertEquals('Description 1', trim($crawler->filter('ol.bcl-timeline li:nth-child(1) div')->html())); + $this->assertEquals('Label 2', trim($crawler->filter('ol.bcl-timeline li:nth-child(2) h5')->html())); + $this->assertEquals('Title 2', trim($crawler->filter('ol.bcl-timeline li:nth-child(2) h6')->html())); + // Explicit format "plain_text" specified. + $this->assertEquals('<p>Description 2</p>', trim($crawler->filter('ol.bcl-timeline li:nth-child(2) div')->html())); + $this->assertEquals('Label 3', trim($crawler->filter('ol.bcl-timeline li:nth-child(3) h5')->html())); + $this->assertEquals('Title 3', trim($crawler->filter('ol.bcl-timeline li:nth-child(3) h6')->html())); + $this->assertEquals('<p>Description <strong>3</strong></p>', trim($crawler->filter('ol.bcl-timeline li:nth-child(3) div')->html())); + $this->assertEquals('Label 4', trim($crawler->filter('ol.bcl-timeline li:nth-child(4) h5')->html())); + $this->assertEquals('Title 4', trim($crawler->filter('ol.bcl-timeline li:nth-child(4) h6')->html())); + // Explicit format "filtered_html" specified. + $this->assertEquals('Description <strong>4</strong>', trim($crawler->filter('ol.bcl-timeline li:nth-child(4) div')->html())); + $this->assertEquals('<p>Description <strong>5</strong></p>', trim($crawler->filter('ol.bcl-timeline li:nth-child(5) div')->html())); + $this->assertEquals('Label 5', trim($crawler->filter('ol.bcl-timeline li:nth-child(5) h5')->html())); + $this->assertEquals('Title 5', trim($crawler->filter('ol.bcl-timeline li:nth-child(5) h6')->html())); + $this->assertEquals('Label 6', trim($crawler->filter('ol.bcl-timeline li:nth-child(6) h5')->html())); + $this->assertEquals('Title 6', trim($crawler->filter('ol.bcl-timeline li:nth-child(6) h6')->html())); + // Explicit format "full_html" specified. + $this->assertEquals('Description 6', trim($crawler->filter('ol.bcl-timeline li:nth-child(6) div')->html())); + $this->assertEquals('Show more 3 items', trim($crawler->filter('button .label-collapsed')->text())); + + // Increase limit to print all the items and set timeline heading. + $paragraph->set('field_oe_timeline_expand', '7'); + $paragraph->save(); + $html = $this->renderParagraph($paragraph); + $crawler = new Crawler($html); + + // Assert rendering is updated. + $this->assertCount(6, $crawler->filter('ol.bcl-timeline li')); + $this->assertCount(0, $crawler->filter('ol.bcl-timeline label-collapsed')); + $this->assertCount(0, $crawler->filter('ol.bcl-timeline li.bcl-timeline__item--toggle')); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/LinksBlockAssertion.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/LinksBlockAssertion.php new file mode 100644 index 0000000000000000000000000000000000000000..dfde169bb942304683a9dd47c85795ec857dd7fe --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/LinksBlockAssertion.php @@ -0,0 +1,223 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\PatternAssertions; + +use Symfony\Component\DomCrawler\Crawler; + +/** + * Class for asserting links block paragraphs. + */ +class LinksBlockAssertion { + + /** + * Returns a list of link items for Social media follow paragraph. + * + * @return array + * An array of link items. + */ + protected function getSocialMediaLinks(): array { + return [ + [ + 'title' => 'Email', + 'uri' => 'mailto:example@com', + 'link_type' => 'email', + ], + [ + 'title' => 'Facebook', + 'uri' => 'https://facebook.com', + 'link_type' => 'facebook', + ], + [ + 'title' => 'Flickr', + 'uri' => 'https://www.flickr.com', + 'link_type' => 'flickr', + ], + [ + 'title' => 'Google+', + 'uri' => 'https://google.com', + 'link_type' => 'google', + ], + [ + 'title' => 'Instagram', + 'uri' => 'https://instagram.com', + 'link_type' => 'instagram', + ], + [ + 'title' => 'LinkedIn', + 'uri' => 'https://linkedin.com', + 'link_type' => 'linkedin', + ], + [ + 'title' => 'Pinterest', + 'uri' => 'https://pinterest.com', + 'link_type' => 'pinterest', + ], + [ + 'title' => 'RSS', + 'uri' => 'https://rss-example.com', + 'link_type' => 'rss', + ], + [ + 'title' => 'Storify', + 'uri' => 'https://storify.com', + 'link_type' => 'storify', + ], + [ + 'title' => '1st Twitter', + 'uri' => 'https://twitter.com', + 'link_type' => 'twitter', + ], + [ + 'title' => '2nd Twitter', + 'uri' => 'https://twitter.com', + 'link_type' => 'twitter', + ], + [ + 'title' => 'Yammer', + 'uri' => 'https://yammer.com', + 'link_type' => 'yammer', + ], + [ + 'title' => 'Youtube', + 'uri' => 'https://youtube.com', + 'link_type' => 'youtube', + ], + [ + 'title' => 'Vimeo', + 'uri' => 'https://vimeo.com', + 'link_type' => 'vimeo', + ], + ]; + } + + /** + * Returns a list of link items for Block Links paragraph. + * + * @return array + * An array of link items. + */ + protected function getBlockLinks(): array { + return [ + [ + 'title' => 'European Commission', + 'uri' => 'https://example.com', + ], + [ + 'title' => 'Priorities', + 'uri' => 'https://example.com', + ], + [ + 'title' => 'Jobs, Growth and Investment', + 'uri' => 'https://example.com', + ], + ]; + } + + /** + * Assert links from social media. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertSocialLinks(Crawler $crawler): void { + $links = $crawler->filter('ul'); + $links_html = $links->html(); + $this->assertStringContainsString('Email', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 5) = \'#email\']')); + $this->assertStringContainsString('Facebook', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 8) = \'#facebook\']')); + $this->assertStringContainsString('Flickr', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 6) = \'#flickr\']')); + $this->assertStringContainsString('Google+', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 6) = \'#google\']')); + $this->assertStringContainsString('Instagram', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 9) = \'#instagram\']')); + $this->assertStringContainsString('LinkedIn', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 8) = \'#linkedin\']')); + $this->assertStringContainsString('Pinterest', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 9) = \'#pinterest\']')); + $this->assertStringContainsString('RSS', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 3) = \'#rss\']')); + $this->assertStringContainsString('Storify', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 7) = \'#storify\']')); + $this->assertStringContainsString('1st Twitter', $links_html); + $this->assertStringContainsString('2nd Twitter', $links_html); + $this->assertCount(2, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 7) = \'#twitter\']')); + $this->assertStringContainsString('Yammer', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 6) = \'#yammer\']')); + $this->assertStringContainsString('Youtube', $links_html); + $this->assertCount(1, $crawler->filterXPath('//*[name()=\'use\' and substring(@*, string-length(@*) - 7) = \'#youtube\']')); + $this->assertStringContainsString('Other social networks', $links_html); + } + + /** + * Assert Background is gray. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertBackgroundGray(Crawler $crawler): void { + $this->assertCount(1, $crawler->filter('div.bg-light.px-4.py-3')); + } + + /** + * Assert Background is transparent. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertBackgroundTransparent(Crawler $crawler): void { + $this->assertCount(0, $crawler->filter('div.bg-light.px-4.py-3')); + } + + /** + * Assert Links Block with Social Media is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertSocialMediaLinksBlockRendering(Crawler $crawler): void { + $this->assertCount(1, $crawler->filter('h5.fw-bold.pb-3.mb-3.border-bottom')); + $this->assertCount(1, $crawler->filter('ul.ps-0.mb-0')); + $this->assertCount(15, $crawler->filter('li.list-unstyled')); + $this->assertCount(14, $crawler->filter('li.list-unstyled.me-4-5')); + } + + /** + * Assert direction is horizontal. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + * @param bool $social + * Flag to determine if is block links with social media or not. + */ + protected function assertHorizontalLinks(Crawler $crawler, $social = TRUE): void { + $this->assertCount($social ? 15 : 3, $crawler->filter('li.d-inline')); + } + + /** + * Assert direction is vertical. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertVerticalLinks(Crawler $crawler): void { + $this->assertCount(0, $crawler->filter('li.d-inline')); + } + + /** + * Assert Links Block is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + */ + protected function assertLinksBlockRendering(Crawler $crawler): void { + $this->assertCount(1, $crawler->filter('h5.fw-bold.pb-3.mb-3.border-bottom')); + $this->assertCount(1, $crawler->filter('ul.ps-0.mb-0')); + $this->assertCount(3, $crawler->filter('li.list-unstyled')); + $this->assertCount(2, $crawler->filter('li.list-unstyled.me-4-5')); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php new file mode 100644 index 0000000000000000000000000000000000000000..f032eb90a05f6f61b793fd97b477b28c7ee90232 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php @@ -0,0 +1,99 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\PatternAssertions; + +use Drupal\file\Entity\File; +use PHPUnit\Framework\Assert; +use Symfony\Component\DomCrawler\Crawler; + +/** + * Class for asserting Listing pattern. + */ +class ListingAssertion extends Assert { + + /** + * Assert default variant of Listing is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + * @param \Drupal\file\Entity\File $file + * + * Image file added to the list item. + */ + public function assertDefaultListingRendering(Crawler $crawler, File $file): void { + $this->assertCount(6, $crawler->filter('div.listing-item.border-bottom.border-md-0.border-0.card')); + $this->assertCount(6, $crawler->filter('div.mw-listing-img')); + $this->assertCount(6, $crawler->filter('div.card-body.p-0.pb-md-0.pb-3')); + $text_element = $crawler->filter('div.card-text'); + $this->assertCount(6, $text_element); + $this->assertImageRendering($crawler, $file); + } + + /** + * Assert highlight variant of Listing is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + * @param \Drupal\file\Entity\File $file + * Image file added to the list item. + */ + public function assertHighlightListingRendering(Crawler $crawler, File $file): void { + $this->assertCount(6, $crawler->filter('div.listing-item--highlight.border-0.bg-lighter.card')); + $text_element = $crawler->filter('div.card-text'); + $this->assertCount(6, $text_element); + $this->assertImageRendering($crawler, $file); + } + + /** + * Assert Listing is rendering correctly. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + * @param int $nid + * Node identifier. + */ + public function assertListingRendering(Crawler $crawler, int $nid): void { + $this->assertCount(1, $crawler->filter('div.bcl-listing')); + $this->assertCount(6, $crawler->filter('div.row-cols-1.g-4 > div.col')); + $this->assertStringContainsString('Listing item block title', trim($crawler->filter('h2.fw-bold')->text())); + $this->assertCount(6, $crawler->filter('h5.card-title')); + $link_element = $crawler->filter('a.text-underline-hover'); + $this->assertCount(6, $link_element); + $this->assertStringContainsString( + 'node/' . $nid, + $link_element->attr('href') + ); + $text_element = $crawler->filter('div.card-text'); + $this->assertStringContainsString('Item title 1', trim($crawler->filter('h5.card-title > a.text-underline-hover')->text())); + $this->assertStringContainsString('Label 1 - 1', trim($crawler->filter('span.badge')->eq(0)->text())); + $this->assertStringContainsString('Label 2 - 1', trim($crawler->filter('span.badge')->eq(1)->text())); + $this->assertStringContainsString( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ut ex tristique, dignissim sem ac, bibendum est.', + $text_element->text() + ); + } + + /** + * Assert image is rendering. + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * The DomCrawler where to check the element. + * @param \Drupal\file\Entity\File $file + * Image file added to the card. + */ + public function assertImageRendering(Crawler $crawler, File $file): void { + $image_element = $crawler->filter('.card-img-top'); + $this->assertCount(6, $image_element); + $this->assertStringContainsString( + file_url_transform_relative(file_create_url($file->getFileUri())), + $image_element->attr('src') + ); + $this->assertStringContainsString( + 'Alt for image 1', + $image_element->attr('alt') + ); + } + +} diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Traits/RenderTrait.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Traits/RenderTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..b7864898de26ee3cbc4a23d4b9206dd35ba9fd3a --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Traits/RenderTrait.php @@ -0,0 +1,30 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Kernel\Traits; + +/** + * Helper rendering trait. + */ +trait RenderTrait { + + /** + * Renders final HTML given a structured array tree. + * + * @param array $elements + * The structured array describing the data to be rendered. + * + * @return string + * The rendered HTML. + * + * @throws \Exception + * When called from inside another renderRoot() call. + * + * @see \Drupal\Core\Render\RendererInterface::render() + */ + protected function renderRoot(array &$elements): string { + return (string) $this->container->get('renderer')->renderRoot($elements); + } + +} diff --git a/oe_whitelabel.theme b/oe_whitelabel.theme index 3da1f38601b763077e2430d595823bb79a5cf0e3..5da6c190eebd347b07f207bc2265114b0e6df528 100644 --- a/oe_whitelabel.theme +++ b/oe_whitelabel.theme @@ -11,6 +11,14 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\oe_whitelabel_helper\EuropeanUnionLanguages; +// Include all files from the includes directory. +$includes_path = __DIR__ . '/includes/*.inc'; +foreach (glob($includes_path) as $filename) { + // The inspection disallowing basename() is not relevant for known paths. + // phpcs:ignore QualityAssurance.Functions.DrupalWrappers.FoundWithAlternative + require_once __DIR__ . '/includes/' . basename($filename); +} + /** * Implements hook_form_FORM_ID_alter() for facets_forms. */ diff --git a/runner.yml.dist b/runner.yml.dist index e607338df2475eb3c8c3430bedf5ddd3a1a2ba30..17e68fd13c793c6c8bfc4a1d7bff8b029f845a01 100644 --- a/runner.yml.dist +++ b/runner.yml.dist @@ -25,6 +25,7 @@ drupal: - "./vendor/bin/drush en oe_whitelabel_search -y" - "./vendor/bin/drush en oe_whitelabel_starter_news -y" - "./vendor/bin/drush en oe_whitelabel_starter_event -y" + - "./vendor/bin/drush en oe_whitelabel_paragraphs -y" - "./vendor/bin/drush en toolbar -y" - "./vendor/bin/drush theme:enable oe_whitelabel -y" - "./vendor/bin/drush theme:enable seven -y" diff --git a/templates/overrides/field/field--entity-reference-revisions--paragraph.html.twig b/templates/overrides/field/field--entity-reference-revisions--paragraph.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..e8157acd91f75c38a8ac289d6de36e387760d0c0 --- /dev/null +++ b/templates/overrides/field/field--entity-reference-revisions--paragraph.html.twig @@ -0,0 +1,13 @@ +{# +/** + * @file + * Theme override for the entity reference revisions field which allowed to use paragraphs. + * + * @see ./templates/field/field--bare.html.twig + */ +#} +{% for item in items %} + <div class="my-4"> + {{ item.content }} + </div> +{% endfor %} diff --git a/templates/paragraphs/paragraph--oe-accordion.html.twig b/templates/paragraphs/paragraph--oe-accordion.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..4f84608b0bb2a2d810ab3f530fae42acedc470f6 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-accordion.html.twig @@ -0,0 +1,11 @@ +{# +/** + * @file + * Theme override to display the 'accordion' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('accordion', { + 'items': items, +}) }} diff --git a/templates/paragraphs/paragraph--oe-banner.html.twig b/templates/paragraphs/paragraph--oe-banner.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..cbe34141aea9caf1a37c41d0812937cd60e6b54e --- /dev/null +++ b/templates/paragraphs/paragraph--oe-banner.html.twig @@ -0,0 +1,41 @@ +{# +/** + * @file + * Theme override to display the 'banner' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{% set attributes = create_attribute() %} +{% if url %} + {% set _call_to_action = { + 'label': label, + 'path': url, + 'attributes': create_attribute({ + 'class': [ + 'btn', + variant == 'primary' ? 'btn-light' : 'btn-primary', + ], + }), + 'icon': { + 'name': 'chevron-right', + 'size': 'fluid', + 'path': bcl_icon_path, + }, + } %} +{% endif %} +{% set _hero = 'hero' in pattern %} +{% set _shade = 'shade' in variant %} +{{ pattern('banner', { + 'variant': variant, + 'title': content.field_oe_title, + 'description': content.field_oe_text, + 'call_to_action': _call_to_action, + 'image': image.src, + 'hero': _hero, + 'shade': _shade, + 'full_width': full_width, + 'centered': 'center' in alignment, + 'attributes': attributes, +}) }} + diff --git a/templates/paragraphs/paragraph--oe-content-row--variant-inpage-navigation.html.twig b/templates/paragraphs/paragraph--oe-content-row--variant-inpage-navigation.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..42899b15b81c15db40d340974160616a424d8546 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-content-row--variant-inpage-navigation.html.twig @@ -0,0 +1,15 @@ +{# +/** + * @file + * Theme override to display the 'Content row' #type and 'Inpage navigation' #variant paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('inpage_navigation', { + 'title': title, + 'links': links, + 'content': content.field_oe_paragraphs, + 'full_layout': true, + 'attributes': attributes, +}) }} diff --git a/templates/paragraphs/paragraph--oe-content-row.html.twig b/templates/paragraphs/paragraph--oe-content-row.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..385a7771806fab78d395a1a4dc870c827902d210 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-content-row.html.twig @@ -0,0 +1,13 @@ +{# +/** + * @file + * Theme override to display the 'content row' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +<div class="row"> + <div class="col-md-12"> + {{ content.field_oe_paragraphs }} + </div> +</div> diff --git a/templates/paragraphs/paragraph--oe-description-list.html.twig b/templates/paragraphs/paragraph--oe-description-list.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..a78c5d6e4fdb5aa33b7c19fb0e75022ab2ebb7bb --- /dev/null +++ b/templates/paragraphs/paragraph--oe-description-list.html.twig @@ -0,0 +1,17 @@ +{# +/** + * @file + * Theme override to display the 'Description list' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} + +{% if title is not empty %} + <h4 class="fw-bold mb-4">{{ title }}</h4> +{% endif %} + +{{ pattern('description_list', { + 'items': items, + 'orientation': orientation, +}) }} diff --git a/templates/paragraphs/paragraph--oe-facts-figures.html.twig b/templates/paragraphs/paragraph--oe-facts-figures.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..31ede665604ea586e47ed521e721e1b2fe0b04bc --- /dev/null +++ b/templates/paragraphs/paragraph--oe-facts-figures.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Theme override to display the 'Facts and Figures' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('fact_figures', { + 'title': title|default(''), + 'items': items, + 'columns': columns, + 'link': link_more, +}) }} diff --git a/templates/paragraphs/paragraph--oe-links-block.html.twig b/templates/paragraphs/paragraph--oe-links-block.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..36eee1905965f5128c006672c0871930439b81cd --- /dev/null +++ b/templates/paragraphs/paragraph--oe-links-block.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Theme override to display the 'links block' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('links_block', { + 'orientation': orientation, + 'background': background, + 'title': title, + 'links': links, +}) }} diff --git a/templates/paragraphs/paragraph--oe-list-item-block.html.twig b/templates/paragraphs/paragraph--oe-list-item-block.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..22c1a716cd588d2b841aaed68f63e07022756f08 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-list-item-block.html.twig @@ -0,0 +1,16 @@ +{# +/** + * @file + * Theme override to display the 'List item block' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('listing', { + 'variant': variant, + 'columns': columns, + 'items': items, + 'link': link, + 'title': title, +}) }} + diff --git a/templates/paragraphs/paragraph--oe-quote.html.twig b/templates/paragraphs/paragraph--oe-quote.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..a01bbbe7d273ad7da6b2af071070751173cc4a90 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-quote.html.twig @@ -0,0 +1,12 @@ +{# +/** + * @file + * Theme override to display the 'quote' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('blockquote', { + 'quote': content.field_oe_plain_text_long, + 'attribution': content.field_oe_text, +}) }} diff --git a/templates/paragraphs/paragraph--oe-rich-text.html.twig b/templates/paragraphs/paragraph--oe-rich-text.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..8024655618529752a8a8f7b5c77c4af940ce6248 --- /dev/null +++ b/templates/paragraphs/paragraph--oe-rich-text.html.twig @@ -0,0 +1,10 @@ +{# +/** + * @file + * Theme override to display the 'rich text' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +<h4 class="fw-bold mb-4">{{ content.field_oe_title }}</h4> +{{ content|without('field_oe_title') }} diff --git a/templates/paragraphs/paragraph--oe-social-media-follow.html.twig b/templates/paragraphs/paragraph--oe-social-media-follow.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..36eee1905965f5128c006672c0871930439b81cd --- /dev/null +++ b/templates/paragraphs/paragraph--oe-social-media-follow.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Theme override to display the 'links block' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ pattern('links_block', { + 'orientation': orientation, + 'background': background, + 'title': title, + 'links': links, +}) }} diff --git a/templates/paragraphs/paragraph--oe-text-feature-media.html.twig b/templates/paragraphs/paragraph--oe-text-feature-media.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..ff2a4d42828b4913429b128e930a98533ee6c22d --- /dev/null +++ b/templates/paragraphs/paragraph--oe-text-feature-media.html.twig @@ -0,0 +1,25 @@ +{# +/** + * @file + * Theme override to display the 'featured_media' type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} + +{% if not paragraph.field_oe_link.isEmpty %} + {# Add cache info from the Link field to the page. #} + {% set bubble_cache = content.field_oe_link|render %} +{% endif %} + +{{ pattern('featured_media', { + 'embedded_media': embedded_media, + 'image': image, + 'ratio': ratio, + 'text_position': text_position, + 'title': not paragraph.field_oe_title.isEmpty ? content.field_oe_title, + 'subtitle': not paragraph.field_oe_feature_media_title.isEmpty ? content.field_oe_feature_media_title, + 'caption': not paragraph.field_oe_plain_text_long.isEmpty ? content.field_oe_plain_text_long, + 'text': not paragraph.field_oe_text_long.isEmpty ? content.field_oe_text_long, + 'link': link|default([]), +}) }} diff --git a/templates/paragraphs/paragraph--oe-timeline--default.html.twig b/templates/paragraphs/paragraph--oe-timeline--default.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..813ac0dd257882e9c17c431a5fc00efce76beafe --- /dev/null +++ b/templates/paragraphs/paragraph--oe-timeline--default.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Theme override to display the 'timeline' #type paragraph. + * + * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig + */ +#} +{{ + pattern('timeline', { + hide_from: hide_from, + items: content.items, + }) +}}