$attributes Block attributes.
* @param string $content Block content.
* @return string
* @since 1.3.0
*/
public function render( $attributes, $content = '' ) {
unset( $content ); // Unused parameter.
if ( empty( $attributes ) ) {
return '';
}
$image_id = isset( $attributes['imageId'] ) ? absint( Helper::get_string_value( $attributes['imageId'] ) ) : 0;
$image_url = isset( $attributes['imageUrl'] ) ? Helper::get_string_value( $attributes['imageUrl'] ) : '';
$alt = isset( $attributes['imageAlt'] ) ? Helper::get_string_value( $attributes['imageAlt'] ) : '';
// Nothing selected — a display block with no image contributes nothing.
if ( ! $image_id && '' === $image_url ) {
return '';
}
// Restrict the size to the supported set so it can be passed to core safely.
$size = isset( $attributes['sizeSlug'] ) ? Helper::get_string_value( $attributes['sizeSlug'] ) : 'full';
if ( ! in_array( $size, self::SIZES, true ) ) {
$size = 'full';
}
// Restrict alignment to a known set so it can be used safely in a class.
$align = isset( $attributes['textAlign'] ) ? Helper::get_string_value( $attributes['textAlign'] ) : 'left';
if ( ! in_array( $align, [ 'left', 'center', 'right' ], true ) ) {
$align = 'left';
}
// Object fit — applied as a class (CSS carries the property) so no inline
// styles pass through kses. Empty means the browser default.
$fit = isset( $attributes['objectFit'] ) ? Helper::get_string_value( $attributes['objectFit'] ) : '';
if ( ! in_array( $fit, [ 'fill', 'cover', 'contain' ], true ) ) {
$fit = '';
}
// Optional fixed dimensions (px) from the editor resize handles /
// Dimensions controls. 0 = auto. Emitted as width/height CSS, which
// wp_kses passes through safecss_filter_attr.
$width_px = isset( $attributes['width'] ) ? max( 0, (int) Helper::get_string_value( $attributes['width'] ) ) : 0;
$height_px = isset( $attributes['height'] ) ? max( 0, (int) Helper::get_string_value( $attributes['height'] ) ) : 0;
$style = '';
if ( $width_px ) {
$style .= 'width:' . $width_px . 'px;';
}
if ( $height_px ) {
$style .= 'height:' . $height_px . 'px;';
}
// Prefer the attachment render (correct srcset/sizes/lazy-loading, and it
// tracks the file if it was edited/regenerated); fall back to the stored
// URL when the attachment no longer resolves (e.g. deleted media).
$image_markup = '';
if ( $image_id ) {
$image_markup = wp_get_attachment_image(
$image_id,
$size,
false,
array_filter(
[
'class' => 'sd-image' . ( $fit ? ' sd-image--fit-' . $fit : '' ),
'alt' => $alt,
'style' => $style,
],
static fn ( $value, $key ) => 'alt' === $key || '' !== $value,
ARRAY_FILTER_USE_BOTH
)
);
}
if ( '' === $image_markup && '' !== $image_url ) {
$image_markup = sprintf(
'',
esc_url( $image_url ),
esc_attr( $alt ),
$fit ? esc_attr( ' sd-image--fit-' . $fit ) : '',
$style ? ' style="' . esc_attr( $style ) . '"' : ''
);
}
if ( '' === $image_markup ) {
return '';
}
$wrapper_classes = self::get_display_block_classes( $attributes, 'sd-image-block' );
// Optional caption, rendered as a semantic figcaption.
$caption_markup = '';
$caption = isset( $attributes['caption'] ) ? Helper::get_string_value( $attributes['caption'] ) : '';
if ( ! empty( $attributes['enableCaption'] ) && '' !== trim( $caption ) ) {
// Caption alignment is independent of the image alignment; empty
// means it follows the figure (image) alignment.
$caption_align = isset( $attributes['captionAlign'] ) ? Helper::get_string_value( $attributes['captionAlign'] ) : '';
if ( ! in_array( $caption_align, [ 'left', 'center', 'right' ], true ) ) {
$caption_align = '';
}
$caption_markup = sprintf(
'