Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,26 @@ HappyPrime\ThemeImageBlock\register_theme_image(
'description' => 'The Happy Prime logo.',
'alt' => 'Happy Prime',
'path' => 'images/happy-prime-logo.svg',
'width' => '',
'width' => '300',
'height' => '',
'sizes' => [
'variations' => [
'small' => [
'path' => 'images/happy-prime-logo-small.svg',
'width' => 100,
'height' => 100,
'width' => '100',
'height' => '100',
],
'medium' => [
'path' => 'images/happy-prime-logo-medium.svg',
'width' => 200,
'height' => 200,
'width' => '200',
'height' => '200',
],
'large' => [
'path' => 'images/happy-prime-logo-large.svg',
'width' => 300,
'height' => 300,
'width' => '300',
'height' => '300',
],
],
'sizes' => '(max-width: 600px) 100vw, 300px',
]
);
```
Expand All @@ -63,9 +64,10 @@ Registers a theme image for use in the Theme Image block.
- `description` (string, optional): Description of the image.
- `alt` (string, optional): Default alt text for accessibility.
- `path` (string, required): Path to the image file relative to the theme directory.
- `width` (string, optional): Default width value.
- `height` (string, optional): Default height value.
- `sizes` (array, optional): Array of size variations.
- `width` (string, optional): Width of the main image in pixels. Used to build the srcset attribute.
- `height` (string, optional): Height of the main image in pixels.
- `variations` (array, optional): Array of image variations with different sizes. Each variation should include `path`, `width`, and `height`. Used to build the srcset attribute.
- `sizes` (string, optional): Value for the HTML sizes attribute. Controls which image size the browser selects from srcset based on layout. Example: `(max-width: 600px) 100vw, 300px`.

**Returns:** Boolean indicating success.

Expand All @@ -83,7 +85,9 @@ Registers a theme image for use in the Theme Image block.
## Features

- **PHP-based registration**: Register images from your theme or plugin code
- **Rich metadata**: Include titles, descriptions, alt text, and size variations
- **Rich metadata**: Include titles, descriptions, alt text, and image variations
- **Responsive images**: Automatic srcset generation from registered variations for optimal image loading
- **Custom sizes attribute**: Define custom sizes strings to control responsive image selection
- **Flexible dimensions**: Support for all CSS units and functions (px, %, rem, clamp, calc, etc.)
- **Inline SVG support**: Render SVG files inline for better styling control
- **Link support**: Add links to images with target and rel options
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ includes:

parameters:
level: 9
treatPhpDocTypesAsCertain: false
43 changes: 41 additions & 2 deletions src/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,34 @@ public static function render( $attributes, $content ): string {
$width = isset( $attributes['width'] ) && ! empty( $attributes['width'] ) ? esc_attr( $attributes['width'] ) : '';
$height = isset( $attributes['height'] ) && ! empty( $attributes['height'] ) ? esc_attr( $attributes['height'] ) : '';

// Build srcset from registered variations.
$srcset_parts = array();

// Add the main image if it has a width.
if ( ! empty( $image_data['width'] ) ) {
$srcset_parts[] = sprintf(
'%s %sw',
esc_url( get_template_directory_uri() . '/' . $image_data['path'] ),
(int) $image_data['width']
);
}

// Add variations if they have width and path.
if ( ! empty( $image_data['variations'] ) && is_array( $image_data['variations'] ) ) {
foreach ( $image_data['variations'] as $variation ) {
if ( ! empty( $variation['width'] ) && ! empty( $variation['path'] ) ) {
$srcset_parts[] = sprintf(
'%s %sw',
esc_url( get_template_directory_uri() . '/' . $variation['path'] ),
(int) $variation['width']
);
}
}
}

$srcset = ! empty( $srcset_parts ) ? implode( ', ', $srcset_parts ) : '';
$sizes = ! empty( $image_data['sizes'] ) ? esc_attr( $image_data['sizes'] ) : '';

// Construct the image path from the registered image data.
$image_path = realpath( get_template_directory() . '/' . $image_data['path'] );
$theme_dir = realpath( get_template_directory() );
Expand Down Expand Up @@ -104,8 +132,19 @@ public static function render( $attributes, $content ): string {
}
}

if ( $html->next_tag( array( 'tag_name' => 'img' ) ) && ! empty( $inline_styles ) ) {
$html->set_attribute( 'style', implode( '; ', $inline_styles ) );
// This seems to be the best way to rewind and seek again? Seems strange.
$html = new \WP_HTML_Tag_Processor( $html->get_updated_html() );

if ( $html->next_tag( array( 'tag_name' => 'img' ) ) ) {
if ( ! empty( $inline_styles ) ) {
$html->set_attribute( 'style', implode( '; ', $inline_styles ) );
}
if ( ! empty( $srcset ) ) {
$html->set_attribute( 'srcset', $srcset );
}
if ( ! empty( $sizes ) ) {
$html->set_attribute( 'sizes', $sizes );
}
}

$content = $html->get_updated_html();
Expand Down
31 changes: 19 additions & 12 deletions src/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class Registry {
* path: string,
* width: string,
* height: string,
* sizes: array<string, array{path: string, width: string, height: string}>
* variations: array<string, array{path: string, width: string, height: string}>,
* sizes: string
* }>
*/
private static array $images = array();
Expand All @@ -39,7 +40,8 @@ class Registry {
* @type string $path Path to the image file relative to the theme directory (required).
* @type string $width Default width value (optional).
* @type string $height Default height value (optional).
* @type array $sizes Array of size variations (optional).
* @type array $variations Array of image variations for srcset (optional).
* @type string $sizes Value for the sizes attribute (optional).
* }
*
* @return bool True if registered successfully, false otherwise.
Expand Down Expand Up @@ -79,7 +81,8 @@ public static function register( string $slug, array $args ): bool {
'path' => '',
'width' => '',
'height' => '',
'sizes' => array(),
'variations' => array(),
'sizes' => '',
);

$args = wp_parse_args( $args, $defaults );
Expand All @@ -92,7 +95,8 @@ public static function register( string $slug, array $args ): bool {
'path' => sanitize_text_field( $args['path'] ),
'width' => sanitize_text_field( $args['width'] ),
'height' => sanitize_text_field( $args['height'] ),
'sizes' => self::sanitize_sizes( $args['sizes'] ),
'variations' => self::sanitize_variations( $args['variations'] ),
'sizes' => sanitize_text_field( $args['sizes'] ),
);

return true;
Expand All @@ -108,7 +112,8 @@ public static function register( string $slug, array $args ): bool {
* path: string,
* width: string,
* height: string,
* sizes: array<string, array{path: string, width: string, height: string}>
* variations: array<string, array{path: string, width: string, height: string}>,
* sizes: string
* }> Registered images, keyed by image slug.
*/
public static function get_all(): array {
Expand All @@ -127,7 +132,8 @@ public static function get_all(): array {
* path: string,
* width: string,
* height: string,
* sizes: array<string, array{path: string, width: string, height: string}>
* variations: array<string, array{path: string, width: string, height: string}>,
* sizes: string
* }|null Image data or null if not found.
*/
public static function get( string $slug ): ?array {
Expand Down Expand Up @@ -184,6 +190,7 @@ public static function get_for_editor(): array {
'alt' => $data['alt'],
'width' => $data['width'],
'height' => $data['height'],
'variations' => $data['variations'],
'sizes' => $data['sizes'],
);
}
Expand All @@ -192,20 +199,20 @@ public static function get_for_editor(): array {
}

/**
* Sanitize size variations.
* Sanitize image variations.
*
* @param mixed $sizes Size variations.
* @param mixed $variations Image variations.
*
* @return array<string, array{path: string, width: string, height: string}> Sanitized sizes.
* @return array<string, array{path: string, width: string, height: string}> Sanitized variations.
*/
private static function sanitize_sizes( $sizes ): array {
if ( ! is_array( $sizes ) ) {
private static function sanitize_variations( $variations ): array {
if ( ! is_array( $variations ) ) {
return array();
}

$sanitized = array();

foreach ( $sizes as $size => $data ) {
foreach ( $variations as $size => $data ) {
if ( ! is_array( $data ) ) {
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion theme-image-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
* @type string $path Path to the image file relative to the theme directory (required).
* @type string $width Default width value (optional).
* @type string $height Default height value (optional).
* @type array $sizes Array of size variations (optional).
* @type array $variations Array of image variations for srcset (optional).
* @type string $sizes Value for the sizes attribute (optional).
* }
*
* @return bool True if registered successfully, false otherwise.
Expand Down