Skip to content

Commit c717b98

Browse files
Merge pull request #337 from emulsify-ds/feat-core-3.x-updates
Release: Emulsify Core 3.x and helpful preprocesses
2 parents 5de1fe5 + fdf396b commit c717b98

25 files changed

+1018
-1139
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,3 @@
1010

1111
### Functional Testing:
1212
- [ ] Document steps that allow someone to fully test your code changes. Include screenshot and links when appropriate.
13-
14-

.github/workflows/semantic-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- name: Checkout
13-
uses: actions/checkout@v3
13+
uses: actions/checkout@v4
1414
- name: Semantic Release
1515
uses: cycjimmy/semantic-release-action@v3
1616
env:

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20
1+
24

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "emulsify-ds/emulsify-drupal",
3-
"description": "The official Drupal 10 base theme for Emulsify that generates custom themes with Storybook development + Webpack Build",
3+
"description": "The official Drupal base theme for Emulsify that generates custom themes with Storybook development + Webpack Build",
44
"type": "drupal-theme",
55
"homepage": "http://emulsify.info",
66
"license": "GPL-2.0-only",

emulsify.theme

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,15 @@
66
*/
77

88
/**
9-
* Implements hook_theme_suggestions_alter().
9+
* Place any preprocess functions in [something].inc files.
1010
*
11-
* Add form login template suggestions.
12-
*
13-
* @inheritdoc
11+
* The .theme files should contain logic for the elements in their corresponding
12+
* template directories (ie 'node.theme.inc' should modify templates in
13+
* 'templates/nodes'.)
1414
*/
15-
function emulsify_theme_suggestions_alter(&$suggestions, $variables, $hook) {
16-
if ($hook == 'field') {
17-
$suggestions[] = 'field__' . $variables['element']['#entity_type'] . '__' . $variables['element']['#field_name'];
18-
$suggestions[] = 'field__' . $variables['element']['#entity_type'] . '__' . $variables['element']['#field_name'] . '__' . $variables['element']['#bundle'] . '__' . $variables['element']['#view_mode'];
19-
}
20-
21-
if ($hook == 'form' && !empty($variables['element']['#id'])) {
22-
$suggestions[] = 'form__' . str_replace('-', '_', $variables['element']['#id']);
23-
}
24-
25-
if ($hook == 'table' && !empty($variables['attributes']['class'][0])) {
26-
$suggestions[] = 'table__' . str_replace('-', '_', $variables['attributes']['class'][0]);
27-
}
28-
29-
if ($hook == 'user') {
30-
$suggestions[] = 'user__' . $variables['elements']['#view_mode'];
31-
}
32-
33-
if ($hook == 'views_view') {
34-
$suggestions[] = 'views_view__' . $variables['view']->id();
35-
$suggestions[] = 'views_view__' . $variables['view']->id() . '__' . $variables['view']->current_display;
36-
}
37-
38-
if ($hook == 'views_view_unformatted') {
39-
$suggestions[] = 'views_view_unformatted__' . $variables['view']->id();
40-
$suggestions[] = 'views_view_unformatted__' . $variables['view']->id() . '__' . $variables['view']->current_display;
41-
}
42-
43-
if ($hook == 'views_mini_pager') {
44-
$suggestions[] = 'views_mini_pager';
45-
}
46-
}
15+
require_once dirname(__FILE__) . '/includes/field.inc';
16+
require_once dirname(__FILE__) . '/includes/form.inc';
17+
require_once dirname(__FILE__) . '/includes/layout.inc';
18+
require_once dirname(__FILE__) . '/includes/paragraphs.inc';
19+
require_once dirname(__FILE__) . '/includes/user.inc';
20+
require_once dirname(__FILE__) . '/includes/views.inc';

