Выбор первых картинок из контента
Вариант с использованием properties. Используется в плейсхолдере например так
<img src="[[+properties.first_img_src.0]]" >
Плагин нужно выставить для события OnBeforeDocFormSave
Плагин перезаписывает последнюю актуальную картинку на момент сохранения ресурса, под словом актуальную я имею в виду то, что делается проверка на корректность файла, и если он действительно существует, то только тогда произойдет действие.
Если картинки не найдено — то будет записан null
{"first_img_src":null}
если контент вообще пустой -то ничего не произойдет вообще.
Код можно как угодно доработать, зависит от логики реализации.
Код плагина:
<?php
if ($modx->event->name == 'OnBeforeDocFormSave') {
//get current content for resource
$content = $resource->getContent();
if (!empty($content)){
//get first image in content
$doc = new DOMDocument();
$doc->loadHTML($content);
$xml = simplexml_import_dom($doc);
$images = $xml->xpath('//img');
foreach ($images as $img) {
//also avaliable in array $img['alt'] и $img['title]
$file_headers = @get_headers($img['src']);
if ($file_headers[0] != 'HTTP/1.1 404 Not Found') {
$first_img_src = $img['src'];
break;
}
}
//get properties
$properties = $resource->get('properties');
//here you can check for empty $first_img_src and set default noImage photo
//save or override first_img_src
$properties['first_img_src'] = $first_img_src;
$resource->set('properties', $properties);
}
}
В комментариях предлагается использовать так же парсер MODX http://bezumkin.ru/sections/tips\_and\_tricks/2192/#comment-17960
0
👍
👎
❤️
🔥
😮
😢
😀
😡
2 984
22.11.2013 16:31:14
23 комментария
Сергей
Если выбирается только 1 элемент, то зачем цикл? Если уж объявили переменную $file, то надо использовать до последнего =) Почините код чанка.
По моему лучше такие операции делать при создании материала, занеся адрес в отдельное поле.
Зачем так сложно? Почему бы просто не использовать preg_match?
Например, вот:
Если ты по поводу парсинга то тут каждому свое. Просто xpath заточен именно на это,и он стандартизирован W3C которому и я стараюсь придерживаться. По скорости разницы ты не заметишь, хотя можно протестировать =)
Ну а дополнительная проверка доступности изображения делается на случай, когда выводится пользовательский контент и пользователь например загрузил ссылку на изображение на сторонний ресурс,который сейчас не доступен. В итоге получим отсутствия изображения с ошибкой, что не эстетично. Тоже самое касается если файл просто удалится с хостинга - лучше не вывести ничего, чем бяку в виду не существующей ссылки на картинку, не так ли ? :)
Одна регулярка отработает быстрее, чем преобразование документа и поиск по DOM.
Ну и отсутствующая картинка что в превью, что в контенте - одинаково плохо. Или ты предлагаешь и при загрузке тикета так все картинки проверять и прятать?
Ну и подумай о том, что при выводе списка тиектов каждая картинка будет запрашиваться минимум дважды - сначала твой скрипт отработает, а потом юзер загрузит.
В общем, интересный велосипед, но на мой взгляд ценность очень сомнительна. Лучше уж логи проверять на предмет 404.
Можно использовать как угодно. По поводу скорости - проведу замер интересно тоже стало.
У меня это используется не везде конечно, а только на главной для вывода ТОП-5 новостей по определенным параметрам..Поэтому главную портить точно нет смысла. А подстраховаться можно,мало ли..
p.s вообще парсинг xml/xhtml/html код регулярками это как-то не красиво. Вот кажется эта статья на хабре http://habrahabr.ru/post/114772/ описывает что лучше отказаться от регулярок в пользу xpath Запросов =)
Поиск первой картинки через преобразование всего документа - вот что некрасиво.
Твой код, 100 итераций - 0.47 сек
Мой код, 100 итераций - 0.28 сек
Мой выбор очевиден.
скрипты без изменений,кроме ID страницы у меня отработали
0.20023822784424 -твой 0.22262501716614 -мой
странно..Притом контент был большой
И кстати - у тебя возвращается тег целиком,а у меня адрес. Т.е тебе нужно еще парсить $img для того чтобы достать адрес картинки,а это доп. действия и возможно доп. нагрузка. =)
p.s ну я и не пытаюсь его позиционировать как более совершенное решение.Зависит от цели, но на мой взгляд если например потребуется выбрать все картинки с страницы, то мое решение уже будет в плюсе,т.к самое сложное уже позади. по идее
Видимо, зависит от сложности форматирования. preg_match то пофиг - он не анализирует документ.
Вот гляди: http://s4327.modx-test.com/pcre.html - 0.22 сек http://s4327.modx-test.com/xpath.html - 0.51 сек
http://s4327.modx-test.com/manager/ Логин s4327 Пароль SufmusRqoRnJ
Алексей Карташов
Идея правильная. Только есть ещё один вариант.
Вот как можно сделать по-другому (просто времени реализовать такое у меня не было): Пишем плагин на событие сохранения документа, который берёт контент этого документа, парсит его modx-парсером, вытаскивает из контента картинку, и вот здесь простой финт - записывает эту картинку в tvшку.
Потом собрать пакет, который автоматом создаст нужную tvшку, и при установке пробежится по уже существующим документам и сделает свою работу. Плагин будет сохранять картинку в tv независимо от того - привязана эта tv-шка к шаблону текущего ресурса или нет (просто создаёт запись в таблице site_tmplvars_content_values (по-моему как-то так она называется)). А уж потом эту tvшку можно привязывать к любому шаблону - превьюшки уже будут на месте.
Но здесь есть один минус - если в контенте документа используются какие-либо сниппеты, благодаря которым выводимый контент динамически меняется независимо от того, сохранялся доумент или нет, то такой способ может не подойти.
Ваша идея - картинка всегда вытягивается из актуального (на момент загрузки страницы с этим сниппетом) контента документа, но работа делается каждый раз при обращении к этой странице (со сниппетом). Моя - делать работу один раз, сохраняя картинку по событию, и везде, где только можно, использовать эту tvшку штатными modx-средствами. Но при наличии страниц с динамичным контентом этот метод может не подойти.
Выбирайте :-)
Не плохое решение +) Тут зависит уже от нужд. Но коли речь зашла о плагинах и TV я бы предпочел вместо TV использовать свойство properties и запихивать уже туда код первой картинки в ресурс.Это и дает существенный прирост в скорости, и вообще выглядит куда красивее, =) Возможно реализую, если появится свободное время. =)
Тоже реализовал это через плагин к твшкам.
сорри так, без scriptProperties не работает =) идея сохранять в properties интересная, надо будет попробовать
Вот вариант с properties. Используется в плейсхолдере например так
Плагин нужно выставить для события OnBeforeDocFormSave
Плагин перезаписывает последнюю актуальную картинку на момент сохранения ресурса. Если картинки не найдено - то будет записан null
Код можно как угодно доработать, зависит от логики реализации.
Я думаю это самый практичный из приведенных выше вариантов работы,в плане скорости,т.к мы не тратим ничего на выходе.
Скрипт конечно полезный,только он не дает сохранить пустой ресурс *2168705 FastCGI sent in stderr: "PHP message: PHP Fatal error: Call to a member function xpath() on a non-object in www/core/cache/includes/elements/modplugin/6.include.cache.php on line 15"
Спасибо за наводку, не подумал об этом. Вот фикс:
Алексей Карташов
Забыли пропарсить контент modx-парсером:
Да, согласен, это полезно т.к действительно в контенте могут быть сниппеты и чанки в которых может выводиться изображение. Но я не стал это добавлять,т.к в моих страницах не предполагается использовать ModX теги в контенте, поскольку он редактируется с фронта, и важно выводить лишь то,что заполнил ручками пользователь. Добавлю в шапку сноску на Ваш пост.
Подскажите пожалуйста, что нужно изменить,чтобы этот плагин с Tickets начал работать из frontend? Я почему-то был уверен, что он и без изменений заработает,но к сожалению нет.
up! Если создавать тикет из бэкенда,то плагин записывает в базу строку
, что позволяет потом обернуть ее например в phptrumbon и делать превью. Если же создавать тикет из фронтенда,то плагин записывает в базу строку
и phptrumbon воспринимает изображение как лежащее на внешнем сервере и отдает заглушку. Посоветуйте как быть с превью...
Василий, хотел бы твое мнение услышать, и мне кажется есть смысл перенести в Тонкости и трюки, т.к на мой взгляд штука очень полезная
У меня доступ в админку закрыт по ip и было лень включать.
Перенес.
А я в свою очередь поправил шапку под последнее актуальное состояние, чтобы не путать людей.
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
Василий Наумкин
04.02.2025 19:27:08
Я таким давно не занимаюсь и с MODX не работаю.
Попробуйте обратиться к ребятам с modx.pro.
Василий Наумкин
23.12.2024 05:33:00
В MODX сначала создали проблему, автоматически генерируя адреса, а потом "решили" заморозкой.
Так ч...
Дмитрий
14.12.2024 09:10:38
Василий, прошу прощения, тупанул, не разобрался сразу. Фреймворк отличный! "Чистый лист" на vue, рис...
Василий Наумкин
05.12.2024 20:01:14
В итоге основная ошибка была в неправильном общем root в Nginx, из-за чего запросы не улетали на фай...
Василий Наумкин
01.07.2024 11:56:41
Да, верно, именно так.
А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024 09:38:15
О, точно, вылезает если не залогинен.
Спасибо, исправил!
Уровни подписки
Спасибо!
500 ₽ в месяц
Эта подписка ничего не даёт, просто возможность сказать спасибо за мои заметки. Подписчики отмечаются зелёненьким цветом в комментариях.
Большое спасибо!
1 000 ₽ в месяц
И эта подписка не даёт ничего, кроме оранжевого цвета в комментариях и возможности сказать спасибо, но уже большое!