Так уж вышло, что пришлось столкнуться с разделением мультидоменного сайта на самостоятельные единицы. И, как следствие, возник вопрос как же теперь передать на страницы одного домена данные, опубликованные в ином? Это может быть публикация новостей, отзывов, цен, товаров и мн.др. Иным словом — совершенно любые данные.

Естественно копировать свежую информацию каждый раз, когда она появляется, менеджер сайта не захочет. Значит нужно все это дело автоматизировать, причем не давая лишнюю нагрузку на сервер.

Решение было найдено на основе 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, помните об этом.

Вторая часть — сайт реципиент

Теперь готовые данные нужно получить и несколько вариантов на выбор:

  1. Вывести напрямую на экран (регулярная нагрузка на 2 сайта)
  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, чтобы видеть, есть ли ошибки в пути к файлу.
В общем то на этом все. Данные можно передать любые и упаковывать по своему желанию :)

И огромное спасибо Олегу за поиск потерявшегося слеша в адресе из-за которого картинки упорно не желали отображаться.