includes/field.inc

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Field-related hook implementations for the Emulsify theme.
6+
*/
7+
8+
use Drupal\paragraphs\ParagraphInterface;
9+
10+
/**
11+
* Implements hook_preprocess_field().
12+
*
13+
* Adds a zero-based index to each paragraph item in an
14+
* entity_reference_revisions field referencing paragraphs.
15+
*
16+
* @param array $variables
17+
* Template variables array, containing:
18+
* - field_type: The field’s base type (e.g., 'entity_reference_revisions').
19+
* - element: The render array for the field, with '#items'.
20+
* - items: An array of rendered items, each with ['content']['#paragraph'].
21+
*/
22+
function emulsify_preprocess_field(array &$variables) {
23+
// Only target entity_reference_revisions fields that point to paragraphs.
24+
if (
25+
$variables['field_type'] === 'entity_reference_revisions'
26+
&& $variables['element']['#items']->getItemDefinition()->getSetting('target_type') === 'paragraph'
27+
) {
28+
$delta = 0;
29+
foreach ($variables['items'] as $key => &$item) {
30+
// Each item’s render array should have the paragraph object.
31+
if (
32+
isset($item['content']['#paragraph'])
33+
&& $item['content']['#paragraph'] instanceof ParagraphInterface
34+
) {
35+
// Assign the index for use in Twig.
36+
$item['content']['#paragraph']->index = $delta++;
37+
}
38+
}
39+
unset($item);
40+
}
41+
}
42+
43+
/**
44+
* Implements hook_theme_suggestions_field_alter().
45+
*
46+
* Adds template suggestions for field renderings based on:
47+
* - Entity type.
48+
* - Field name.
49+
* - Bundle.
50+
* - View mode.
51+
*
52+
* Suggestions generated:
53+
* - field--[entity_type]--[field_name].html.twig
54+
* - field--[entity_type]--[field_name]--[bundle]--[view_mode].html.twig
55+
*
56+
* @param string[] $suggestions
57+
* Existing theme hook suggestions; we append ours.
58+
* @param array $variables
59+
* Template variables array, containing:
60+
* - element: The render array for the field, with metadata keys:
61+
* '#entity_type', '#field_name', '#bundle', '#view_mode'.
62+
* @param string $hook
63+
* The base hook name being invoked (should be 'field').
64+
*/
65+
function emulsify_theme_suggestions_field_alter(array &$suggestions, array $variables, $hook) {
66+
// Only act on the 'field' hook.
67+
if ($hook !== 'field') {
68+
return;
69+
}
70+
71+
// Extract metadata from the render array.
72+
$entity_type = $variables['element']['#entity_type'] ?? '';
73+
$field_name = $variables['element']['#field_name'] ?? '';
74+
$bundle = $variables['element']['#bundle'] ?? '';
75+
$view_mode = $variables['element']['#view_mode'] ?? '';
76+
77+
// Base suggestion: field--[entity_type]--[field_name].html.twig.
78+
if ($entity_type && $field_name) {
79+
$suggestions[] = "field__{$entity_type}__{$field_name}";
80+
}
81+
82+
// Detailed suggestion: field--[entity_type]--[field_name]--[bundle]--[view_mode].html.twig.
83+
if ($entity_type && $field_name && $bundle && $view_mode) {
84+
$suggestions[] = "field__{$entity_type}__{$field_name}__{$bundle}__{$view_mode}";
85+
}
86+
}

includes/form.inc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Theme hook implementations for Drupal forms.
6+
*/
7+
8+
/**
9+
* Implements hook_theme_suggestions_form_alter().
10+
*
11+
* Adds template suggestions for rendering forms by their HTML ID:
12+
* - form--<form_id>.html.twig.
13+
*
14+
* This allows you to create form-specific Twig templates, e.g.:
15+
* form--contact_form.html.twig
16+
* form--user_login_form.html.twig
17+
*
18+
* @param string[] $suggestions
19+
* An array of theme hook suggestion names. We append our custom suggestion.
20+
* @param array $variables
21+
* An associative array containing:
22+
* - element: The render array for the form, including '#id'.
23+
*/
24+
function emulsify_theme_suggestions_form_alter(array &$suggestions, array $variables) {
25+
// Check that the form render array has an '#id'.
26+
if (!empty($variables['element']['#id'])) {
27+
// Normalize the ID by converting hyphens to underscores.
28+
$form_id = str_replace('-', '_', $variables['element']['#id']);
29+
30+
// Build a suggestion key "form__<form_id>".
31+
$suggestions[] = "form__{$form_id}";
32+
}
33+
}

