1, 'data-srcset' => 1, 'data-sizes' => 1, 'class' => 1, ) ); $allowed_tags['img'] = $img_attributes; return $allowed_tags; } /** * Find image elements that should be lazy-loaded. * * @param object $content The content. * @return object */ function pixigo_add_image_placeholders( $content ) { // Don't lazyload for feeds, previews. if ( is_feed() || is_preview() ) { return $content; } // Don't lazy-load if the content has already been run through previously. if ( false !== strpos( $content, 'data-src' ) ) { return $content; } // Find all elements via regex, add lazy-load attributes. $content = preg_replace_callback( '#<(img)([^>]+?)(>(.*?)|[\/]?>)#si', 'pixigo_process_image', $content ); return $content; } /** * Returns true when a given string of classes contains a class signifying image * should not be lazy-loaded * * @param string $classes A string of space-separated classes. * @return bool */ function pixigo_should_skip_image_with_blacklisted_class( $classes ) { $blacklisted_classes = array( 'skip-lazy', ); foreach ( $blacklisted_classes as $class ) { if ( false !== strpos( $classes, $class ) ) { return true; } } return false; } /** * Processes images in content by acting as the preg_replace_callback. * * @param array $matches element to be altered. * * @return string The image with updated lazy attributes */ function pixigo_process_image( $matches ) { $old_attributes_str = $matches[2]; $old_attributes_kses_hair = wp_kses_hair( $old_attributes_str, wp_allowed_protocols() ); if ( empty( $old_attributes_kses_hair['src'] ) ) { return $matches[0]; } $old_attributes = pixigo_flatten_kses_hair_data( $old_attributes_kses_hair ); $new_attributes = pixigo_process_image_attributes( $old_attributes ); // If we didn't add lazy attributes, just return the original image source. if ( empty( $new_attributes['data-src'] ) ) { return $matches[0]; } $new_attributes_str = pixigo_build_attributes_string( $new_attributes ); return sprintf( '', $new_attributes_str, $matches[0] ); } /** * Given an array of image attributes, updates the `src`, `srcset`, and `sizes` attributes so * that they load lazily. * * @param array $attributes Attributes of the current element. * * @return array The updated image attributes array with lazy load attributes. */ function pixigo_process_image_attributes( $attributes ) { if ( empty( $attributes['src'] ) ) { return $attributes; } if ( ! empty( $attributes['class'] ) && pixigo_should_skip_image_with_blacklisted_class( $attributes['class'] ) ) { return $attributes; } $old_attributes = $attributes; // Add the lazy class to the img element. $attributes['class'] = pixigo_set_lazy_class( $attributes ); // Set placeholder and lazy-src. $attributes['src'] = pixigo_get_placeholder_image(); // Set data-src to the original source uri. $attributes['data-src'] = $old_attributes['src']; // Process `srcset` attribute. if ( ! empty( $attributes['srcset'] ) ) { $attributes['data-srcset'] = $old_attributes['srcset']; unset( $attributes['srcset'] ); } // Process `sizes` attribute. if ( ! empty( $attributes['sizes'] ) ) { $attributes['data-sizes'] = $old_attributes['sizes']; unset( $attributes['sizes'] ); } return $attributes; } /** * Append a `lazy` class to elements for lazy-loading. * * @param array $attributes element attributes. * @return string */ function pixigo_set_lazy_class( $attributes ) { if ( array_key_exists( 'class', $attributes ) ) { $classes = $attributes['class']; $classes .= ' lazy'; } else { $classes = 'lazy'; } return $classes; } /** * Set the placeholder image. * * @return string The URL to the placeholder image. */ function pixigo_get_placeholder_image() { return get_theme_file_uri( '/images/placeholder.svg' ); } /** * Flatten attribute list into string. * * @param array $attributes Array of attributes. * @return string $flattened_attributes */ function pixigo_flatten_kses_hair_data( $attributes ) { $flattened_attributes = array(); foreach ( $attributes as $name => $attribute ) { $flattened_attributes[ $name ] = $attribute['value']; } return $flattened_attributes; } /** * Build string of new attributes to be returned to the element. * * @param array $attributes Array of attributes. * @return string */ function pixigo_build_attributes_string( $attributes ) { $string = array(); foreach ( $attributes as $name => $value ) { if ( '' === $value ) { $string[] = sprintf( '%s', $name ); } else { $string[] = sprintf( '%s="%s"', $name, esc_attr( $value ) ); } } return implode( ' ', $string ); } /** * Enqueue and defer lazyload script. */ function pixigo_enqueue_assets() { wp_enqueue_script( 'pixigo-lazy-load-images', get_theme_file_uri( '/pluggable/lazyload/js/lazyload.js' ), array(), '20151215', false ); wp_script_add_data( 'pixigo-lazy-load-images', 'defer', true ); }