Joomla и Last-modified

Joomla и Last-modified

В тот момент, когда 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; добавляем следующий код:

  1. $last_modified=strtotime($this->item->modified);
  2. JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
  3. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
  4. 	header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
  5. 	die;
  6. 	}

А в html/com_content/category/blog.php добавляем:

  1. $last_modified=strtotime($this->category->modified_time);
  2. foreach($this->items as $post){
  3. 	$lm=strtotime($post->modified);
  4. 	if($last_modified<$lm)
  5. 		$last_modified=$lm;
  6. 	}
  7. JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
  8. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
  9. 	header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
  10. 	die;
  11. 	}

Шаг 3 (Для Joomla 1.5).

В данной версии Джумлы слегка изменена объектная модель и есть некоторые «Палки в колёса» от разработчиков. Если вы проверите заголовки, то обнаружите что Last-modified равен текущему времени (с учётом временных поясов). Глубоко в дебрях CMS (/libraries/joomla/environment/response.php) спрятан код, который и отдаёт такие странные заголовки. Придётся его закомментировать:

  1. if (JResponse::allowCache() === false){
  2. 	//JResponse::setHeader( 'Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true );
  3. 	//JResponse::setHeader( 'Last-Modified', gmdate("D, d M Y H:i:s") . ' GMT', true );
  4. 	//JResponse::setHeader( 'Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
  5. 	//JResponse::setHeader( 'Pragma', 'no-cache' ); 											// HTTP 1.0
  6. 	}

Далее — всё как в предыдущем варианте, с учётом того что для статьи вместо $this->item надо использовать $this->article, а дата изменения категории не сохраняется (только дата каждого поста).

В html/com_content/article/default.php после defined('_JEXEC') or die; добавляем следующий код:

  1. $last_modified=strtotime($this->article->modified);
  2. JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
  3. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
  4. 	header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
  5. 	die;
  6. 	}

А в html/com_content/category/blog.php добавляем:

  1. $last_modified=NULL;
  2. foreach($this->items as $post){
  3. 	$lm=strtotime($post->modified);
  4. 	if((empty($last_modified))||($last_modified<$lm))
  5. 		$last_modified=$lm;
  6. 	}
  7. JResponse::setHeader('Last-Modified',gmdate('D, d M Y H:i:s', $last_modified).' GMT');
  8. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>=$last_modified){
  9. 	header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
  10. 	die;
  11. 	}

Вместо заключения

Всё, готово! Проверяем заголовки и наслаждаемся результатом. Хотя данный вариант подходит всего лишь для статей и для блогов, менять остальные компоненты можно аналогичным образом.

Итак, мы научились менять вывод компонентов и успешно внедрили вывод заголовка Last-modified для статей и блогов, с чем я вас и поздравляю!

Вопросы пишите в комментариях.

Комментарии

05.05.2013 01:39:16
Avatar of РоманРоман
Не работает на Joomla 3
26.10.2013 06:05:04
Avatar of MilaMila
Да и с компонентом zoo врядли получится :(
30.10.2013 11:53:06
Avatar of КонсервКонсерв
@Роман
На Joomla 3 не проверял. Думаю, там не сильно отличается. С прямыми руками поправить - как два пальца.

@Mila
Естественно. Для каждого компонента надо править отдельно. Плюс, модули пролетают. Разве что ковырять саму джумлу и каждый модуль/компонент в отдельности...
К сожалению, разработчики Joomla многих вещей не предусмотрели. Однако, данный костыль - наиболее элегантный из всех, которые я видел.
09.12.2013 03:07:01
Avatar of ЯрикЯрик
А для Joomshopping, для товаров и категорий можно изменить ???
11.12.2013 10:21:44
Avatar of КонсервКонсерв
@Ярик
Joomshopping не смотрел, но, думаю, можно.

Без проблем патчил VirtueMart по алгоритму, описанному в статье.
24.12.2013 10:55:29
Avatar of Юра ГалинЮра Галин
Рекомендую онлайн сервис для проверки Last Modified: http://last-modified.com/ru/if-modified-since.html
24.12.2013 11:14:01
Avatar of Юра ГалинЮра Галин
@Роман
Рекомендую для Joomla 3 плагин, у меня нормально запработало. Вот ссылка: http://www.sdf-group.ru/joomla/lmpluginj3.html
15.01.2014 01:55:05
Avatar of ВладимирВладимир
У меня сайт на Joomla 3.2 и ни описанный способ, ни плагин не работают.
Удалось на Денвере нахимичить следующее:
В файле 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 = дата изменения материала. К сожалению, по непонятным мне причинам, этот код не работает на основном сервере.
27.02.2014 12:14:22
Avatar of СергейСергей
да и на Joomla 2.5.7 не работает
16.08.2014 11:33:30
Avatar of 202202
Спасибо за статью
29.07.2015 09:03:56
Avatar of AlexandrAlexandr
Пилю https://BiOS72.ru.
joomla 3
Сделал так, в шаблоне вывода контента
JResponse::allowCache(true);
Готово!
29.07.2015 10:14:32
Avatar of AlexandrAlexandr
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;
}
15.12.2015 06:12:28
Avatar of КонсервКонсерв
@Alexandr
Спасибо за подсказку!
05.05.2016 09:49:41
Avatar of СергейСергей
Если кому интересно, то вот по аналогии для компонента K2 - проверено работает (jommla 3.4.8)!

