Задача: сделать чтобы все изображения, загруженные в поле content, обрезались до заданных размеров и выводились пользователю, само поле content, при этом, не заменяется новыми изображениями.
В данном примере, мы будем использовать:
Плагин с событием OnLoadWebDocument
Пакет для обработки изображений pThumb
Скрипт ленивой загрузки изображений lazysizes
Разобьем весь код на части:
Создаем плагин с событием OnLoadWebDocument, названием любым, например OnLoadWebDocument
В поле код плагина помещаем следующий код:
$eventName=$modx->event->name;
switch($eventName) {
case 'OnLoadWebDocument':
// код события
break;
}
В код события помещаем следующий код:
Если id шаблона не 1, то выходим
$template=$modx->resource->template;
if((int)$template!==1){
break;
}
Если контент пустой, то выходим
$content=$modx->resource->content;
$content=mb_convert_encoding(html_entity_decode($content), 'HTML-ENTITIES', 'UTF-8');
if(!$content){
break;
}
Берем контент, оборачиваем как страницу html, парсим, если изображений не найдено, то выходим
$doc=new DOMDocument();
$doc->encoding="utf-8";
$doc->recover=true;
$doc->strictErrorChecking=false;
$doc->loadHTML('<html>'.$content.'</html>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$images=$doc->getElementsByTagName('img');
if(count($images)==0){
break;
}
Задаем настройки для изображений, максимальную ширину, изображение по умолчанию
$maxwidthimg=740;
$defaultimg='/assets/img/icon-loading.svg';
Проходимся цикром по всем изображениям, берем только те у которых есть src и он не равен изображению по умолчанию, добавляем класс lazyload и атрибут data-src, задаем ширину для изображения
foreach($images as $image){
$src=$image->getAttribute('src');
if(!$src){
continue;
}
if($src==$defaultimg){
continue;
}
$newsrc=$modx->runSnippet('pThumb', array(
'input' => $src,
'options' => 'w='.$maxwidthimg.'&f=jpg&q=90',
));
if(!$newsrc){
continue;
}
$image->setAttribute('data-src',$newsrc);
$image->setAttribute('src',$defaultimg);
$class=$image->getAttribute('class');
$classarray=explode(',',$class);
$classarray[]='lazyload';
$newclass=implode(' ',$classarray);
$image->setAttribute('class',$newclass);
$width=$image->getAttribute('width');
if((int)$width>$maxwidthimg){
$image->setAttribute('width','100%');
$image->removeAttribute('height');
}
}
Сохраняем полученный результат и заменяем наш контент новым, убирая обертку html
$modx->resource->content=str_replace(array('<html>','</html>'),'',$doc->saveHTML());
В итоге получаем следующий год:
$eventName=$modx->event->name;
switch($eventName) {
case 'OnLoadWebDocument':
$maxwidthimg=740;
$defaultimg='/assets/img/icon-loading.svg';
$template=$modx->resource->template;
if((int)$template!==1){
break;
}
$content=$modx->resource->content;
$content=mb_convert_encoding(html_entity_decode($content), 'HTML-ENTITIES', 'UTF-8');
if(!$content){
break;
}
$doc=new DOMDocument();
$doc->encoding="utf-8";
$doc->recover=true;
$doc->strictErrorChecking=false;
$doc->loadHTML(''.$content.'', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$images=$doc->getElementsByTagName('img');
if(count($images)==0){
break;
}
foreach($images as $image){
$src=$image->getAttribute('src');
if(!$src){
continue;
}
if($src==$defaultimg){
continue;
}
$newsrc=$modx->runSnippet('pThumb', array(
'input' => $src,
'options' => 'w='.$maxwidthimg.'&f=jpg&q=90',
));
if(!$newsrc){
continue;
}
$image->setAttribute('data-src',$newsrc);
$image->setAttribute('src',$defaultimg);
$class=$image->getAttribute('class');
$classarray=explode(',',$class);
$classarray[]='lazyload';
$newclass=implode(' ',$classarray);
$image->setAttribute('class',$newclass);
$width=$image->getAttribute('width');
if((int)$width>$maxwidthimg){
$image->setAttribute('width','100%');
$image->removeAttribute('height');
}
}
$modx->resource->content=str_replace(array('',''),'',$doc->saveHTML());
break;
}