modx + webp просто и надежно - автоматически



Недавно нашел удачный плагин для преобразования картинок/рисунков в webp в автоматическом режиме — плагин сам решит поддерживает ли браузер webp и отдаст ему кэш страницы с webp, а если нет (apple) то отдаст обычную страницу… От вас ничего не требуется кроме установки плагина, не из репозитория (на странице все расписано).


Ссылка на github

Инструкция по установке

Да, в идеале установить бинарный «cwebp», но если нет доступа то GD отконрвертирует рисунки (да качество ниже и сжатие не лучшее, но PageSpeed Вас все равно полюбит ;) )
Shedko Denis
02 декабря 2021, 22:44
modx.pro
9
1 215
+9

Комментарии: 11

Anton
03 декабря 2021, 00:17
0
Спасибо, но modx.com/extras/package/pthumb
webP + phpThumbOff, все работает как швейцарский нож уже 10 лет.
    Shedko Denis
    03 декабря 2021, 19:50
    1
    0
    Тут дело в том, что плагин САМ смотрит ответы и принимает решение, что можно отдать страницу с webp или отдать с обычными форматами (той же iOS).

    И ничего придумывать не надо.
      Евгений
      20 апреля 2022, 20:06
      0
      Не подскажете как вы вызываете phpThumbOff чтоб он webP генерил с заданным параметром качества?
      Вызываю вот так:
      [[+image_absolute:phpthumbof=`w=350&h=195&zc=C&f=webp&q=10`]]
      но параметр «q», как не меняй на качестве и весе картинки не отражается.
      В phpThumbOn, такая же история.
        Anton
        21 апреля 2022, 11:35
        0
        Привет.
        Как я понял, ты вызываешь сниппет внутри pdoTools (из-за знака +), верно?
        1. Точно не путаешь [[* вместо [[+ ?
        2. Формат файла должен быть таким f=webP (латинская буква P должна быть большая)
        И еще. В сниппете phpThumbOff или phpThumbOn какая-то бага при генерации webP. Если картинка имеет прозрачный фон, то он заменяет ее на белый фон.

        Лично я использую pThumb

        Получилось?
          Евгений
          29 апреля 2022, 02:19
          0
          Не получилось((
          Не phpThumbOff, не phpThumbOn, не pThumb не понимают настройки качества для webP.
          Мне кажется webP генерится по умолчанию с максимальным качеством, и это никак не поменять.
          То есть наверно как-то можно, но у меня не получилось.
          <picture>
              <source type="image/webp"
                  srcset="[[+image_absolute:phpthumbon=`w=350&h=195&zc=C&q=50&f=webP`]], 
                          [[+image_absolute:phpthumbon=`w=700&h=390&zc=C&q=50&f=webP`]] 2x">
              <img title="[[+pagetitle]]" alt="[[+pagetitle]]"
                     src="[[+image_absolute:phpthumbon=`w=350&h=195&zc=C`]]" 
                  srcset="[[+image_absolute:phpthumbon=`w=700&h=390&zc=C`]] 2x">
          </picture>
          Вэб пишная картинка получается в полтора раза тяжелее чем JPG. Весь смысл использования webP теряется.
      Николай Савин
      03 декабря 2021, 12:08
      0
      Изменил раздел на «Готовые решения», так как здесь речь не о компоненте MODX
        Дмитрий Середюк
        06 декабря 2021, 17:37
        +1
        Вроде как такая конструкция работает без всяких плагинов
        <picture class="image image_cover">
            {if $webp}
               <source type="image/webp" data-srcset="{$webp}">
            {/if}
            <img class="lazyload" src="#" data-src="{$small?:$empty}" alt="{$pagetitle}" itemprop="image"/>
        </picture>
          Shedko Denis
          06 декабря 2021, 18:54
          1
          +1
          Да.

          Но когда страниц уже более 2 тыс., чанков и снипеттов за 300 именно этот плагин решение как «Поставил и забыл — оно все работает само» и ничего не надо переписывать и следить за слетевшим css.
          picture не устроил тем, то надо было очень много чего переписать. А у нас работают «ленивые» люди, которые ищут простые пути, а не работу на многие человеко-часы.
          Viktor
          09 декабря 2021, 12:53
          +1
          Кстати не на всех хостингах это работает, там есть функция exec её часто блокирует.
            Kirill
            18 января 2022, 00:22
            0
            Вопрос. Как его заставить работать по расписанию. У меня каждую ночь грузится с внешнего источника, по крону, n-ое количество картинок и json. Каждый день заходить в админку и руками жать на кнопку не хочется
              Viktor
              29 апреля 2022, 08:17
              0
              По webp у меня есть такой сниппет, для google page speed insgiht хватает полностью, автоматом конвертирует все найденные картинки будь то в source будто в src, так же в функции может уменьшить или увеличить качетсво. работает на всех хостах.
              <?php
              /**
               * OnManagerPageBeforeRender
               * OnWebPagePrerender
               * OnSiteRefresh
               * 
               * Generate Webp image format
               * 
               * Uses either Imagick or imagewebp to generate webp image
               * 
               * @param string $file Path to image being converted.
               * @param int $compression_quality Quality ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file).
               * 
               * @return false|string Returns path to generated webp image, otherwise returns false.
               */
              
              
              if(
              	$modx->event->name == 'OnSiteRefresh' ||
              	$modx->event->name == 'OnTemplateSave' ||
              	$modx->event->name == 'OnChunkSave' ||
              	$modx->event->name == 'OnPluginSave' ||
              	$modx->event->name == 'OnTemplateVarSave' ||
              	$modx->event->name == 'OnDocFormSave' ||
              	$modx->event->name == 'OnSnippetSave'
              ) {
              	$options= [xPDO::OPT_CACHE_KEY=>'webp_on_page']; // Clear webp modx cache
              	$modx->cacheManager->clean($options);
              }
              
              function jcphp01_modx_custom_generate_webp_image($file, $compression_quality = 80)
              {
                  
                  
                  $fileWithBasePath = preg_replace("~\/(?!.*\/)(.*)~", '', MODX_BASE_PATH) . $file;
                  
                  // check if file exists
                  if (!file_exists($fileWithBasePath)) {
                      return false;
                  }
              
                  // If output file already exists return path
                  $output_file = $file . '.webp';
                  $outputFileWithBasePath = $fileWithBasePath . '.webp';
                  
                  if (file_exists($outputFileWithBasePath)) {
                      return $output_file;
                  }
                  
                  
                  $file_type = strtolower(pathinfo($fileWithBasePath, PATHINFO_EXTENSION));
              
                  if (function_exists('imagewebp')) {
                      
                      switch ($file_type) {
                          case 'jpeg':
                          case 'jpg':
                              $image = imagecreatefromjpeg($fileWithBasePath);
                              break;
              
                          case 'png':
                              $image = imagecreatefrompng($fileWithBasePath);
                              imagepalettetotruecolor($image);
                              imagealphablending($image, true);
                              imagesavealpha($image, true);
                              break;
              
                          case 'gif':
                              $image = imagecreatefromgif($fileWithBasePath);
                              break;
                          default:
                              return false;
                      }
              
                      // Save the image
                      $result = imagewebp($image, $outputFileWithBasePath, $compression_quality);
                      if (false === $result) {
                          return false;
                      }
              
                      // Free up memory
                      imagedestroy($image);
              
                      return $output_file;
                  } elseif (class_exists('Imagick')) {
                      $image = new Imagick();
                      $image->readImage($fileWithBasePath);
              
                      if ($file_type === 'png') {
                          $image->setImageFormat('webp');
                          $image->setImageCompressionQuality($compression_quality);
                          $image->setOption('webp:lossless', 'true');
                      }
              
                      $image->writeImage($outputFileWithBasePath);
                      return $output_file;
                  }
              
                  return false;
              }
              
              
              
              
              
              function check_image_file_for_webp_converter_custom($img_real, &$webp_on_page){
              	static $uniq_imgs= [];
              	
              
              	$img_real= trim($img_real);
              	if(in_array($img_real, $uniq_imgs)) return;
              	$uniq_imgs[]= $img_real;
              	
              	$ext= strtolower(pathinfo($img_real, PATHINFO_EXTENSION));
              	if(
              		$ext == 'jpg' ||
              		$ext == 'jpeg' ||
              		$ext == 'png' 
              	) {
              		$abs= jcphp01_modx_custom_generate_webp_image($img_real);
              		$abs_base= str_replace('//', '/', MODX_BASE_PATH.$abs);
              
              		if( file_exists($abs_base)){
              			$webp_on_page[$img_real]= $abs;
              		}
              	}
              }
              
              
              try{
              
                  if( // replace jpg and png images to webp
                  	$modx->event->name == 'OnWebPagePrerender' && 
                  	stripos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false
                  ){
                      
                  	if($disable_replacing_for_logged_user && $modx->user->hasSessionContext('mgr')) return ''; 
                  	
                  	$options= [xPDO::OPT_CACHE_KEY=>'webp_on_page'];
                  	$cache_key= md5(MODX_SITE_URL.$_SERVER['REQUEST_URI']);
                  
                  	$cached_webp_on_page= $modx->cacheManager->get($cache_key, $options);
                  	$output= &$modx->resource->_output;
                  
                      
                  
                  	if( empty($cached_webp_on_page) ){
                  		$webp_on_page= [];
                  		
                  		preg_match_all('/<img[^>]+>/i', $output, $result);
                  		
                  		if(count($result)){ // Search images in img tag
                  			foreach($result[0] as $img_tag)	{
                  				$img_tag= str_replace("'", '"', $img_tag); // src
                  				preg_match('/(src)=("[^"]*")/i', $img_tag, $img[$img_tag]);						
                  				$img_real= str_replace('"', '', $img[$img_tag][2]);
                  				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
                  				
                  				preg_match('/(data-src)=("[^"]*")/i', $img_tag, $img[$img_tag]); // data-src					
                  				$img_real= str_replace('"', '', $img[$img_tag][2]);
                  				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
                  				
                  				preg_match('/(srcset)=("[^"]*")/i', $img_tag, $img[$img_tag]); // srcset
                  				$srcset= explode(',', str_replace('"', '', $img[$img_tag][2]));
                  				foreach($srcset as $src_item){
                  				    $src_a= explode(' ', $src_item);
                  				    if(isset($src_a[0]) && !empty($src_a[0])) {
                  				        check_image_file_for_webp_converter_custom($src_a[0], $webp_on_page);
                  				    } else {
                  				        if(isset($src_a[1]) && !empty($src_a[1])) {
                  				            check_image_file_for_webp_converter_custom($src_a[1], $webp_on_page);
                  				        }
                  				    }
                  				}
                  			}
                  		}
                  
                  		preg_match_all('/url\(([^)]*)"?\)/iu', $output, $result);
                  		if(count($result)){ // Search images in url css rules
                  			foreach($result[1] as $img_tag)	{
                  				if(stripos($img_real, 'data:')) continue;
                  				$img_real= str_replace(['"',"'"], '', $img_tag);
                  				check_image_file_for_webp_converter_custom($img_real, $webp_on_page);
                  			}
                  		}
                  		
                  		$webp_on_page['/webp/webp/']= '/webp/';
                  		$webp_on_page['//webp/']= '/webp/';
                  		$webp_on_page['.webp.webp']= '.webp';
                  		
                  		if(count($webp_on_page)) $output= str_replace(array_keys($webp_on_page), array_values($webp_on_page), $output);
                  		$modx->cacheManager->set($cache_key, serialize($webp_on_page), 0, $options);
                  	} else {
                  		$webp_on_page= unserialize($cached_webp_on_page);
                  		if(count($webp_on_page)){
                  			$output= str_replace(array_keys($webp_on_page), array_values($webp_on_page), $output);
                  		}
                  	}
                  	return '';
                  }
                  
              } catch (Exception $e){
                  $modx->log(1, $e);
              }
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              11