Задача: сделать чтобы все изображения, загруженные в поле 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;
}