В тот момент, когда HTTP-клиент (ваш браузер или поисковой робот) отправляет на сервер запрос на получение документа, сервер перед документом отправляет определённые заголовки. Это и Content-Type, без которого браузер не знает, что ему делать с документом и установка Cookie, без которых не будет работать авторизация на большинстве сайтов и многие другие заголовки.
Среди всех заголовков не последнюю роль играет Last-modified. Он не является обязательным, но этот заголовок очень важен. Во-первых, он уменьшает нагрузку на сервер и скорость повторной загрузки страницы (клиенты не запрашивают весь документ, зная что документ не изменялся). Во-вторых, он даёт поисковым роботам очень много информации. Без данного заголовка скорость индексации сайта падает в разы.
Я был несколько удивлён, если не сказать ошеломлён, узнав что Joomla не отдаёт заголовка Last-modified. Порывшись в рунете, я нашел несколько костылей, которые исправляют данный недочёт. Но они были настолько кривые, что мне даже страшно было предположить, что курили их автора.
Итак, небольшое знание внутренностей Joomla даёт решение нашей задачи. Выводом основного контента страницы занимаются компоненты (дополнительного - модули). Дефолтный компонент, который выводит статьи, блоги статей и т.п. называется com_content. За вывод контента компонента в Joomla отвечают так называемые views. В компоненте их может быть несколько (см. /components/com_content/views/). Можно править файлы прямо там, но при обновлении Joomla они слетят, так что лучше создать папку html в папке шаблона, где создать определённую структуру.
Практическая часть
Допустим, нам надо выводить корректный Last-Modified для статей и блога статей остальные варианты я пока не рассматриваю.
Шаг 1.
Создаём директорию (папку) /templates/<Название шаблона>/html/, в ней — директорию com_content и уже в com_content создаём две директории article и category. Они будут отвечать за вывод отдельной статьи и списка статей (блогов и т.п.).
Шаг 2.
Копируем в эти директории содержимое /components/com_content/views/article/ и /components/com_content/views/category/ соответственно. Теперь мы можем менять вывод статей и блогов, не боясь апдейта Джумлы.
Вы теперь можете менять содержимое html/com_content/article/default.php для изменения разметки вывода статьи и html/com_content/category/blog.php для того чтобы поменять вывод блога. Заметьте, изменения происходят в шаблоне, не трогая внутренности Joomla!
Шаг 3 (Для Joomla 2.5).
Но ведь задача была в том, чтобы добавить вывод заголовка Last-Modified! Сейчас мы этим и займёмся. В html/com_content/article/default.php после defined('_JEXEC') or die; добавляем следующий код:
$last_modified=strtotime($this->item->modified);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
А в html/com_content/category/blog.php добавляем:
$last_modified=strtotime($this->category->modified_time);
foreach($this->items as $post){
$lm=strtotime($post->modified);
if($last_modified<$lm)
$last_modified=$lm;
}
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
Шаг 3 (Для Joomla 1.5).
В данной версии Джумлы слегка изменена объектная модель и есть некоторые «Палки в колёса» от разработчиков. Если вы проверите заголовки, то обнаружите что Last-modified равен текущему времени (с учётом временных поясов). Глубоко в дебрях CMS (/libraries/joomla/environment/response.php) спрятан код, который и отдаёт такие странные заголовки. Придётся его закомментировать:
if (JResponse::allowCache() === false){
//JResponse::setHeader( 'Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true );
//JResponse::setHeader( 'Last-Modified', gmdate("D, d M Y H:i:s") . ' GMT', true );
//JResponse::setHeader( 'Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
//JResponse::setHeader( 'Pragma', 'no-cache' ); // HTTP 1.0
}
Далее — всё как в предыдущем варианте, с учётом того что для статьи вместо $this->item надо использовать $this->article, а дата изменения категории не сохраняется (только дата каждого поста).
В html/com_content/article/default.php после defined('_JEXEC') or die; добавляем следующий код:
$last_modified=strtotime($this->article->modified);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
А в html/com_content/category/blog.php добавляем:
$last_modified=NULL;
foreach($this->items as $post){
$lm=strtotime($post->modified);
if((empty($last_modified))||($last_modified<$lm))
$last_modified=$lm;
}
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
Вместо заключения
Всё, готово! Проверяем заголовки и наслаждаемся результатом. Хотя данный вариант подходит всего лишь для статей и для блогов, менять остальные компоненты можно аналогичным образом.
Итак, мы научились менять вывод компонентов и успешно внедрили вывод заголовка Last-modified для статей и блогов, с чем я вас и поздравляю!
Вопросы пишите в комментариях.
Комментарии
На Joomla 3 не проверял. Думаю, там не сильно отличается. С прямыми руками поправить - как два пальца.
@Mila
Естественно. Для каждого компонента надо править отдельно. Плюс, модули пролетают. Разве что ковырять саму джумлу и каждый модуль/компонент в отдельности...
К сожалению, разработчики Joomla многих вещей не предусмотрели. Однако, данный костыль - наиболее элегантный из всех, которые я видел.
Joomshopping не смотрел, но, думаю, можно.
Без проблем патчил VirtueMart по алгоритму, описанному в статье.
Рекомендую для Joomla 3 плагин, у меня нормально запработало. Вот ссылка: http://www.sdf-group.ru/joomla/lmpluginj3.html
Удалось на Денвере нахимичить следующее:
В файле mydomen.ru/libraries/joomla/application/web.php 429ю строку
$this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
на это:
$this->setHeader('Last-Modified', $this->modifiedDate->format('D, d M Y H:i:s'));
В итоге тестовый сайт отдает Last Modified = дата изменения материала. К сожалению, по непонятным мне причинам, этот код не работает на основном сервере.
joomla 3
Сделал так, в шаблоне вывода контента
JResponse::allowCache(true);
Готово!
$last_modified=strtotime($this->item->modified);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT',true);
JResponse::setHeader('Cache-Control','public',true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
Спасибо за подсказку!
/templates/[ВАШ_ШАБЛОН]/html/com_k2/templates/default/category_item.php
После:
defined('_JEXEC') or die;
Добавить:
$last_modified=strtotime($this->item->modified);
foreach($this->item as $post){
$lm=strtotime($post->modified);
if($last_modified<$lm)
$last_modified=$lm;
}
JResponse::allowCache(true);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT',true);
JResponse::setHeader('Cache-Control','public',true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
/templates/[ВАШ_ШАБЛОН]/html/com_k2/templates/default/item.php
После:
defined('_JEXEC') or die;
Добавить:
JResponse::allowCache(true);
$last_modified=strtotime($this->item->modified);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT',true);
JResponse::setHeader('Cache-Control','public',true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
вместо изменений в файле /templates/[ВАШ_ШАБЛОН]/html/com_k2/templates/default/category_item.php
я сделал в /templates/[ВАШ_ШАБЛОН]/html/com_k2/templates/default/category.php
После:
defined('_JEXEC') or die;
Добавить:
defined('_JEXEC') or die;
$last_modified=strtotime($this->primary->modified);
foreach($this->primary as $post){
$lm=strtotime($post->modified);
if($last_modified<$lm)
$last_modified=$lm;
}
JResponse::allowCache(true);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT',true);
JResponse::setHeader('Cache-Control','public',true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
* $this->primary - это у меня все материалы в категории в виде первичных материалов, других нет.
Но нужно учесть, что также есть основные ($this->leading), вторичные ($this->secondary), ссылки ($this->links)
Пусть меня поправит тот кто лучше разбирается в php чем можно заменить $this->primary на более универсальное, но у меня отлично и так работает.
Я думаю, это может не работать со специфическими сортировками, а так ок.
Я бы ещё добавил проверку на дату изменения самой категории (например, если изменилось описание или МЕТА данные категории).
Ещё вопрос - $this->primary это что? Массив? Объект?
В одном месте вы работаете как с объектом ($this->primary->modified).
А чуть ниже - как с массивом (foreach($this->primary as $post){)
И еще заметил глюк, по крайней мере у меня: время показывается с вычитанием не 3-х часов (поправка на UTC +3 часа), а 6-ти (!!!) часов. Поэтому, прибавил 3 часа в секундах 10800 и получилось так:
defined('_JEXEC') or die;
$last_modified=strtotime($this->primary->modified)+10800;
foreach($this->primary as $post){
$lm=strtotime($post->modified);
if($last_modified<$lm)
$last_modified=$lm+10800;
}
JResponse::allowCache(true);
JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT',true);
JResponse::setHeader('Cache-Control','public',true);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
die;
}
Решений этой проблемы нашел в интернете (даже в англоязычном) 3-4, ничего не работало, только этот способ сработал!
Версия джумлы последняя - 3.6.5!
Заработало! Ура!
http://kinofilesm.forum.cool/viewtopic.php?id=31
http://kinofilesm.6bb.ru/viewtopic.php?id=21
http://kinofilesm.owitch.ru/viewtopic.php?id=28
http://kinofilesm.7bb.ru/viewtopic.php?id=45
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костолом трейлер[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костолом смотреть онлайн[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]кино костолом[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костоломов юрий владимирович[/url]
фильм костолом смотреть онлайн в хорошем качестве
костолом смотреть онлайн в hd 1080
костолом смотреть онлайн бесплатно
костолом актеры
фильм костолом актеры
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костолом 2020 смотреть онлайн[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костолом смотреть онлайн[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]костоломов юрий владимирович[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]фильм костолом смотреть онлайн в хорошем качестве[/url]
[url=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html]их звали костоломы[/url]
костоломов юрий владимирович
смотреть фильм костолом 2020
костолом трейлер на русском
костолом смотреть онлайн в хорошем качестве
костолом фильм 2020
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом трейлер на русском</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>смотреть костолом</a>
кино костолом
смотреть фильм костолом
костолом трейлер на русском
смотреть костолом
костолом генератор чисел
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом 2020 смотреть онлайн</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн бесплатно в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом фильм 2020</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом фильм</a>
костолом смотреть онлайн в hd 1080
их звали костоломы
костолом фильм
костолом 2020
костоломов юрий владимирович
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>смотреть фильм костолом 2020</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн бесплатно в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом трейлер на русском</a>
костолом трейлер
костолом смотреть онлайн в хорошем качестве
костолом 2020 смотреть онлайн
костолом генератор чисел
фильм костолом смотреть онлайн
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костоломов юрий владимирович</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн бесплатно в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом фильм</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом врач</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом 2020 трейлер</a>
костолом актеры
костолом генератор чисел
костолом смотреть онлайн бесплатно в хорошем качестве
костолом 2020 трейлер
костолом трейлер
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>дракон костолом</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом генератор чисел</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом актеры</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом 2020</a>
костолом фильм 2020
костолом
костолом смотреть онлайн
костоломов юрий владимирович
дракон костолом
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом 2020 смотреть онлайн</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом трейлер</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>костолом смотреть онлайн бесплатно в хорошем качестве</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>их звали костоломы</a>
<a href=http://kinoslon.website/uzhasy/280-kostolom-2020-smotret-onlajn.html>кино костолом</a>
смотреть фильм костолом 2020
костолом смотреть онлайн
их звали костоломы
костолом генератор чисел
костолом актеры
Заполните форму и мы подберем займ
от компаний и банков, готовых выдать Вам деньги
Возраст: От 18 до 70 лет <a href=https://intercreditl.ru/offers/potrebitelskij-kredit/>https://intercreditl.ru/offers/potrebitelskij-kredit/</a>
Подбор займа онлайн, кредитов, кредитных карт
Размер: от 1.000 до 3.000.000 руб
Срок: От 7 дней до 5 лет
Время рассмотрения: от 7 минут
Получение денег: Мобильный телефон, наличными или через платежные системы
Возраст: От 18 до 70 лет <a href=https://intercreditl.ru/offers/mikrozajmy/>https://intercreditl.ru/offers/mikrozajmy/</a>
<a href=https://intercreditl.ru/sovety/>https://intercreditl.ru/sovety/</a> Советы
<a href=http://crmp.su/forum/viewtopic.php?f=42&t=45263>Кредитные карты с кэшбеком</a> <a href=http://www.rybak-rybaka.ru/forum/messages/forum18/topic12277/message236880/?sessid=57990f754623ac3687643ea688ca2cb6&TOPIC_SUBSCRIBE=Y&FORUM_SUBSCRIBE=Y&result=new>Микрозаймы Срочные</a> <a href=http://autoprogs.ru/diagnostika-kitaiskih-avtomobilei-remont-elektroniki-278/great-wall-h3-19992/index2.html#post954576>Микрозайм без справок о доходах</a> aba9498
dulcolax price https://dulcolax4u.top in Canada
Everything trends of medicine. Get information now.
https://amp.ru.vaskar.co.in/translate/1?to=en&from=ru&source=Meds%20prescribing%20information.%20Generic%20Name.%20%0D%0A%3Ca%20href%3D%22https%3A%2F%2Fdiflucan4u.top%22%3Ediflucan%20order%3C%2Fa%3E%20in%20Canada%20%0D%0AAll%20information%20about%20medicine.%20Get%20information%20here.%20%0D%0A%20%0D%0Ahttp%3A%2F%2F4booking.net%2Fpage-full-width-page%2F%23comment-80684%20Best%20about%20pills.%20http%3A%2F%2Falim.mn%2Farticle%2F1799%20All%20about%20medicine.%20https%3A%2F%2Fahimkh-yuluyuu-tny.blog.ss-blog.jp%2F2013-03-15%3Fcomment_success%3D2021-01-10T00%3A09%3A03%26time%3D1610204943%20Best%20news%20about%20pills.%20%20cb245_b%20&result=Meds%20prescribing%20information.%20Generic%20Name.%20%3Ca%20href%3D%22https%3A%2F%2Fdiflucan4u.top%22%3Ediflucan%20order%3C%2Fa%3E%20in%20Canada%20All%20information%20about%20medicine.%20Get%20information%20here.%20http%3A%2F%2F4booking.net%2Fpage-full-width-page%2F%23comment-80684%20Best%20about%20pills.%20http%3A%2F%2Falim.mn%2Farticle%2F1799%20All%20about%20medicine.%20https%3A%2F%2Fahimkh-yuluyuu-tny.blog.ss-blog.jp%2F2013-03-15%3Fcomment_success%3D2021-01-10T00%3A09%3A03%26time%3D1610204943%20Best%20news%20about%20pills.%20cb245_b Actual trends of medicine. http://archiwum.pion.pl/web/node/434?page=534#comment-2322443 Everything trends of medicine. https://beercrunch.com/beer/braumanufaktur-hertl-jagermeister-bock Best news about meds. a9498a7