/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;
}
06.05.2016 11:55:25
Avatar of СергейСергей
Кстати, в категории все-таки дата глючит: когда норм показывает, когда нет. Поэтому, я переделал вот так:

вместо изменений в файле /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 на более универсальное, но у меня отлично и так работает.
06.05.2016 04:16:30
Avatar of КонсервКонсерв
@Сергей
Я думаю, это может не работать со специфическими сортировками, а так ок.

Я бы ещё добавил проверку на дату изменения самой категории (например, если изменилось описание или МЕТА данные категории).

Ещё вопрос - $this->primary это что? Массив? Объект?
В одном месте вы работаете как с объектом ($this->primary->modified).
А чуть ниже - как с массивом (foreach($this->primary as $post){)
16.05.2016 11:57:47
Avatar of СергейСергей
Консерв, честно говоря, я не заморачивался объект это или массив, т.к. в php мало разбираюсь. А подставлял я больше методом тыка :) Для меня главное - чтоб работало.

И еще заметил глюк, по крайней мере у меня: время показывается с вычитанием не 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;
}
07.06.2016 03:13:10
Avatar of КонсервКонсерв
@Сергей, тогда уж могут быть проблемы с летним/зимним временем :-)
15.04.2017 07:55:57
Avatar of ВикторВиктор
Огромное спасибо! Не поленюсь написать!

Решений этой проблемы нашел в интернете (даже в англоязычном) 3-4, ничего не работало, только этот способ сработал!

