Skip to content

Commit 0fd9d05

Browse files
committed
Inital code commit
1 parent 88f3b83 commit 0fd9d05

5 files changed

Lines changed: 223 additions & 0 deletions

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "fosterinteractive/mainspring_responsive_image_styles",
3+
"type": "drupal-module",
4+
"license": "MIT"
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: Mainspring Responsive Image Styles
2+
type: module
3+
description: Provides custom twig function for image styles
4+
core_version_requirement: ^9 || ^10
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/**
4+
* @file
5+
* This is the mainspring_responsive_image_styles module.
6+
*
7+
* It adds the paragraphs layout configuration to paragraphs as variables.
8+
*/
9+
10+
/**
11+
* Implements hook_preprocess_paragraph().
12+
*/
13+
function mainspring_responsive_image_styles_preprocess_paragraph(array &$variables) {
14+
$paragraph = $variables['paragraph'];
15+
16+
// PARAGRAPH LAYOUT / REGION VARIABLES.
17+
// Determine the layout and region a paragraph is in so we can set a specific
18+
// reponsive image style based on the layout. e.g. if a image is in a 4 col.
19+
$behavior_settings = $paragraph->getAllBehaviorSettings();
20+
$layout_paragraphs_settings = $behavior_settings['layout_paragraphs'] ?? [];
21+
if (!empty($layout_paragraphs_settings['parent_uuid']) && $parent = $paragraph->getParentEntity()) {
22+
$parent_field = $paragraph->get('parent_field_name');
23+
$field_name = $parent_field->first()->getString();
24+
// If the parent delta is set then we can get the layout paragraph to
25+
// determine which layout is used.
26+
if (isset($layout_paragraphs_settings['parent_delta'])) {
27+
$parent_delta = $layout_paragraphs_settings['parent_delta'];
28+
$field = $paragraph->getParentEntity()->get($field_name)->get($parent_delta);
29+
if (!empty($field)) {
30+
$layout_paragraph = $field->get('entity')->getTarget()->getValue();
31+
$layout_settings = $layout_paragraph->getAllBehaviorSettings();
32+
33+
$variables['paragraph_layout'] = $layout_settings['layout_paragraphs']['layout'];
34+
$variables['paragraph_columns'] = $layout_settings['layout_paragraphs']['config']['classes']['section_layout'] ?? NULL;
35+
$variables['paragraph_region'] = $layout_paragraphs_settings['region'];
36+
}
37+
}
38+
// It seems that paragraphs presave dosn't work on the initial save of a
39+
// paragraph so a new paragraph is missing it's parent delta. If that is the
40+
// case then we can figure out what the delta is by the parent uuid.
41+
else {
42+
$parent_field = $paragraph->get('parent_field_name');
43+
$field_name = $parent_field->first()->getString();
44+
$item_list = $parent->get($field_name);
45+
/** @var \Drupal\Core\Field\EntityReferenceFieldItemList $item_list */
46+
$sibling_paragraphs = $item_list->referencedEntities();
47+
if (count($sibling_paragraphs)) {
48+
$uuid_map = [];
49+
foreach ($sibling_paragraphs as $delta => $item) {
50+
$uuid_map[$item->uuid()] = $delta;
51+
}
52+
53+
$parent_delta = $uuid_map[$layout_paragraphs_settings['parent_uuid']] ?? NULL;
54+
if (isset($parent_delta)) {
55+
$field = $paragraph->getParentEntity()->get($field_name)->get($parent_delta);
56+
if (!empty($field)) {
57+
$layout_paragraph = $field->get('entity')->getTarget()->getValue();
58+
$layout_settings = $layout_paragraph->getAllBehaviorSettings();
59+
60+
$variables['paragraph_layout'] = $layout_settings['layout_paragraphs']['layout'];
61+
$variables['paragraph_columns'] = $layout_settings['layout_paragraphs']['config']['classes']['section_layout'] ?? NULL;
62+
$variables['paragraph_region'] = $layout_paragraphs_settings['region'];
63+
}
64+
}
65+
}
66+
}
67+
}
68+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
mainspring_responsive_image_styles.twig_extension:
3+
class: Drupal\mainspring_responsive_image_styles\TwigMainspringExtension
4+
arguments: ['@theme_handler', '@messenger', '@current_user']
5+
tags:
6+
- { name: twig.extension }

src/TwigMainspringExtension.php

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
namespace Drupal\mainspring_responsive_image_styles;
4+
5+
use Drupal\Component\Discovery\DiscoveryException;
6+
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
7+
use Drupal\Component\Serialization\Yaml;
8+
use Drupal\Core\Extension\ThemeHandlerInterface;
9+
use Drupal\Core\Messenger\MessengerInterface;
10+
use Drupal\Core\Session\AccountInterface;
11+
use Drupal\Core\StringTranslation\StringTranslationTrait;
12+
use Twig\Extension\AbstractExtension;
13+
use Twig\TwigFunction;
14+
15+
/**
16+
* Responsive image styles.
17+
*/
18+
class TwigMainspringExtension extends AbstractExtension {
19+
20+
use StringTranslationTrait;
21+
22+
/**
23+
* Root file path.
24+
*
25+
* @var string
26+
*/
27+
protected $root;
28+
29+
/**
30+
* The theme handler.
31+
*
32+
* @var \Drupal\Core\Extension\ThemeHandlerInterface
33+
*/
34+
protected $themeHandler;
35+
36+
/**
37+
* The messenger.
38+
*
39+
* @var \Drupal\Core\Messenger\MessengerInterface
40+
*/
41+
protected $messenger;
42+
43+
/**
44+
* The current user.
45+
*
46+
* @var \Drupal\Core\Session\AccountInterface
47+
*/
48+
protected $currentUser;
49+
50+
/**
51+
* Constructs the TwigMainspringExtension object.
52+
*
53+
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
54+
* The theme handler.
55+
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
56+
* The messenger.
57+
* @param \Drupal\Core\Session\AccountInterface $current_user
58+
* The current user.
59+
*/
60+
public function __construct(ThemeHandlerInterface $theme_handler, MessengerInterface $messenger, AccountInterface $current_user) {
61+
$this->themeHandler = $theme_handler;
62+
$this->messenger = $messenger;
63+
$this->currentUser = $current_user;
64+
$this->root = \Drupal::root();
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function getFunctions(): array {
71+
$functions = [
72+
new TwigFunction('mainspring_responsive_image_style', [$this, 'responsiveImageStyle']),
73+
];
74+
75+
return $functions;
76+
}
77+
78+
/**
79+
* Determines responsive image style.
80+
*
81+
* @return string
82+
* The name of the responsive image style.
83+
*/
84+
public function responsiveImageStyle($layout, $section_layout, $image_style, $zone = NULL) {
85+
86+
$theme = $this->themeHandler->getDefault();
87+
$theme_info = $this->themeHandler->listInfo();
88+
$default_theme_info = $theme_info[$theme];
89+
$path = $default_theme_info->getPath();
90+
91+
$file = $path . '/' . $theme . '.responsive_image_layouts.yml';
92+
$data = [];
93+
if (file_exists($this->root . '/' . $file)) {
94+
// If a file is empty or its contents are commented out, return an empty
95+
// array instead of NULL for type consistency.
96+
try {
97+
$data = Yaml::decode(file_get_contents($file)) ?: [];
98+
}
99+
catch (InvalidDataTypeException $e) {
100+
throw new DiscoveryException("The $file contains invalid YAML", 0, $e);
101+
}
102+
}
103+
104+
$responsive_image_style = '';
105+
106+
if (isset($data[$layout][$section_layout][$image_style])) {
107+
$option = $data[$layout][$section_layout][$image_style];
108+
if (is_array($option)) {
109+
if (!empty($zone)) {
110+
$n = trim($zone, 'zone');
111+
$n = $n - 1;
112+
if (isset($option[$n])) {
113+
$responsive_image_style = $option[$n];
114+
}
115+
}
116+
else {
117+
$responsive_image_style = reset($option);
118+
}
119+
}
120+
else {
121+
$responsive_image_style = $option;
122+
}
123+
}
124+
125+
if (empty($responsive_image_style) && $this->currentUser->id() == 1) {
126+
// throw new \Exception("The reponsive image style could not be matched. Please check that the $file has a matching responsive image style set for your variables $layout $section_layout $image_style");
127+
$this->messenger->addError($this->t("The reponsive image style could not be matched. Please check that the @file has a matching responsive image style set for your variables @layout @section_layout @image_style",
128+
[
129+
'@file' => $file,
130+
'@layout' => $layout,
131+
'@section_layout' => $section_layout,
132+
'@image_style' => $image_style,
133+
]
134+
));
135+
}
136+
137+
return $responsive_image_style;
138+
}
139+
140+
}

0 commit comments

Comments
 (0)