Естественно копировать свежую информацию каждый раз, когда она появляется, менеджер сайта не захочет. Значит нужно все это дело автоматизировать, причем не давая лишнюю нагрузку на сервер.
Решение было найдено на основе xml и modx revo (хотя версия, если по честному, может быть любой).
Как опубликовать новости с одного сайта на втором?
Понадобится:- Два сайта на modx
- Доступы в админку
- Доступы на сервер
Первое, что мы делаем — это создаем удобный формат данный на сайте доноре. Назовем его news.site.com. Для этого создадим новый документ, укажем ему
- Тип содержимого — XML
- Опубликован — Да
- Шаблон — пустой

После сохранения, в само поле документа пропишем следующее:
<?xml version="1.0" encoding="utf-8"?>
<DailyExRates>
[[pdoResources?
&tpl=`xml-new-tpl`
&parents=`16`
&depth=`1`
&limit=`3`
&includeContent=`1`
&includeTVs=`img`
&tvPrefix=``
&sortby=`id`
]]
</DailyExRates>
Т.е. при помощи pdoResources мы перебираем все документы в 16-м родителе, забирая трех из них. Дополнить выборку можно на свой вкус. Мне же нужны будут фото, ссылка, название самых свежих новостей.
Теперь сам чанк xml-new-tpl. Изначально я собиралась сделать его сразу и rss рассылкой, но решила, что смысла в этом мало и просто произвольно вывожу нужные данные в таком формате:
<ItemNew id="{$idx}">
<Title>{$pagetitle}</Title>
<Links>{$_modx->config['site_url']}[[~{$id}]]</Links>
<Description>
{$content | striptags | limit:'200'}
</Description>
<Image>http://news.site.com[[phpthumbon? &input=`{$img}` &options=`&w=230&h=156&q=55`]]</Image>
<PubDate>{$publishedon | date:'m/d/Y'}</PubDate>
</ItemNew>
У нас есть порядковый номер, ссылка на новость, очищенный кусочек текста, прямая ссылка на картинку и даже дата публикации.
Сохранившись и просмотрев документ мы увидим результат. Если появилась ошибка — что то Вы сделали не так и лучше перепроверьте данные. Кстати, ошибки могут полезть от спецсимволов в pagetitle, помните об этом.
Вторая часть — сайт реципиент
Теперь готовые данные нужно получить и несколько вариантов на выбор:- Вывести напрямую на экран (регулярная нагрузка на 2 сайта)
- Сохранять куда-то (кэш, чанк, поле ресурса)
Я предпочитаю данные сохранять, чтобы не запрашивать их всякий раз. А для того, чтобы о них не беспокоиться — добавлять еще и запланированные задания.
На сайте company.site.com создаем TV поле с типом ввода Текстовое поле и именем news. Здесь же делаем новый сниппет с любым именем. Пусть это будетxml_new. В нем пишем:
<?php
$content = file_get_contents("http://news.site.com/xmlnew.xml"); // адрес страницы сайта-донора, которую создавали
$xml = new SimpleXMLElement($content);
$textpage = '';
// теперь перебираем полученный массив. У нас 3 новости. Записываем данные из XML в переменные и чуток чистим от спец символов.
for ($i = 0; $i <= 2; $i++) {
$title = $xml->ItemNew[$i]->Title;
$title = htmlspecialchars($title);
$title = htmlentities($title);
$link = $xml->ItemNew[$i]->Links;
$image = $xml->ItemNew[$i]->Image;
// В этом же цикле можно по полному пути к картинке сохранять ее на текущий сервер с перезаписываемыми именами 1,2,3. Тем самым наши новости станут еще менее зависимыми от сайта-донора.
$textpage .= '<div class="item">
<span>'.$title.'</span>
<div class="contento">
<img alt="'.$title.'" data-src="'.$image.'" src="" class="lazy_img" />
</div>
<a href="'.$link.'" title="'.$title.'">Подробнее</a>
</div>';
}
// склеиваем все в кучу и отправляем на запись в <strong>ресурс с ID 2</strong> в созданное нами заранее TV по имени <strong>news</strong>.
$res = $modx->getObject('modResource', 2);
$news = $res->getTVValue('news');
$res->setTVValue('news', $textpage);
Для проверки и удобства менеджера я еще создаю на сайте company.site.com ресурс (неопубликованный) с именем ОБНОВИТЬ НОВОСТИ. В котором пустой шаблон и только вызов в теле документа
[[xml_new]]
<p>Данные успешно обновлены.</p>
Теперь, при открытии данного документа мы запускаем скрипт и записываем данные в поле news ресурса №2. И сами новости на сайте реципиенте мы уже грузим из этого поля.
Автоматизация
Чтобы не задумываться о том, свежие ли данные, проще доверить их крону. Для этого на сайте company.site.com мы ставим приложение Cron Manager и в нем прописываем пути к нашему сниппету, ставим время обновления в минутах и активность.

Но. Чтобы запустить событие, нужно все же слазить и на сервер. В общем списке доступных возможностей будет cron (или запланированные задания, в зависимости от поставщика услуг).
Здесь мы указываем полный путь к нашему файлу и периодичность его запуска:
полный путь /assets/components/cronmanager/cron.php

Можно добавить и свой email, чтобы видеть, есть ли ошибки в пути к файлу.
В общем то на этом все. Данные можно передать любые и упаковывать по своему желанию :)
И огромное спасибо Олегу за поиск потерявшегося слеша в адресе из-за которого картинки упорно не желали отображаться.
Андрей Казунин 06.09.2017 16:47 #
Вараника 06.09.2017 20:02 #
Олег 09.09.2017 21:26 #
Через getChunk() было бы солиднее )
За спасибо спасибо =)
Вараника 11.09.2017 08:53 #
Илья Уткин 12.11.2017 13:35 #
В MODX есть прекрасный инструмент для кеширования данных — cacheManager. С его помощью можно сохранить данные на определённое время.
Благодаря кеш-менеджеру мы можем отказаться от cron, от неопубликованного ресурса и от лишнего ТВ-параметра. Вся логика будет находиться в одном сниппете, а оформление можно вынести в чанк:
Этот сниппет надо вызывать некешированным, так как о кешировании мы позаботились сами. Через два часа после сохранения данных в кеше они будут удалены и код с запросом будет выполнен снова. Результаты опять сохранятся на 2 часа.
Если нужно прямо сейчас обновить данные, а 2 часа ещё не прошли, достаточно просто очистить кеш стандартным способом — через пункт в верхнем меню админки.
Вараника 12.11.2017 22:35 #
Спасибо тебе :)