Drupal 8:如何在节点模板中分段渲染指定段落字段内容
Hey there! I’ve worked with Drupal paragraph fields like this before, so let’s walk through how to split up the rendering of your Ambience images and Tile breakdown content across different areas of your node template.
First, make sure you’re using the correct machine names for your fields (replace the example names below with your actual field machine names, like field_ambiences for your Ambiences paragraph field, field_image for the Ambience image, etc.).
Option 1: Directly render in your Twig node template
If you want to keep things simple and handle rendering directly in the node template (e.g., node--collection.html.twig), you can loop through your Ambiences paragraphs and extract the specific fields you need for each section.
Render Ambience images in one area
Add this code wherever you want the Ambience images to appear:
{# Section for Ambience images #} <div class="ambience-image-gallery"> {% for ambience in node.field_ambiences %} {# Check if the Ambience has an image before rendering #} {% if ambience.entity.field_image is not empty %} {# Use the default field view mode, or specify an image style #} {{ ambience.entity.field_image|view }} {# Or use a custom image style like this: #} {# {{ ambience.entity.field_image|image_style('your_custom_image_style') }} #} {% endif %} {% endfor %} </div>
Render Tile breakdown content in another area
Then, in a different part of your template, add this to render the Tile breakdown details:
{# Section for Tile breakdown content #} <div class="tile-breakdown-section"> {% for ambience in node.field_ambiences %} {% set tile_breakdowns = ambience.entity.field_tile_breakdown %} {# Only render if there are Tile breakdown sub-paragraphs #} {% if tile_breakdowns is not empty %} {% for breakdown in tile_breakdowns %} <div class="tile-breakdown-card"> {# Tile breakdown image #} {% if breakdown.entity.field_image is not empty %} <div class="breakdown-image"> {{ breakdown.entity.field_image|view }} </div> {% endif %} {# Tile breakdown name #} <h3 class="breakdown-name">{{ breakdown.entity.field_name.value }}</h3> {# Format field #} <div class="breakdown-format">Format: {{ breakdown.entity.field_format.value }}</div> {# Container width field #} <div class="breakdown-container-width">Container Width: {{ breakdown.entity.field_container_width.value }}</div> {# Other display options #} {% if breakdown.entity.field_other_display_options is not empty %} <div class="breakdown-options"> {{ breakdown.entity.field_other_display_options.value }} </div> {% endif %} </div> {% endfor %} {% endif %} {% endfor %} </div>
Option 2: Clean up with a preprocess function
If you want to keep your Twig template cleaner, you can use a theme preprocess function to extract and organize the data before it reaches the template.
Add this to your theme’s .theme file (e.g., yourtheme.theme):
function yourtheme_preprocess_node__collection(&$variables) { $node = $variables['node']; // Initialize empty arrays to hold our data $variables['ambience_images'] = []; $variables['tile_breakdown_items'] = []; // Loop through each Ambiences paragraph if (!$node->field_ambiences->isEmpty()) { foreach ($node->field_ambiences as $ambience) { // Collect Ambience images if (!$ambience->entity->field_image->isEmpty()) { $variables['ambience_images'][] = $ambience->entity->field_image->view('large'); } // Collect Tile breakdown data $tile_breakdowns = $ambience->entity->field_tile_breakdown; if (!$tile_breakdowns->isEmpty()) { foreach ($tile_breakdowns as $breakdown) { $variables['tile_breakdown_items'][] = [ 'image' => $breakdown->entity->field_image->isEmpty() ? '' : $breakdown->entity->field_image->view('medium'), 'name' => $breakdown->entity->field_name->value, 'format' => $breakdown->entity->field_format->value, 'container_width' => $breakdown->entity->field_container_width->value, 'other_options' => $breakdown->entity->field_other_display_options->value, ]; } } } } }
Then, in your node--collection.html.twig template, you can use these preprocessed variables like so:
{# Ambience images section #} <div class="ambience-image-gallery"> {% for image in ambience_images %} {{ image }} {% endfor %} </div> {# Tile breakdown section #} <div class="tile-breakdown-section"> {% for item in tile_breakdown_items %} <div class="tile-breakdown-card"> {% if item.image %} {{ item.image }} {% endif %} <h3>{{ item.name }}</h3> <div>Format: {{ item.format }}</div> <div>Container Width: {{ item.container_width }}</div> {% if item.other_options %} <div>{{ item.other_options }}</div> {% endif %} </div> {% endfor %} </div>
A few quick notes:
- Replace
yourthemewith your actual theme name, and adjust field machine names to match your setup. - Use
|image_style()or specify a view mode to control how images are displayed (e.g., thumbnail, large, custom styles you’ve created). - Always add checks for empty fields to avoid rendering errors if a paragraph doesn’t have all fields filled out.
内容的提问来源于stack exchange,提问作者Eloy Ruiz

