From fd1a0d5552ee625f2f97bcc7ba7d07e273cad0f8 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 1 Jul 2026 21:38:20 +1000 Subject: [PATCH 1/4] [#246] Added focal-point image style for banner featured image. --- ...image.style.civictheme_banner_featured.yml | 23 +++++++++++ web/themes/custom/drevops/includes/banner.inc | 41 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 config/default/image.style.civictheme_banner_featured.yml diff --git a/config/default/image.style.civictheme_banner_featured.yml b/config/default/image.style.civictheme_banner_featured.yml new file mode 100644 index 00000000..5c08854c --- /dev/null +++ b/config/default/image.style.civictheme_banner_featured.yml @@ -0,0 +1,23 @@ +uuid: 1ca889fe-b7a4-4fb9-922e-76e9463b280f +langcode: en +status: true +dependencies: + module: + - focal_point +name: civictheme_banner_featured +label: 'Banner Featured Image' +effects: + 00a742ba-c206-45ad-a0aa-3ec6424ab498: + uuid: 00a742ba-c206-45ad-a0aa-3ec6424ab498 + id: focal_point_scale_and_crop + weight: 1 + data: + width: 800 + height: 800 + crop_type: focal_point + de1c7da0-031e-4b2e-9dec-384198b5d6e3: + uuid: de1c7da0-031e-4b2e-9dec-384198b5d6e3 + id: image_convert + weight: 2 + data: + extension: webp diff --git a/web/themes/custom/drevops/includes/banner.inc b/web/themes/custom/drevops/includes/banner.inc index f64c02c6..4271e899 100644 --- a/web/themes/custom/drevops/includes/banner.inc +++ b/web/themes/custom/drevops/includes/banner.inc @@ -10,6 +10,7 @@ declare(strict_types=1); use Drupal\civictheme\CivicthemeConstants; use Drupal\Component\Render\MarkupInterface; use Drupal\Core\Render\Markup; +use Drupal\media\MediaInterface; /** * Pre-process for Banner block. @@ -27,6 +28,8 @@ function _drevops_preprocess_block__civictheme_banner(array &$variables): void { return; } + _drevops_preprocess_block__civictheme_banner__featured_image($variables); + // Finds a banner type. $type = civictheme_get_field_value($block, 'field_c_b_banner_type', TRUE, CivicthemeConstants::BANNER_TYPE_DEFAULT); $route_match = \Drupal::routeMatch(); @@ -51,6 +54,44 @@ function _drevops_preprocess_block__civictheme_banner(array &$variables): void { } } +/** + * Apply a focal-point image style to the banner featured image. + * + * The base theme serves the original featured image file, leaving the browser + * to crop it with object-fit, which ignores the editor-defined focal point. + * Re-resolving the same media through a focal-point image style moves the crop + * server-side so the focal point is honoured. + * + * @see _civictheme_preprocess_block__civictheme_banner() + * @see _civictheme_preprocess_block__civictheme_banner__node() + */ +function _drevops_preprocess_block__civictheme_banner__featured_image(array &$variables): void { + if (empty($variables['featured_image'])) { + return; + } + + $block = $variables['elements']['content']['#block_content'] ?? NULL; + + $route_match = \Drupal::routeMatch(); + $node = $route_match->getParameter('node_revision') ?: $route_match->getParameter('node'); + + // A per-node featured image overrides the block-level one, mirroring the base + // theme's resolution order. + $media = !empty($node) ? civictheme_get_field_value($node, 'field_c_n_banner_featured_image', TRUE) : NULL; + if (empty($media) && !empty($block)) { + $media = civictheme_get_field_value($block, 'field_c_b_featured_image', TRUE); + } + + if (!$media instanceof MediaInterface) { + return; + } + + $featured_image = civictheme_media_image_get_variables($media, 'civictheme_banner_featured'); + if (!empty($featured_image)) { + $variables['featured_image'] = $featured_image; + } +} + /** * Pre-process breadcrumb to fix double HTML escaping issue. * From 2fb107f809dabeda7dc69c5d9a19332dcc249950 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 1 Jul 2026 21:44:17 +1000 Subject: [PATCH 2/4] Made banner featured image resolution self-contained instead of guarding on base-theme state. --- web/themes/custom/drevops/includes/banner.inc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/web/themes/custom/drevops/includes/banner.inc b/web/themes/custom/drevops/includes/banner.inc index 4271e899..169bb691 100644 --- a/web/themes/custom/drevops/includes/banner.inc +++ b/web/themes/custom/drevops/includes/banner.inc @@ -66,10 +66,6 @@ function _drevops_preprocess_block__civictheme_banner(array &$variables): void { * @see _civictheme_preprocess_block__civictheme_banner__node() */ function _drevops_preprocess_block__civictheme_banner__featured_image(array &$variables): void { - if (empty($variables['featured_image'])) { - return; - } - $block = $variables['elements']['content']['#block_content'] ?? NULL; $route_match = \Drupal::routeMatch(); From 795381b5688b7bd7b972e17c2f410239d3f80bbf Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 1 Jul 2026 21:45:08 +1000 Subject: [PATCH 3/4] Passed the build render array to featured image field lookups so cacheability metadata bubbles. --- web/themes/custom/drevops/includes/banner.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/themes/custom/drevops/includes/banner.inc b/web/themes/custom/drevops/includes/banner.inc index 169bb691..17c8c3fe 100644 --- a/web/themes/custom/drevops/includes/banner.inc +++ b/web/themes/custom/drevops/includes/banner.inc @@ -73,9 +73,9 @@ function _drevops_preprocess_block__civictheme_banner__featured_image(array &$va // A per-node featured image overrides the block-level one, mirroring the base // theme's resolution order. - $media = !empty($node) ? civictheme_get_field_value($node, 'field_c_n_banner_featured_image', TRUE) : NULL; + $media = !empty($node) ? civictheme_get_field_value($node, 'field_c_n_banner_featured_image', TRUE, build: $variables) : NULL; if (empty($media) && !empty($block)) { - $media = civictheme_get_field_value($block, 'field_c_b_featured_image', TRUE); + $media = civictheme_get_field_value($block, 'field_c_b_featured_image', TRUE, build: $variables); } if (!$media instanceof MediaInterface) { From fd196640360e6340b02f389b6d21697a48e49043 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Wed, 1 Jul 2026 21:53:25 +1000 Subject: [PATCH 4/4] Flipped negated ternary in banner featured image resolver. --- web/themes/custom/drevops/includes/banner.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/themes/custom/drevops/includes/banner.inc b/web/themes/custom/drevops/includes/banner.inc index 17c8c3fe..a22d0fc1 100644 --- a/web/themes/custom/drevops/includes/banner.inc +++ b/web/themes/custom/drevops/includes/banner.inc @@ -73,7 +73,7 @@ function _drevops_preprocess_block__civictheme_banner__featured_image(array &$va // A per-node featured image overrides the block-level one, mirroring the base // theme's resolution order. - $media = !empty($node) ? civictheme_get_field_value($node, 'field_c_n_banner_featured_image', TRUE, build: $variables) : NULL; + $media = empty($node) ? NULL : civictheme_get_field_value($node, 'field_c_n_banner_featured_image', TRUE, build: $variables); if (empty($media) && !empty($block)) { $media = civictheme_get_field_value($block, 'field_c_b_featured_image', TRUE, build: $variables); }