Drupal7升级Drupal9后自定义模块如何实现响应式图片
Drupal9 自定义模块响应式图片实现方案
结合你已经手动定义好各设备尺寸图片路径的现状,提供两种可直接落地的实现方案,可根据项目后续维护需求选择。
方案一:直接输出<picture>标签(改造成本最低,适配现有代码逻辑)
该方案不需要额外配置Drupal后台能力,直接复用你已经生成的各尺寸路径,符合HTML原生响应式图片标准,适合固定位置的静态banner场景。
- 首先调整PHP层的路径生成逻辑,把现有硬拼
$base_url的写法换成Drupal9规范的路径获取方式,避免CDN、多语言场景下路径出错:
/** @var \Drupal\Core\Extension\ModuleExtensionList $module_extension_list */ $module_extension_list = \Drupal::service('extension.list.module'); $module_path = $module_extension_list->getPath('你的自定义模块机读名'); $banner_img = [ 'large_image' => file_create_url($module_path . '/images/flower-02.jpg'), 'mid_desktop_image' => file_create_url($module_path . '/images/flower-02.jpg'), 'ipad_image' => file_create_url($module_path . '/images/flower-02730.jpg'), 'mobile_image' => file_create_url($module_path . '/images/flower-02560.jpg'), ]; // 把$banner_img传给对应模板文件 $build['banner'] = [ '#theme' => '你的自定义banner模板名', '#banner_img' => $banner_img, ];
- 在模块对应的Twig模板文件(如
yourmodule-banner.html.twig)中输出picture标签结构:
<picture> <!-- 大屏设备加载原图 --> <source media="(min-width: 1200px)" srcset="{{ banner_img.large_image }}"> <!-- 中尺寸桌面设备加载原图 --> <source media="(min-width: 992px)" srcset="{{ banner_img.mid_desktop_image }}"> <!-- 平板设备加载730宽度图 --> <source media="(min-width: 576px)" srcset="{{ banner_img.ipad_image }}"> <!-- 移动端加载560宽度图,同时作为兜底兼容不支持picture的浏览器 --> <img src="{{ banner_img.mobile_image }}" alt="站点宣传banner" loading="lazy" width="100%"> </picture>
- 注意事项:
- media查询的断点值请和项目前端全局断点规则保持一致,避免尺寸切换时出现断层
<img>兜底标签必须保留,它是老旧浏览器兼容、搜索引擎识别图片内容的核心节点loading="lazy"为原生懒加载属性,非首屏场景建议加上,可减少首屏加载体积
方案二:对接Drupal核心响应式图片模块(适合长期维护、多场景复用)
如果后续banner支持后台上传、多位置复用同套响应式规则,建议用Drupal9核心自带的响应式图片能力,不需要手动维护多版本图片路径:
- 先开启Drupal核心自带的两个模块:
Responsive Image(响应式图片)、Breakpoint(断点管理),两个模块均为核心内置,无需额外下载。 - 在自定义模块根目录新建
[模块机读名].breakpoints.yml文件,定义项目使用的响应式断点,文件名必须和模块机读名完全一致,否则系统无法识别:
yourmodule.breakpoint.large: label: 大屏桌面 mediaQuery: '(min-width: 1200px)' weight: 0 multipliers: - 1x - 2x # 适配高清屏 yourmodule.breakpoint.mid_desktop: label: 中桌面 mediaQuery: '(min-width: 992px)' weight: 1 multipliers: - 1x - 2x yourmodule.breakpoint.ipad: label: 平板 mediaQuery: '(min-width: 576px)' weight: 2 multipliers: - 1x - 2x yourmodule.breakpoint.mobile: label: 移动端 mediaQuery: '' weight: 3 multipliers: - 1x - 2x
- 进入后台「配置 - 媒体 - 图片样式」,提前建好对应尺寸的图片裁切样式(如730px宽、560px宽的等比缩放样式);再进入「配置 - 媒体 - 响应式图片样式」,新建一套响应式图片规则,关联刚才定义的断点,为每个断点匹配对应尺寸的图片样式。
- 代码层不需要手动拼接各尺寸路径,直接用响应式图片渲染数组输出即可,系统会自动按断点规则生成对应picture标签:
$build['banner'] = [ '#theme' => 'responsive_image', '#responsive_image_style_id' => '你新建的响应式图片样式机读名', // 模块内静态图可直接用module流包装器写路径 '#uri' => 'module://你的模块机读名/images/flower-02.jpg', '#alt' => '站点宣传banner', ];
- 该方案优势:后续调整尺寸、适配高清屏、新增webp格式支持都可以在后台配置完成,不需要修改代码;只需要上传一张最大尺寸的原图,系统会自动生成各尺寸的裁切版本,不需要手动保存多份不同尺寸的图片文件。
内容的提问来源于stack exchange,提问作者vaishali
相关产品推荐
相关产品推荐

