Render Templates

  • JNext lesson
  • KPrevious lesson
  • FSearch lessons
  • EscClear search

Template Variables

Every block render template receives four variables from ACF:

  • $block (array) – The block settings and attributes. Contains $block['id'] (unique block instance ID), $block['name'] (e.g. acf/accordion), $block['className'] (additional CSS classes), $block['style'] (style variation), and $block['data'] (flat ACF field values).

  • $content (string) – The rendered InnerBlocks HTML. Only populated for blocks with "jsx": true in their block.json supports.

  • $is_preview (bool) – true when the block is being rendered inside the editor as an AJAX preview. Useful for disabling interactive JavaScript or showing placeholder content.

  • $post_id (int) – The ID of the post being edited or displayed.

Reading Field Values

Templates should use the compatibility helper functions instead of calling get_field() directly. This ensures fields work correctly across all ACF versions, including ACF 6.7+ where get_field() behavior changed for block data.

Single Fields

$title = acf_blocks_get_field( 'field_name', $block );

This calls get_field() first. If it returns false/null/empty, it falls back to reading from $block['data']['field_name'].

Repeater Fields

$items = acf_blocks_get_repeater( 'items', array(
    'item_title',
    'item_description',
    'item_icon',
), $block );

The second argument is an array of sub-field names. You can also pass an associative array to specify field types for special handling:

$products = acf_blocks_get_repeater( 'products', array(
    'product_name'  => 'text',
    'product_image' => 'image',
    'product_link'  => 'link',
    'is_featured'   => 'bool',
    'price'         => 'number',
), $block );

Supported types:

  • text (default) – Returns the raw string value.
  • image – If the value is a numeric attachment ID, returns an array with ID, url, and alt.
  • image_url – If the value is a numeric attachment ID, returns just the URL string.
  • link – Handles serialized link arrays and normalizes to title, url, target.
  • bool – Casts to boolean.
  • int / number – Casts to integer.

The function handles three data formats transparently:

  1. Native ACF arrays (when get_field() works normally).
  2. Flat indexed keys like items_0_item_title, items_1_item_title (REST API save format).
  3. Nested row-0, row-1 format (ACF 6.7+ block comment format).

Nested Repeaters

For repeaters inside repeaters (e.g. the Compare block where each product has a sub-repeater of features):

$features = acf_blocks_get_nested_repeater(
    'products_' . $i . '_features',
    array( 'feature_name', 'feature_value' ),
    $block['data']
);

The first argument is the full flat key prefix. The third argument is the raw $block['data'] array (not the $block array itself).

Icon Markup

The helper function acf_blocks_get_icon_markup() handles icon field values:

echo acf_blocks_get_icon_markup( $icon_value );

If the value looks like a CSS class string (contains hyphens or spaces, no emoji), it outputs <i class="..." aria-hidden="true"></i>. Otherwise it outputs the value as escaped text (for emoji or text icons).

A backward-compatible alias md_get_icon_markup() is available.

InnerBlocks

Blocks with "jsx": true in their block.json supports can use InnerBlocks. The $content variable contains the rendered InnerBlocks HTML. Templates typically output it like:

<div class="acf-hero-content">
    <InnerBlocks />
    <?php echo $content; ?>
</div>

The <InnerBlocks /> tag is replaced by the editor with the InnerBlocks editing interface. On the frontend, $content contains the rendered output.

Some blocks (like Hero) check whether $content is empty and fall back to legacy ACF field values when it is. This provides backward compatibility with content created before InnerBlocks support was added.

Preview Detection

Use $is_preview to adjust rendering for the editor:

if ( $is_preview ) {
    // Show a simplified version for the editor
} else {
    // Full frontend rendering with interactive JS
}

This is commonly used to skip loading frontend JavaScript (like the star rating submission handler) in the editor preview.

Inline Styles

Some blocks generate per-instance inline CSS. The Section Block uses md_store_block_css() to collect CSS during rendering, then md_output_stored_block_css() outputs it all in wp_footer. The Post Display block outputs a <style> tag directly within its render template.

For inline CSS, the utility function acf_blocks_minify_css() strips comments, collapses whitespace, and removes trailing semicolons:

$css = acf_blocks_minify_css( $raw_css );