includes/layout.inc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Theme hook implementations for Drupal Layouts.
6+
*/
7+
8+
/**
9+
* Implements hook_preprocess_layout().
10+
*
11+
* Prepares variables for all layout templates:
12+
* - Copies the original Drupal attributes into a `container__attributes` variable.
13+
* - Extracts any CSS classes into `container__additional_classes` for easy use in Twig.
14+
*
15+
* @param array $variables
16+
* An associative array of variables passed to the template, including:
17+
* - attributes: (array) The HTML attributes for the layout container.
18+
*/
19+
function emulsify_preprocess_layout(array &$variables) {
20+
// Only proceed if 'attributes' exists and is in array form.
21+
if (!empty($variables['attributes']) && is_array($variables['attributes'])) {
22+
// Duplicate all attributes for a wrapping container element.
23+
$variables['container__attributes'] = $variables['attributes'];
24+
25+
// Pull out just the 'class' entries for additional CSS classes.
26+
$variables['container__additional_classes'] = $variables['attributes']['class'] ?? [];
27+
}
28+
}

includes/paragraphs.inc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Theme hook implementations for Drupal paragraph entities.
6+
*/
7+
8+
use Drupal\node\NodeInterface;
9+
10+
/**
11+
* Implements hook_preprocess_paragraph().
12+
*
13+
* Prepares variables for all paragraph templates:
14+
* - Exposes the paragraph index in the parent entity reference.
15+
* - Exposes the parent entity type and bundle.
16+
* - If the parent is a node, exposes the node's title.
17+
* - Copies raw attributes into container variables for use in Twig.
18+
*
19+
* @param array $variables
20+
* An associative array of variables passed to the template.
21+
*/
22+
function emulsify_preprocess_paragraph(array &$variables) {
23+
$paragraph = $variables['paragraph'];
24+
25+
// Expose the paragraph's zero-based index within its parent entity.
26+
$variables['paragraph_index'] = $paragraph->index;
27+
28+
// If the paragraph has a parent entity, expose its type & bundle.
29+
if ($parent = $paragraph->getParentEntity()) {
30+
$variables['parent_type'] = $parent->getEntityTypeId();
31+
$variables['parent_bundle'] = $parent->bundle();
32+
33+
// When that parent is a node, expose its title.
34+
if ($parent instanceof NodeInterface) {
35+
$variables['node_title'] = $parent->label();
36+
}
37+
}
38+
39+
// If raw attributes were provided, copy them for a container wrapper.
40+
if (!empty($variables['attributes']) && is_array($variables['attributes'])) {
41+
// Full attributes array for a container element.
42+
$variables['container__attributes'] = $variables['attributes'];
43+
44+
// Just the 'class' entries for additional CSS classes.
45+
$variables['container__additional_classes'] = $variables['attributes']['class'] ?? [];
46+
}
47+
}

includes/user.inc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* Theme hook implementations for Drupal user entities.
6+
*/
7+
8+
/**
9+
* Implements hook_theme_suggestions_user_alter().
10+
*
11+
* Adds template suggestions for rendering user entities by view mode:
12+
* - user--<view_mode>.html.twig.
13+
*
14+
* For example, if the user is rendered in the “compact” view mode, this will
15+
* allow you to create a template named:
16+
* user--compact.html.twig.
17+
*
18+
* @param string[] $suggestions
19+
* An array of theme hook suggestion names. We append to this.
20+
* @param array $variables
21+
* An associative array containing:
22+
* - elements: The render array for the user entity, including '#view_mode'.
23+
*/
24+
function emulsify_theme_suggestions_user_alter(array &$suggestions, array $variables) {
25+
// Ensure the view mode is available on the render array.
26+
if (isset($variables['elements']['#view_mode'])) {
27+
$view_mode = $variables['elements']['#view_mode'];
28+
29+
// Build a suggestion key in the form "user__<view_mode>".
30+
$suggestions[] = "user__{$view_mode}";
31+
}
32+
}

0 commit comments

Comments
 (0)