diff --git a/modules/oe_whitelabel_helper/oe_whitelabel_helper.module b/modules/oe_whitelabel_helper/oe_whitelabel_helper.module
old mode 100644
new mode 100755
index 6874592cc..9d69802fd
--- a/modules/oe_whitelabel_helper/oe_whitelabel_helper.module
+++ b/modules/oe_whitelabel_helper/oe_whitelabel_helper.module
@@ -7,9 +7,68 @@
declare(strict_types = 1);
+use Drupal\Core\Template\Attribute;
+
/**
* Implements hook_locale_translation_projects_alter().
*/
function oe_whitelabel_helper_locale_translation_projects_alter(&$projects) {
$projects['oe_whitelabel_helper']['info']['interface translation server pattern'] = drupal_get_path('module', 'oe_whitelabel_helper') . '/translations/%project-%language.po';
}
+
+/**
+ * Theme preprocess function for grid_field_formatter.
+ *
+ * This function essentially extends the core field module theming methods, in
+ * particular template_preprocess_field. It also introduces new field template
+ * suggestions such as:
+ * - field--two-column.tpl.php
+ * - field--two-column--[FIELD_TYPE].tpl.php
+ * - field--two-column--[FIELD_NAME].tpl.php
+ * - field--two-column--[FIELD_NAME]--[BUNDLE].tpl.php.
+ *
+ * @see field--two-column.tpl.php
+ */
+function oe_whitelabel_helper_field_formatter(&$variables, $hook) {
+ // Extend the core field module theming functions.
+ template_preprocess_field($variables, $hook);
+
+ // Add colummns number.
+ $number_of_columns = $variables['element']['#columns'];
+ $variables['columns'] = $number_of_columns;
+
+ // Build row attributes.
+ $variables['row_attributes'] = new Attribute([
+ 'class' => ['row'],
+ ]);
+
+ // Build column layout number.
+ $variables['column_layout'] = floor(12 / $number_of_columns);
+}
+
+/**
+ * Implements hook_theme_suggestions_HOOK().
+ */
+function oe_whitelabel_helper_theme_suggestions_field__two_column(array $variables) {
+ $suggestions = [];
+ $element = $variables['element'];
+
+ $suggestions[] = 'field__two_column' . $element['#field_type'];
+ $suggestions[] = 'field__two_column' . $element['#field_name'];
+ $suggestions[] = 'field__two_column' . $element['#entity_type'] . '__' . $element['#bundle'];
+ $suggestions[] = 'field__two_column' . $element['#entity_type'] . '__' . $element['#field_name'];
+ $suggestions[] = 'field__two_column' . $element['#entity_type'] . '__' . $element['#field_name'] . '__' . $element['#bundle'];
+
+ return $suggestions;
+}
+
+/**
+ * Implements hook_theme().
+ */
+function oe_whitelabel_helper_theme() {
+ return [
+ 'field_oe_whitelabel_double_column_formatter' => [
+ 'render element' => 'element',
+ ],
+ ];
+}
diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/MultiColumn.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/MultiColumn.php
new file mode 100644
index 000000000..4e642469e
--- /dev/null
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/MultiColumn.php
@@ -0,0 +1,272 @@
+moduleHandler = $module_handler;
+ $this->entityFieldManager = $entity_field_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $plugin_id,
+ $plugin_definition,
+ $configuration['group'],
+ $configuration['settings'],
+ $configuration['label'],
+ $container->get('module_handler'),
+ $container->get('entity_field.manager')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function defaultContextSettings($context): array {
+ return [
+ 'first_column' => '',
+ 'second_column' => '',
+ 'hide_table_if_empty' => FALSE,
+ ] + parent::defaultSettings();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function settingsForm(): array {
+ $form = parent::settingsForm();
+
+ $form['first_column'] = [
+ '#title' => $this->t('First column classes'),
+ '#description' => $this->t('Add custom classes to the first column.'),
+ '#type' => 'textfield',
+ '#default_value' => $this->getSetting('first_column'),
+ ];
+ $form['second_column'] = [
+ '#title' => $this->t('Second column classes'),
+ '#description' => $this->t('Add custom classes to the second column.'),
+ '#type' => 'textfield',
+ '#default_value' => $this->getSetting('second_column'),
+ ];
+
+ $form['hide_table_if_empty'] = [
+ '#title' => $this->t('Hide the table if empty'),
+ '#description' => $this->t('Do not output any table or container markup if there are no rows with values.'),
+ '#type' => 'checkbox',
+ '#default_value' => $this->getSetting('hide_table_if_empty'),
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function settingsSummary(): array {
+ $summary = parent::settingsSummary();
+ $summary[] = $this->t('Display results as a 2 column table.');
+
+ return $summary;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function preRender(&$element, $rendering_object): void {
+ parent::preRender($element, $rendering_object);
+
+ $element['#mode'] = $this->context;
+ // Allow modules to alter the rows, useful for removing empty rows.
+ $children = Element::children($element, TRUE);
+ $this->moduleHandler->alter('field_group_table_rows', $element, $children);
+
+ if ($this->getSetting('hide_table_if_empty')) {
+ field_group_remove_empty_display_groups($element, []);
+ if ($element == []) {
+ return;
+ }
+ }
+
+ // Elements wrapper.
+ $element['#type'] = 'container';
+ $element['#attributes']['class'][] = 'my-3';
+
+ // Print the fieldset title.
+ $element['fieldset_title']['#type'] = 'markup';
+ $element['fieldset_title']['#markup'] = '
' . $this->group->label . ' ';
+
+ // Fieldset data container.
+ $element['fieldset']['data']['#type'] = 'container';
+ $element['fieldset']['data']['#attributes']['class'][] = 'row';
+
+ // Set additional classes per column.
+ $classes = ['col-12', 'col-md-6'];
+ if ($this->getSetting('first_column')) {
+ $first_column_classes = array_merge($classes, [$this->getSetting('first_column')]);
+ }
+
+ if ($this->getSetting('second_column')) {
+ $second_column_classes = array_merge($classes, [$this->getSetting('second_column')]);
+ }
+ // Columns container.
+ $element['fieldset']['data']['first_column']['#type'] = 'container';
+ $element['fieldset']['data']['first_column']['#attributes'] = [
+ 'class' => $this->getSetting('first_column') ? $first_column_classes : $classes,
+ ];
+ $element['fieldset']['data']['second_column']['#type'] = 'container';
+ $element['fieldset']['data']['second_column']['#attributes'] = [
+ 'class' => $this->getSetting('second_column') ? $second_column_classes : $classes,
+ ];
+
+ $this->buildFieldsetColumns($element, $children);
+ }
+
+ /**
+ * Build the columns of the fieldset.
+ */
+ protected function buildFieldsetColumns(array &$element, array $children): void {
+ // Number of items in the first columns.
+ $first_column_elements = array_slice($children, 0, ceil(count($children) / 2));
+ // Build fieldset column(s).
+ foreach ($children as $key => $field_name) {
+ $column = in_array($field_name, $first_column_elements) ? 'first_column' : 'second_column';
+ if ($row = $this->buildRow($element, $field_name)) {
+ $element['fieldset']['data'][$column][$field_name] = $row;
+ }
+ unset($element[$field_name]);
+ }
+ }
+
+ /**
+ * Build the row for requested element.
+ *
+ * @param array $element
+ * Rendering array of an element.
+ * @param string $field_name
+ * The name of currently handling field.
+ *
+ * @return array
+ * Table row definition on success or an empty array otherwise.
+ */
+ protected function buildRow(array $element, string $field_name): array {
+ $item = $this->getRowItem($element, $field_name);
+ $build = [];
+
+ if (!$item) {
+ return $build;
+ }
+ $item['#attributes'] = ['class' => 'col-12 col-md-6'];
+ $build = $item;
+
+ return $build;
+ }
+
+ /**
+ * Return item definition array.
+ *
+ * @param array $element
+ * Rendering array.
+ * @param string $field_name
+ * Item field machine name.
+ *
+ * @return array
+ * Item definition array on success or empty array otherwise.
+ */
+ protected function getRowItem(array $element, string $field_name): array {
+ $item = $element[$field_name] ?? [];
+ $is_empty = !is_array($item) || !array_intersect($this->renderApiProperties, array_keys($item));
+
+ if ($is_empty && $this->getSetting('always_show_field_value') && isset($element['#entity_type'], $element['#bundle'])) {
+ $field_definitions = $this->entityFieldManager->getFieldDefinitions($element['#entity_type'], $element['#bundle']);
+ $field_definition = $field_definitions[$field_name] ?? NULL;
+
+ if ($field_definition instanceof FieldConfigInterface) {
+ $is_empty = FALSE;
+
+ $item = [
+ '#title' => $field_definition->label(),
+ '#label_display' => 'above',
+ '#markup' => Xss::filter($this->getSetting('empty_field_placeholder')),
+ ];
+ }
+ }
+
+ $item['#attributes']['class'] = ['row'];
+ return $is_empty ? [] : $item;
+ }
+
+}
diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/templates/field--two-column.html.twig b/modules/oe_whitelabel_helper/src/Plugin/field_group/templates/field--two-column.html.twig
new file mode 100755
index 000000000..700147dc5
--- /dev/null
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/templates/field--two-column.html.twig
@@ -0,0 +1,49 @@
+{#
+/**
+ * @file
+ * Default template for a field.
+ */
+#}
+{%
+ set classes = [
+ bundle|clean_class ~ '__' ~ field_name_clean|clean_class,
+ label_display == 'inline' ? 'd-flex',
+]
+%}
+{%
+ set title_classes = [
+ 'field__label',
+ 'col-12',
+ 'col-md-6',
+ label_display == 'visually_hidden' ? 'visually-hidden',
+]
+%}
+
+{% if label_hidden %}
+ {% if multiple %}
+
+ {% for item in items %}
+
{{ item.content }}
+ {% endfor %}
+
+ {% else %}
+ {% for item in items %}
+ {{ item.content }}
+ {% endfor %}
+ {% endif %}
+{% else %}
+
+
+ {{ label }}{% if label_display == 'inline' %}: {% endif %}
+
+ {% if multiple %}
+
+ {% endif %}
+ {% for item in items %}
+
{{ item.content }}
+ {% endfor %}
+ {% if multiple %}
+
+ {% endif %}
+
+{% endif %}
diff --git a/modules/oe_whitelabel_user_profile/README.md b/modules/oe_whitelabel_user_profile/README.md
new file mode 100755
index 000000000..798a6b75e
--- /dev/null
+++ b/modules/oe_whitelabel_user_profile/README.md
@@ -0,0 +1,9 @@
+# OpenEuropa Whitelabel User Profile
+
+This module offers additional functionality to the User Profile feature.
+
+Here is an overview of the features it offers:
+
+## User Profile Management block
+
+A block providing a link to the user profile management.
diff --git a/modules/oe_whitelabel_user_profile/oe_whitelabel_user_profile.info.yml b/modules/oe_whitelabel_user_profile/oe_whitelabel_user_profile.info.yml
new file mode 100755
index 000000000..c97ae2fc1
--- /dev/null
+++ b/modules/oe_whitelabel_user_profile/oe_whitelabel_user_profile.info.yml
@@ -0,0 +1,5 @@
+name: OpenEuropa Whitelabel User Profile
+type: module
+description: Adds additional functionality to the user profile.
+package: OpenEuropa Whitelabel Theme
+core_version_requirement: ^8.9 || ^9.1
diff --git a/modules/oe_whitelabel_user_profile/src/Plugin/Block/UserProfileCta.php b/modules/oe_whitelabel_user_profile/src/Plugin/Block/UserProfileCta.php
new file mode 100644
index 000000000..c5b1eae8d
--- /dev/null
+++ b/modules/oe_whitelabel_user_profile/src/Plugin/Block/UserProfileCta.php
@@ -0,0 +1,79 @@
+getConfiguration();
+ $uid = \Drupal::routeMatch()->getRawParameter('user');
+
+ $title = $this->t('Manage Profile');
+ if (!empty($config['link_title'])) {
+ $title = $config['link_title'];
+ }
+
+ $url = Url::fromUserInput("/user/{$uid}/edit");
+ $link_options = [
+ 'attributes' => [
+ 'class' => [
+ 'text-decoration-none',
+ 'text-reset',
+ ],
+ ],
+ ];
+ $url->setOptions($link_options);
+ $link = Link::fromTextAndUrl($title, $url);
+
+ return [
+ '#markup' => $link->toString(),
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockForm($form, FormStateInterface $form_state): array {
+ $form = parent::blockForm($form, $form_state);
+
+ $config = $this->getConfiguration();
+
+ $form['link_title'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Title'),
+ '#description' => $this->t('Title for the User Profile link'),
+ '#default_value' => $config['link_title'] ?? $this->t('Manage Profile'),
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockSubmit($form, FormStateInterface $form_state): void {
+ parent::blockSubmit($form, $form_state);
+ $values = $form_state->getValues();
+ $this->configuration['link_title'] = $values['link_title'];
+ }
+
+}
diff --git a/modules/oe_whitelabel_user_profile/templates/block--oe-whitelabel-user-profile.html.twig b/modules/oe_whitelabel_user_profile/templates/block--oe-whitelabel-user-profile.html.twig
new file mode 100644
index 000000000..c38d98cdc
--- /dev/null
+++ b/modules/oe_whitelabel_user_profile/templates/block--oe-whitelabel-user-profile.html.twig
@@ -0,0 +1,39 @@
+{#
+/**
+ * @file
+ * Theme override to display a block.
+ *
+ * Available variables:
+ * - plugin_id: The ID of the block implementation.
+ * - label: The configured label of the block if visible.
+ * - configuration: A list of the block's configuration values.
+ * - label: The configured label for the block.
+ * - label_display: The display settings for the label.
+ * - provider: The module or other provider that provided this block plugin.
+ * - Block plugin specific settings will also be stored here.
+ * - content: The content of this block.
+ * - attributes: array of HTML attributes populated by modules, intended to
+ * be added to the main container tag of this template.
+ * - id: A valid HTML ID and guaranteed unique.
+ * - title_attributes: Same as attributes, except applied to the main title
+ * tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ * displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ * displayed after the main title tag that appears in the template.
+ *
+ * @see template_preprocess_block()
+ */
+#}
+{%
+ set classes = [
+ 'block',
+ 'block-' ~ configuration.provider|clean_class,
+ 'block-' ~ plugin_id|clean_class,
+ ]
+%}
+
+ {% block content %}
+ {{ content }}
+ {% endblock %}
+
diff --git a/oe_whitelabel.theme b/oe_whitelabel.theme
old mode 100644
new mode 100755
index b42c7187f..a5f7f545d
--- a/oe_whitelabel.theme
+++ b/oe_whitelabel.theme
@@ -130,3 +130,54 @@ function oe_whitelabel_preprocess(&$variables) {
$variables['bcl_component_library'] = theme_get_setting('component_library') ?? 'eu';
$variables['bcl_header_style'] = theme_get_setting('header_style') ?? 'standard';
}
+
+/**
+ * Implements hook_preprocess().
+ */
+function oe_whitelabel_preprocess_pattern_card(array &$variables): void {
+ if ($variables['variant'] !== 'user_profile') {
+ return;
+ }
+
+ $variables['horizontal'] = TRUE;
+
+ // Multiple fields can be added to the same area,
+ // we need to print them inline.
+ $cards_fields = [
+ 'title',
+ 'subtitle',
+ 'content',
+ 'image',
+ ];
+
+ foreach ($cards_fields as $card_field) {
+ if (array_key_exists('#sources', $variables[$card_field])) {
+ for ($i = 0; $i < count($variables[$card_field]['#sources']); $i++) {
+ $variables[$card_field]['#sources'][$i]['#attributes']['class'][] = 'd-inline';
+ // Add margin left for the subsequent elements after the first.
+ if ($i > 0) {
+ $variables[$card_field]['#sources'][$i]['#attributes']['class'][] = 'ms-2';
+ }
+ }
+ }
+ }
+
+ $variables['title'] = [
+ 'content' => $variables['title'],
+ 'tag' => "h2",
+ 'classes' => "fw-bold",
+ ];
+
+ $variables['subtitle'] = [
+ 'content' => $variables['subtitle'],
+ 'tag' => "div",
+ 'classes' => "mb-4 mt-4 text-muted",
+ ];
+
+ $variables['image'] = [
+ 'path' => $variables['image'][0]['#markup'] ?? '',
+ 'alt' => "alt img",
+ 'position' => "top",
+ 'classes' => "card-img-top",
+ ];
+}
diff --git a/templates/patterns/card/card.ui_patterns.yml b/templates/patterns/card/card.ui_patterns.yml
new file mode 100755
index 000000000..f860557fb
--- /dev/null
+++ b/templates/patterns/card/card.ui_patterns.yml
@@ -0,0 +1,135 @@
+card:
+ label: "Card"
+ description: "A card is a flexible and extensible content container. It includes options for headers and footers, a wide variety of content, contextual background colors, and powerful display options. https://v5.getbootstrap.com/docs/5.0/components/card"
+ variants:
+ default:
+ label: Default
+ horizontal:
+ label: Horizontal
+ search:
+ label: Search
+ user_profile:
+ label: User Profile
+ settings:
+ style:
+ type: select
+ label: Card style
+ options:
+ primary: primary
+ secondary: secondary
+ success: success
+ danger: danger
+ warning: warning
+ info: info
+ light: light
+ dark: dark
+ border_variant:
+ type: select
+ label: Card border style
+ options:
+ primary: primary
+ secondary: secondary
+ success: success
+ danger: danger
+ warning: warning
+ info: info
+ light: light
+ dark: dark
+ text_color:
+ type: select
+ label: Card text color
+ options:
+ dark: dark
+ white: white
+ horizontal:
+ type: boolean
+ label: "Horizontal"
+ description: "Horizontal card"
+ preview: false
+ call_to_action_button_variant:
+ type: select
+ label: Call to action button variant
+ options:
+ primary: primary
+ secondary: secondary
+ success: success
+ danger: danger
+ warning: warning
+ info: info
+ light: light
+ dark: dark
+ fields:
+ title:
+ type: "array"
+ label: "Title"
+ description: "Card title [content, tag, classes]"
+ preview:
+ content: "Title card"
+ tag: "h5"
+ subtitle:
+ type: "array"
+ label: "Subtitle"
+ description: "Card subtitle [content, tag, classes]"
+ preview:
+ content: "Subtitle card"
+ classes: "mb-2"
+ text:
+ type: "array"
+ label: "Text"
+ description: "Card text [content, tag, classes]"
+ preview:
+ content: "Text card with longer text which is supported"
+ classes: "mb-2"
+ image:
+ type: "array"
+ label: "Image"
+ description: "Card image [path, alt, position]"
+ preview:
+ path: "https://placeimg.com/1000/500/arch"
+ alt: "Alternative text for card image"
+ position: "top"
+ rounded: 3
+ content:
+ type: "render"
+ label: "Content"
+ description: "Card content"
+ preview: "Custom action "
+ card_header:
+ type: "render"
+ label: "Card header"
+ description: "Card header content"
+ preview: "Header of card"
+ card_footer:
+ type: "render"
+ label: "Card footer"
+ description: "Card footer content"
+ preview: "Footer of card"
+ call_to_action_button:
+ type: "render"
+ label: "Call to action button"
+ description: "Add a call to action button"
+ preview: "Custom action "
+ horizontal_grid:
+ type: "array"
+ label: "Horizontal grid"
+ description: "Horizontal grid layout [left_col, right_col, gutter]"
+ extra_classes_body:
+ type: "text"
+ label: "Extra classes for card body"
+ preview: "body-class"
+ extra_classes_header:
+ type: "text"
+ label: "Extra classes for card header"
+ preview: "header-class"
+ extra_classes_footer:
+ type: "text"
+ label: "Extra classes for card footer"
+ preview: "footer-class"
+ badges:
+ type: "array"
+ label: "Badges for the card"
+ preview:
+ - label: "Primary badge"
+ - label: "Secondary badge"
+ assistive_text: "Assistive text for secondary badge"
+ rounded_pill: true
diff --git a/templates/patterns/card/pattern-card--variant-user-profile.html.twig b/templates/patterns/card/pattern-card--variant-user-profile.html.twig
new file mode 100644
index 000000000..2e36ccb92
--- /dev/null
+++ b/templates/patterns/card/pattern-card--variant-user-profile.html.twig
@@ -0,0 +1,237 @@
+{% spaceless %}
+ {# Parameters:
+ - title (object) (default: {})
+ format: {
+ content: '',
+ tag: '',
+ classes: ''
+ }
+ - subtitle (object) (default: {})
+ format: {
+ content: '',
+ tag: '',
+ classes: ''
+ }
+ - text (object) (default: {})
+ format: {
+ content: '',
+ tag: '',
+ classes: ''
+ }
+ - content (string) (default: '')
+ - image (object) (default: {})
+ format: {
+ path (string),
+ alt (string),
+ position (string)
+ rounded (integer)
+ }
+ - horizontal (boolean) (default: false)
+ - horizontal_grid (object) (default: {})
+ format: {
+ left_col_classes (default: 'col-4')
+ right_col_classes (default: 'col-8')
+ gutter (default: '')
+ }
+ - variant (string) (default: '')
+ - border_variant (string) (default: '')
+ - text_color (string) (default: '')
+ options: ['dark', 'white']
+ - card_header (string) (default: '')
+ - card_footer (string) (default: '')
+ - call_to_action_button (string) (default: '')
+ - extra_classes_body (string) (default: '')
+ - extra_classes_header (string) (default: '')
+ - extra_classes_footer (string) (default: '')
+ - badges (array of badge object) (default: [])
+ #}
+
+ {% set _title = title|default({}) %}
+ {% set _subtitle = subtitle|default({}) %}
+ {% set _text = text|default({}) %}
+ {% set _content = content|default('') %}
+ {% set _image = image|default({}) %}
+ {% set _variant = variant|default('') %}
+ {% set _horizontal = horizontal|default(false) %}
+ {% set _horizontal_grid = horizontal_grid|default({
+ left_col_classes: 'col-6 col-md-3 offset-3 offset-md-0',
+ right_col_classes: 'col-md-9'
+ }) %}
+ {% set _border_variant = border_variant|default('') %}
+ {% set _text_color = text_color|default('') %}
+ {% set _card_header = card_header|default('') %}
+ {% set _card_footer = card_footer|default('') %}
+ {% set _call_to_action_button = call_to_action_button|default('') %}
+ {% set _call_to_action_button_variant = call_to_action_button_variant|default('') %}
+ {% set _extra_classes_body = extra_classes_body|default('') %}
+ {% set _extra_classes_header = extra_classes_header|default('') %}
+ {% set _extra_classes_footer = extra_classes_footer|default('') %}
+ {% set _badges = badges|default([]) %}
+ {% set _body_classes = body_classes ? body_classes ~ ' user_profile-body' : 'user_profile-body' %}
+ {% set _classes = ['user_profile', 'border-0', 'mb-md-3'] %}
+ {% if _text_color is not empty %}
+ {% set _classes = _classes|merge(['text-' ~ _text_color]) %}
+ {% endif %}
+ {% if _variant is not empty %}
+ {% set _classes = _classes|merge(['bg-' ~ _variant]) %}
+ {% endif %}
+ {% if _border_variant is not empty %}
+ {% set _classes = _classes|merge(['border-' ~ _border_variant]) %}
+ {% endif %}
+
+ {% if _extra_classes_body is not empty %}
+ {% set _body_classes = _body_classes ~ ' ' ~ _extra_classes_body %}
+ {% endif %}
+
+ {% set _header_classes = 'user_profile-header' %}
+ {% if _extra_classes_header is not empty %}
+ {% set _header_classes = _header_classes ~ ' ' ~ _extra_classes_header %}
+ {% endif %}
+
+ {% set _footer_classes = 'user_profile-footer' %}
+ {% if _extra_classes_footer is not empty %}
+ {% set _footer_classes = _footer_classes ~ ' ' ~ _extra_classes_footer %}
+ {% endif %}
+
+ {% set _row_classes = 'row' %}
+ {% if _horizontal_grid.gutter is not empty %}
+ {% set _row_classes = _row_classes ~ ' g-' ~ _horizontal_grid.gutter %}
+ {% endif %}
+
+ {% set attributes = attributes.addClass(_classes) %}
+
+
+
+ {% if _card_header is not empty %}
+
+ {% endif %}
+ {% if _horizontal %}
+
+ {% endif %}
+ {% if _image is not empty and _image.position != 'bottom' %}
+ {% if _image.classes is not empty %}
+ {% set _img_class = _image.classes ~ ' user_profile-img-top' %}
+ {% else %}
+ {% set _img_class = 'user_profile-img-top' %}
+ {% endif %}
+ {% if _image.position == 'background' %}
+ {% set _img_class = 'user_profile-img' %}
+ {% endif %}
+ {% if _image.rounded is not empty %}
+ {% set _img_class = _img_class ~ ' rounded-' ~ _image.rounded %}
+ {% endif %}
+ {% if _horizontal %}
+
+ {% endif %}
+
+ {% if _horizontal %}
+
+ {% endif %}
+ {% if _image.position == 'background' %}
+
+ {% endif %}
+ {% endif %}
+ {% if _horizontal %}
+
+ {% endif %}
+
+ {%- if _badges is not empty and _badges is iterable -%}
+
+ {% for _badge in _badges %}
+ {% if _badge.attributes is empty %}
+ {% set _badge = _badge|merge({
+ attributes: create_attribute()
+ }) %}
+ {% endif %}
+ {% if not loop.last %}
+ {% set _badge = _badge|merge({
+ attributes: _badge.attributes.addClass('me-2')
+ })
+ %}
+ {% endif %}
+ {% include '@oe-bcl/bcl-badge/badge.html.twig' with _badge only %}
+ {% endfor %}
+
+ {%- endif -%}
+ {%- if _title is not empty -%}
+ {% set _title_tag = _title.tag ?? 'h5' %}
+ <{{ _title_tag }}
+ class='card-title{{ title.classes ? ' ' ~ title.classes }}'
+ {% if _title.attributes is not empty and _title.attributes is iterable %}
+ {% for attribute in _title.attributes %}
+ {{ create_attribute().set(attribute.name, attribute.value) }}
+ {% endfor %}
+ {% endif %}
+ >
+ {{- title.content -}}
+ {{ _title_tag }}>
+ {%- endif -%}
+ {%- if _subtitle is not empty -%}
+ {% set _subtitle_tag = _subtitle.tag ?? 'h6' %}
+ <{{ _subtitle_tag }}
+ class='card-subtitle{{ _subtitle.classes ? ' ' ~ _subtitle.classes }}'
+ >
+ {{- _subtitle.content -}}
+ {{ _subtitle_tag }}>
+ {%- endif -%}
+ {%- if _text is not empty -%}
+ {% set _text_tag = _text.tag ?? 'p' %}
+ <{{ _text_tag }}
+ class='card-text{{ _text.classes ? ' ' ~ _text.classes }}'
+ >
+ {{- _text.content -}}
+ {{ _text_tag }}>
+ {%- endif -%}
+ {%- if _content is not empty -%}
+ {{- _content -}}
+ {%- endif -%}
+
+ {% if _horizontal %}
+
+ {% endif %}
+ {% if _image is not empty %}
+ {% if _image.position == 'background' %}
+
+ {% endif %}
+ {% if _image.position == 'bottom' %}
+ {% if _horizontal %}
+
+ {% endif %}
+
+ {% if _horizontal %}
+
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% if _horizontal %}
+
+ {% endif %}
+ {% if _card_footer is not empty %}
+
+ {% endif %}
+
+
+
+
+ {{ pattern('button', {
+ variant: _call_to_action_button_variant,
+ label: _call_to_action_button,
+ }) }}
+
+
+
+{% endspaceless %}