Версия джумлы последняя - 3.6.5!
16.04.2017 12:47:47
Avatar of ВикторВиктор
Нет! Рано радовался! Коды отдает верно, но вот не показывает корректно дату создания статьи, всегда показывает дату созданию текущего дня :((((((
16.04.2017 12:57:20
Avatar of ВикторВиктор
Вставил то что писал Сергей - "для компонента K2 - проверено работает (jommla 3.4.8)!"
Заработало! Ура!
18.04.2017 11:40:03
Avatar of КонсервКонсерв
@Виктор, спасибо за отзыв!
06.03.2018 06:40:58
Avatar of KarlosrrnKarlosrrn
удалите,пожалуйста! <a href=https://penki.by/>.</a>





sh.i.n.ami.n.sk.2.0.15@gmail.com
29.03.2018 03:52:06
Avatar of CraigChestCraigChest
Приобрести можно на веб-сайте http://mang.bestseller-super.ru

Хотим предложить нашим клиентам потрясающее средство для похудения Mangoosteen. При помощи него можно сжечь около 15 кг за 2 недели.

Растение мангостин растет на Филиппинах. Плоды данного дерева имеют удивительные свойства. В баночке содержится более 20 плодов данного замечательного растения. Плоды с растения мангкут помогают растопить излишнею жировую ткань. А также отлично воздействуют на человека в комплексе. Специфика изготовления препарата, и специализированная упаковка позволяют сохранить все полезные свойства мангостана.

Главным действующим компонентом сиропа Мангустина являются плоды с растения гарциния, в которых имеется большое число питательных микроэлементов. Благодаря веществу ксантону, которое в больших дозах содержатся в плодах, значительно тормозятся процессы окисления в теле. Окись дифениленкетона считается одним из наиболее мощных антиокислителей. В плоде дерева гарциния также имеются разные группы витаминов и элементы. Купить сироп Мансустина можно на сайте http://mangjoo77.mangoosteen.com.

15.04.2018 01:08:25
Avatar of CraigChestCraigChest
п»їGeneral Knowledge - Power to succeed in competitive exams

In most of the competitive exams that are conducted in the country, General knowledge is a very prominent segment. It is imperative that the candidate answers the questions based on general awareness and current affairs correctly to get good score in the exams. Candidate must appear for various GK quizzes to have a sound general awareness knowledge and understanding of the current events. Candidate who is thinking to appear for any competitive exam should be well versed in this domain. He cannot escape the general knowledge preparation and expect to pass the exam.
Nowadays, most of the companies, educational institutes and other exam conducting bodies lay special emphasis on the general awareness section. The primary aim of including this section in the test pattern is to ascertain and find out the awareness level of the candidate apart from the basic knowledge, aptitude and skill set. In any field and in every department, general knowledge is required to become successful. Because of this reason, candidates will find the general knowledge section in most of the exams. It has now become the part and parcel of every type of competitive exam.
Not only in the GK quiz but in any types of government examinations, defense examinations, private companies papers and recruitment tests, questions based on current affairs and general awareness will surely be there. It is necessary that the candidate brush up the basic concepts as well as abreast himself of the current happenings and events in the world. He may need to revise the entire general knowledge syllabus that he has studied at the school and the college level. Not only this, he should also study various GK quiz papers to be well versed with the latest paper pattern. He must realize that he needs separate preparation for the general awareness section.
Candidates must realize that scoring high in general knowledge section is one of the sure shot way to crack most of the competitive exams. Most of the general awareness questions are straight-forward and if the candidate has read or heard of the content, he may be able to score high in the exam. For most of the students, GK quiz and general knowledge section is a scoring part of the exam and they can even hope to get maximum marks in this. Just by preparing for few days, one can hope to pass all the competitive exams with flying colors.

Visit site: http://gameone.club/

Sydney Sweeney
15.04.2018 02:11:43
Avatar of CraigChestCraigChest
п»їWhy online trading is more convenient for stock market investors?

Online trading is a new technique of buying and selling shares through Internet-based trading platforms. The use of online trading increased after the introduction of high-speed computers and internet connections. Now a trader can trade stocks, bonds, mutual funds, futures, and currencies online without any complications. There are many financial advisors providing stock tips and other trading tips online with an aim to provide investment guidance to the traders.
Investing online is a process of buying and selling securities over the internet. This type of trading first came into existence in 1990's and now various brokers are providing the variety of online trading platforms to their clients.
Benefits of online trading -
1. It terminates role of middle person - Online trading removes interference of any middleman in the trading process, it allows a trader to trade with virtually no direct broker communication. It also decreases the overall trading cost and these benefits make this service much more profitable and hassle-free.
2. It is more convenient - When I talk about online trading, an investor only needs to open a trading account through the internet and then after completing some legal process they can start a trade. You don't have to see time and place as long as you have an internet connection. Thus, online trading is more convenient and accessible for traders from anywhere, It also saves time.
3. It is cheaper - In online trading, the broker fee which a trader will have to pay is lower as compared to the commission charged by the traditional method. If you trade in an in a large volume of stocks, it is possible for you to be able to negotiate your broker&rsquo;s commision.
4. Faster transaction - Online banking is more fast and efficient. Cash can be transferred between accounts almost instantly and conveniently, especially if the two accounts are held at the same bank. All it needs to be able to purchase or sell a stock is a single click of the mouse. Through online trading, a fast exchange can be done which also ensure quicker earnings.
5. An investor can monitor his investment - Online brokerages provide advanced interfaces that allow investors to see how well their stock is performing throughout the day. A trader just has to log in to his phone or computer and then they can easily see profit or losses in real time.
Many websites are offering effective tools and tips such as stock trading tips, commodity tips and binary option trading tips online to educate traders online and even allowing beginners to practice with virtual money before taking the plunge with the real deal. For both experienced traders and those with a limited knowledge of investing, online trading presents one affordable solution.

Visit site: http://gameone.club/

make money with affiliate marketing for beginners
Captcha Обновить
Go Top