diff --git a/README.md b/README.md index 34bd170..1ac44c5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,10 @@ This module requires the the following PHP extension: ## Installation 1. Install the module. 2. Copy the contents of the .htaccess file in the module root to your - site-wide .htaccess. + site-wide .htaccess.* + + \* Images displayed using Drupal core's "Responsive image" formatter + don't depend on the .htaccess mechanism to serve WebP derivatives. ## Maintainers * Bart Vanhoutte (Bart Vanhoutte) - https://www.drupal.org/user/1133754 diff --git a/src/Controller/ImageStyleDownloadController.php b/src/Controller/ImageStyleDownloadController.php index 2ec3cfb..995c33d 100644 --- a/src/Controller/ImageStyleDownloadController.php +++ b/src/Controller/ImageStyleDownloadController.php @@ -101,6 +101,39 @@ class ImageStyleDownloadController extends FileDownloadController { $target = $request->query->get('file'); $image_uri = $scheme . '://' . $target; + // Don't try to generate file if source is missing. + if (!file_exists($image_uri)) { + + $path_info = pathinfo($image_uri); + + $possible_image_uris = [ + // If the image style converted the extension, it has been added to the + // original file, resulting in filenames like image.png.jpeg. So to find + // the actual source image, we remove the extension and check if that + // image exists. + $path_info['dirname'] . DIRECTORY_SEPARATOR . $path_info['filename'], + + // Try out the different possible sources for a webp image. + str_replace('.webp', '.jpg', $image_uri ), + str_replace('.webp', '.jpeg', $image_uri ), + str_replace('.webp', '.png', $image_uri ) + ]; + + $source_image_found = FALSE; + foreach ($possible_image_uris as $possible_image_uri) { + if (file_exists($possible_image_uri)) { + $image_uri = $possible_image_uri; + $source_image_found = TRUE; + break; + } + } + + if (!$source_image_found) { + $this->logger->notice('Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', ['%source_image_path' => $image_uri, '%derivative_path' => $derivative_uri]); + return new Response($this->t('Error generating image, missing source file.'), 404); + } + } + // Check that the style is defined, the scheme is valid, and the image // derivative token is valid. Sites which require image derivatives to be // generated without a token can set the @@ -132,24 +165,6 @@ class ImageStyleDownloadController extends FileDownloadController { } } - // Don't try to generate file if source is missing. - if (!file_exists($image_uri)) { - // If the image style converted the extension, it has been added to the - // original file, resulting in filenames like image.png.jpeg. So to find - // the actual source image, we remove the extension and check if that - // image exists. - $path_info = pathinfo($image_uri); - $converted_image_uri = $path_info['dirname'] . DIRECTORY_SEPARATOR . $path_info['filename']; - if (!file_exists($converted_image_uri)) { - $this->logger->notice('Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', ['%source_image_path' => $image_uri, '%derivative_path' => $derivative_uri]); - return new Response($this->t('Error generating image, missing source file.'), 404); - } - else { - // The converted file does exist, use it as the source. - $image_uri = $converted_image_uri; - } - } - // Don't start generating the image if the derivative already exists or if // generation is in progress in another thread. if (!file_exists($derivative_uri)) { diff --git a/webp.module b/webp.module index fc09081..5f6d9c3 100644 --- a/webp.module +++ b/webp.module @@ -22,3 +22,30 @@ function webp_help($route_name, RouteMatchInterface $route_match) { default: } } + +/** + * Implements template_preprocess_responsive_image(). + */ +function webp_preprocess_responsive_image(&$variables) { + $webp_sources = []; + foreach ($variables['sources'] as $source) { + /** @var \Drupal\Core\Template\Attribute $source */ + $original_url = $source->offsetGet('srcset')->value(); + $webp_url = str_ireplace(['.png', '.jpg', '.jpeg'], '.webp', $original_url); + + + + // Create a new source pointing to the webp URL. + $webp_source = clone $source; + $webp_source->offsetSet('srcset', $webp_url); + $webp_source->offsetSet('type', 'image/webp'); + $webp_sources[] = $webp_source; + } + + // Add the new sources at the top of the list. + $variables['sources'] = array_merge($webp_sources, $variables['sources']); + + // Never output a single image tag, because + // we will always have at least two sources. + $variables['output_image_tag'] = FALSE; +} \ No newline at end of file