int, 'url' => string, 'sizes' => array ]. * @param string $size Registered image size name (thumbnail, medium, large, full...). */ public static function image_url( array $image, string $size ): string { if ( ! empty( $image['id'] ) ) { $url = wp_get_attachment_image_url( (int) $image['id'], $size ); if ( $url ) { return $url; } } if ( ! empty( $image['sizes'][ $size ]['url'] ) ) { return $image['sizes'][ $size ]['url']; } return $image['url'] ?? ''; } /** * Resolves the full-size image URL, used as the lightbox target. */ public static function image_full_url( array $image ): string { return self::image_url( $image, 'full' ); } /** * Builds the HTML for a timeline item's marker icon. * * Icon values are stored as `:` (e.g. `fa:calendar` or * `dashicons:star-filled`) so the block editor's picker can mix both * icon sources. Values saved before this prefix existed have no `:` * and are treated as Font Awesome, matching their original (and only) * meaning at the time. */ public static function icon_markup( string $icon ): string { $icon = trim( $icon ); if ( '' === $icon ) { return ''; } if ( false !== strpos( $icon, ':' ) ) { list( $family, $name ) = explode( ':', $icon, 2 ); } else { $family = 'fa'; $name = $icon; } $name = trim( $name ); if ( '' === $name ) { return ''; } if ( 'dashicons' === $family ) { return sprintf( '', esc_attr( $name ) ); } return sprintf( '', esc_attr( $name ) ); } }