Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A lazysizes implementation for WordPress
<?php
/**
* Lhtheme\Lazysizes\Component class
*
* @package lhtheme
*/
namespace WpMunich\lhtheme\Lazysizes;
use WpMunich\lhtheme\Component_Interface;
use function add_action;
/**
* A class to handle textdomains and other Lazysizes related logic..
*/
class Component implements Component_Interface {
/**
* Gets the unique identifier for the theme component.
*
* @return string Component slug.
*/
public function get_slug() {
return 'lazysizes';
}
/**
* Adds the action and filter hooks to integrate with WordPress.
*/
public function initialize() {
add_filter( 'wp_get_attachment_image_attributes', array( $this, 'modify_image_attributes' ), 10, 3 );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
/**
* Modify image attributes to work with lazysizes.
*
* @param string[] $attr Array of attribute values for the image markup, keyed by attribute name.
* See wp_get_attachment_image().
* @param WP_Post $attachment Image attachment post.
* @param string|int[] $size Requested image size. Can be any registered image size name, or
* an array of width and height values in pixels (in that order).
*
* @return string[] Array of attribute values for the image markup, keyed by attribute name.
*/
public function modify_image_attributes( $attr, $attachment, $size ) {
if ( isset( $attr['srcset'] ) && ! empty( $attr['srcset'] ) ) {
// Modify the class of the image.
$attr['class'] = classNames(
$attr['class'] ? $attr['class'] : null,
array(
'lazyload' => true,
)
);
// Set the data-sizes attribute to auto.
$attr['data-sizes'] = 'auto';
$attr['data-srcset'] = $attr['srcset'];
$smallest = $this->get_smallest_from_wp_srcset( $attr['srcset'] );
if ( $smallest ) {
$attr['data-src'] = $attr['src'];
$attr['src'] = $smallest;
}
unset( $attr['sizes'] );
unset( $attr['srcset'] );
}
return $attr;
}
/**
* Given a srcset this function extracts the smalles source.
*
* @param string $srcset An html srcset.
*/
public function get_smallest_from_wp_srcset( $srcset ) {
$srcset_array = explode( ',', $srcset );
$pattern = "/(?'src'https?:\/\/\S*) (?'width'\d*)w/";
// Defined the defaults.
$current_smallest_width = PHP_INT_MAX;
$current_smallest_src = null;
foreach ( $srcset_array as $image ) {
preg_match( $pattern, $image, $matches );
if ( isset( $matches['width'] ) && intval( $matches['width'] ) < $current_smallest_width ) {
$current_smallest_src = $matches['src'];
$current_smallest_width = $matches['width'];
}
}
return $current_smallest_src;
}
/**
* Enqueue needed scripts.
*
* @return void
*/
public function enqueue_scripts() {
$lazysizes_asset = include( get_template_directory() . '/lazysizes.min.asset.php' ); // phpcs:ignore
wp_enqueue_script( 'lhtheme-lazysizes', get_template_directory_uri() . '/lazysizes.min.js', array_merge( $lazysizes_asset['dependencies'], array() ), $lazysizes_asset['version'], true );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment