Skip to content

Instantly share code, notes, and snippets.

@TrywaR
Last active February 14, 2020 15:10
Show Gist options
  • Save TrywaR/11daff6b66a64015abebe0e332613eba to your computer and use it in GitHub Desktop.
Save TrywaR/11daff6b66a64015abebe0e332613eba to your computer and use it in GitHub Desktop.
MODX Revo > Обработка картинок в контенте
/*_____________________ VeryLazy ______________________*/
// - Подгрузка изображений в блоках при их показе на экране
block_selector = '.home ._block'; // Селектор блоков
function VeryLazy(){
if ($('html').hasClass('webp')) {
$(document).find(block_selector).each(function(index, element){
if ($(document).scrollTop() > $(this).offset().top - $(window).height()){
$(this).addClass('active').find('img[data-src],img[data-webp]').each(function() {
if ($(this).data().webp)
$(this).attr('src', $(this).data().webp)
else
$(this).attr('src', $(this).data().src)
})
// picture
// $(this).find('picture[data-webp]').each(function() {
// if ($('html').hasClass('webp') && $(this).data().webp)
// $(this).attr('srcset', $(this).data().webp)
// })
}
})
}else{
$(document).find(block_selector).each(function(index, element){
if ($(document).scrollTop() > $(this).offset().top - $(window).height()){
$(this).addClass('active').find('img[data-src]').each(function() {
$(this).attr('src', $(this).data().src)
})
}
})
}
}
$(document).scroll(function(){
VeryLazy()
})
VeryLazy()
// - Просто сразу подгрузка
$(function(){
if ($('html').hasClass('webp')) {
$(document).each('img[data-src],img[data-webp]',function(){
if ($('html').hasClass('webp') && $(this).data().webp)
$(this).attr('src', $(this).data().webp)
else
$(this).attr('src', $(this).data().src)
})
// picture
// $(document).each('picture[data-webp]',function(){
// $(this).attr('srcset', $(this).data().webp)
// })
}
})
/*///////////////////////////////////////////////////////*/
<?
// Параметры
$sImgFolder = 'cache_small_img/'; # Папка для сжатых картинок
$sWebpQuality = 65; # Мощность сжатия (0-100)
$sWebpQualityWebp = 100; # Сжатия webp (0-100), если меньше 100 будет двойное сжатие после сжатия миниаюры
$sMainSelector = 'main'; # Селектор для содержания страницы, чтобы не обрабатывать лишние картинки
$sNoSelector = 'no_convert'; # Класс для картинки, которую не стоит обрабатывать
$sImgHrefAttr = 'data-fancybox="gorup" class="img_content"'; # Атрибуты для ссылки на картинку
$sImgMaxWidth = '700'; # Максимальная ширина для миниатюр
$sImgMaxHeight = '700'; # Максимальная высота для миниатюр
$boolLazy = false; # src в тег dada-src для ленивой подгрузки
$boolPicture = false; # обёртка в тег picture
$boolHref = true; # ссылка на оригинал, если надо, для галереи
$boolWebp = true; # Проверка на поддержку webp тут, на php
$boolImageHeight = false; # Подставлять изображениям высоту
$boolTitle = true; # Добавлять title если нет
$boolAlt = true; # Добавлять alt если нет
$sImageTitle = $modx->resource->pagetitle; # откуда брать title
$sImageAlt = $modx->resource->pagetitle; # откуда брать alt
// Подключение webp-convert
require_once( $modx->config['base_path'].'lib/webp-convert/webp-convert.inc' );
use WebPConvert\WebPConvert;
// Подключение phpQuery
require_once( $modx->config['base_path'].'lib/phpQuery-onefile.php' );
// Подключаем phpthumb
$phpThumb = $modx->getService('modphpthumb','modPhpThumb', MODX_CORE_PATH . 'model/phpthumb/', array());
// Проверка на поддержку webp тут, на php
if ($boolWebp) {
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
$notSupportDevice = array('iphone', 'ipod', 'ipad','macintosh','mac os','Edge','MSIE');
$boolSupportWebp = true;
foreach ($notSupportDevice as $val)
if(stripos($userAgent, $val) !== false)
$boolSupportWebp = false;
}
$boolCreate = false; # нужно ли резать и конвертировать картинки
// Проверяем есть ли папка для картинок
if (!file_exists($sImgFolder)) {
mkdir($sImgFolder);
$boolCreate = true;
}
// Проверяем, создавались ли картинки для текущего рессурса
$sImgFolder = $sImgFolder . $modx->resource->id . '/';
if (!file_exists($sImgFolder)) {
mkdir($sImgFolder);
$boolCreate = true;
}
// Обрабатываем контент
$sContent = &$modx->resource->_output; # берём контент
$oDocument = phpQuery::newDocument($sContent); # создаём из него объект phpQuery
$oDocumentMain = &$oDocument->find($sMainSelector); # вытаскиваем содержание страницы
// Беребираем картинки
foreach ($oDocumentMain->find('img') as $oImage) {
$oImage = pq($oImage); # аналог $ в jQuery
// Если картинку можно обрабатывать
if ( $sNoSelector != $oImage->attr('class') ){
// - Все возможные адреса картинки
$sImgSrc = $oImage->attr('src');
$sImgSrcFull = str_replace("//", "/", $modx->config['base_path'] . $sImgSrc);
$sImgSrcSmall = str_replace("//", "/", $sImgFolder . basename($sImgSrc));
$sImgSrcSmallFull = str_replace("//", "/", $modx->config['base_path'] . $sImgSrcSmall);
$sImgSrcWebp = str_replace("//", "/", $sImgFolder . basename($sImgSrc) . '.webp');
$sImgSrcWebpFull = str_replace("//", "/", $modx->config['base_path'] . $sImgSrcWebp);
// - Если картинка есть, работаем дальше
if (file_exists($sImgSrcFull)) {
// -- Парамтеры картинки
$sImgWidth = $oImage->attr('width');
$sImgHeight = $oImage->attr('height');
$arrImageSize = getimagesize($sImgSrcFull);
if ($sImgWidth=="") $sImgWidth = $arrImageSize[0];
if ($sImgHeight=="") $sImgHeight = $arrImageSize[1];
// -- Если обработанные картинки уже есть, не создаём
if ($boolCreate) {
// --- Нужно ли резать?
if ($sImgWidth > $sImgMaxWidth || $sImgHeight > $sImgMaxHeight) {
if ($sImgWidth > $sImgMaxWidth) $sImgWidth = $sImgMaxWidth;
if ($sImgHeight > $sImgMaxHeight) $sImgHeight = $sImgMaxHeight;
// ---- Параметры обрезки
$phpThumb->setSourceFilename($sImgSrcFull);
$phpThumb->setParameter('w', $sImgWidth);
$phpThumb->setParameter('h', $sImgHeight);
$phpThumb->setParameter('q', $sWebpQuality);
$phpThumb->setParameter('zc', 0);
$phpThumb->setParameter('f', pathinfo($sImgSrc, PATHINFO_EXTENSION));
// ---- Обрезка
if ($phpThumb->GenerateThumbnail())
// ----- сохраняем в файл
if (!$phpThumb->renderToFile( $sImgSrcSmallFull ))
$modx->log(modX::LOG_LEVEL_ERROR, 'Не удалось заехать в квартирку по адресу: ' . $sImgSrcSmallFull );
// else
// ----- Если возникла ошибка - пишем лог работы в журнал MODX
// $modx->log(modX::LOG_LEVEL_ERROR, print_r($phpThumb->debugmessages, 1));
}
// --- Нужно ли перегонять в webp?
if (pathinfo($sImgSrcFull, PATHINFO_EXTENSION) != 'webp'){
// ---- Преегоняем обрезанную версию?
if (file_exists($sImgSrcSmallFull)) {
if (!WebPConvert::convert($sImgSrcSmallFull, $sImgSrcWebpFull, ['quality' => $sWebpQualityWebp]))
$modx->log(modX::LOG_LEVEL_ERROR, 'Не удалось создать webp :( ' . $sImgSrcWebpFull);
}
// ---- Перегоняем обычную версию
else {
if (!WebPConvert::convert($sImgSrcFull, $sImgSrcWebpFull, ['quality' => $sWebpQualityWebp]))
$modx->log(modX::LOG_LEVEL_ERROR, 'Не удалось создать webp :( ' . $sImgSrcWebpFull);
}
}
}
// -- Если нет миниатюры используем оригинал
if ( !file_exists($sImgSrcSmallFull) ) {
$sImgSrcSmall = $sImgSrc;
$sImgSrcSmallFull = $sImgSrcFull;
}
// -- Ссылка на оригинал
if ($boolHref && file_exists($sImgSrcSmall)) {
$oImage->wrap('<a href="'.$sImgSrc.'" '.$sImgHrefAttr.'></a>'); # добавляем ссылку на оригинал
}
// -- Если подгрузка для ленивых
if ($boolLazy) {
$oImage->removeAttr('src');
$oImage->attr('data-src', $sImgSrcSmall);
}
else{
$oImage->attr('src', $sImgSrcSmall);
}
// -- Вывод webp
if (file_exists($sImgSrcWebp)) {
// --- Если проверка поддрежки wepb на стороне серва
if ($boolSupportWebp) {
if ($boolLazy)
$oImage->attr('data-src', $sImgSrcWebp);
else
$oImage->attr('src', $sImgSrcWebp);
}
// --- Если проверка поддрежки webp на стороне юзверя
else{
$oImage->attr('data-webp', $sImgSrcWebp);
}
$arrImageSize = getimagesize($sImgSrcWebpFull);
}
// -- Обычный вывод
else{
$arrImageSize = getimagesize($sImgSrcFull);
}
// -- Подставляем размеры
$oImage->attr('width', $arrImageSize[0]);
if ($boolImageHeight)
$oImage->attr('height', $arrImageSize[1]);
else
$oImage->attr('height', 'auto');
// -- Обёртка в picture если надо
if ($boolPicture) {
$oImage->wrap('<picture></picture>'); # оборачиваем в picture чтобы выводить в нескольких форматах
if (file_exists($sImgSrcWebp)) # ссылка на webp
if ($boolLazy)
$oImage->after('<source data-webp="'.$sImgSrcWebp.'" type="image/webp">');
else
$oImage->after('<source srcset="'.$sImgSrcWebp.'" type="image/webp">');
}
// -- Теги title и alt если надо
if ($boolTitle) {
$sTitle = $oImage->attr('title');
if ($sTitle == '') $oImage->attr('title', $sImageAlt);
}
if ($boolAlt) {
$sAlt = $oImage->attr('alt');
if ($sAlt == '') $oImage->attr('alt', $sImageTitle);
}
}
else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Нет картинки :( ' . $sImgSrcFull);
}
}
}
// Вывод
$oDocument->find('meta[http-equiv="Content-Type"]')->remove();
$sContent = $oDocument->html();
$modx->Event->output($sContent);
@TrywaR
Copy link
Author

TrywaR commented Jan 9, 2020

Небольшой баг, phpQuery добавляет тег <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> в head и header's, сделал пока небольшой костыль чтобы это исправить, в строчке 175

$oDocument->find('meta[http-equiv="Content-Type"]')->remove();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment