with the atomic style system (object-fit, * sizing, border, spacing). Static markup; only the scoped CSS and the * per-breakpoint image sources are rendered here. */ class Block extends AtomicBlockBase { protected $block_name = 'atomic-image'; public function render_callback( $attributes, $content, $block_instance ) { $content = $this->with_responsive_sources( $content, $attributes ); return parent::render_callback( $attributes, $content, $block_instance ); } /** * Wrap the saved in a carrying one per breakpoint * that has its own image (`responsiveImages`, keyed by bucket key). * * Done at render time rather than in save() so the media queries always * follow the site's current breakpoints and breakpoint mode, and so a block * without breakpoint images keeps exactly the markup it was saved with. * * Sources are listed narrowest-first (the reverse of the device list): the * browser takes the FIRST matching source, which makes the narrowest * applicable breakpoint win — the same precedence the cascade gives the * block's styles, and the one the editor's resolveImage() previews. A * breakpoint with no image of its own has no source and so inherits. * * @param string $content Saved block markup. * @param array $attributes Block attributes. * @return string Markup. */ protected function with_responsive_sources( $content, $attributes ) { $images = isset( $attributes['responsiveImages'] ) && is_array( $attributes['responsiveImages'] ) ? $attributes['responsiveImages'] : []; if ( empty( $images ) || ! $content || false === stripos( $content, ''; } if ( '' === $sources ) { return $content; } return preg_replace_callback( '/]*>/i', function ( $match ) use ( $sources ) { // The picture is `display: contents`, so the stays the layout // box. Its alignment classes are mirrored so core's layout rules — // which target direct children of a layout container — still // resolve the margins and widths the inherits (style.css). $classes = [ 'ablocks-atomic-image__picture' ]; if ( preg_match( '/\bclass="([^"]*)"/i', $match[0], $class ) ) { foreach ( preg_split( '/\s+/', $class[1] ) as $name ) { if ( preg_match( '/^align(left|right|center|wide|full)$/', $name ) ) { $classes[] = $name; } } } return '' . $sources . $match[0] . ''; }, $content, 1 ); } }