Делалось Лешей Либером (на основе url) и мной на основе id-шек на одном проекте. Можно сказать, что я просто немного пошаманила над кодом Леши, чтобы не было дубликатов и ошибок.
Теперь к делу. Вот итоговая штука, которая у нас вышла:
Что делает штука? У нас есть тип ресурса Товар. У этого товара есть три поля с наименованием его модели, серии и маркировки. Вообще это может быть что угодно: поле с ценой, поле с артикулом, весом и пр.
Предположим менеджеру лениво было создавать товары и он, при заполнении не писал ничего в сео полях или longtitle и description, но исправно записывал видимую информацию о товаре. В итоге у него вышло так:
Красный диван из кожи
Синий диван без ножек
Розовый диван
и т.д.
Приходит сеошник и конечно возмущается. Ему нужно перелопатить 500 товаров и правильно их назвать. Благодаря данному скрипту он сделает это так: напишет в табличку быстрого редактирования номера страниц товаров, которые увидит на сайте в непотребном виде, и напишет так:
Купить диван {Наименование} {Маркировка} в Москве за {Цена} рублей
И все пять сотен диванов станут называться по другому. Удобно? Ну явно удобнее, чем открывать каждый ресурс отдельно или править БД :)
Меньше слов, больше дела. Создаем.
1. В настройках — панели создаем новый виджет и пишем в него произвольное имя. Тип — сниппет, размер — на всю ширину, пространство имен — core, словарь — core:dashboards. В содержимое виджета пишем SeoWidget_Id (это название будущего сниппета).
2. Назначаем виджет Панели.
3. Ну и создаем сам сниппет.
Код сниппета SeoWidget_Id (версия моя)
$err = '';
// ловим отправленные из формы списки поля, в котором пользователь вводит через запятую айдишки страниц
if (isset($_POST['urls'])) {
$urls = trim($_POST['urls']);
$urls = explode(",", $urls);
foreach($urls as $url) {
$id = trim($url);
$err[] = $id;
// Находим документы по этим айдишкам
if ($res = $modx->getObject('modResource', $id)) {
// и берем из них номера присвоенных TV.
$good_name = $res->getTVValue(19);
$good_mark = $res->getTVValue(20);
$series_list = $res->getTVValue(27);
// Немного магии
$healthy = array("{Наименование}", "{Маркировка}", "{Серия}");
$yummy = array($good_name, $good_mark, $series_list);
$pagetitle = str_replace($healthy, $yummy, $modx->db->escape($_POST['pagetitle']));
$longtitle = str_replace($healthy, $yummy, $modx->db->escape($_POST['longtitle']));
$description = str_replace($healthy, $yummy, $modx->db->escape($_POST['description']));
$seo_h1 = str_replace($healthy, $yummy, $modx->db->escape($_POST['seo_h1']));
$seo_title = str_replace($healthy, $yummy, $modx->db->escape($_POST['seo_title']));
$seo_description = str_replace($healthy, $yummy, $modx->db->escape($_POST['seo_description']));
// сохраняем что вышло
$res->set('pagetitle', $pagetitle);
$res->set('longtitle', $longtitle);
$res->set('description', $description);
// помним, что до поля сохраняются через setTVValue, а родные через set
$res->setTVValue('seo-h1',$seo_h1);
$res->setTVValue('seo-title', $seo_title);
$res->setTVValue('seo-desc', $seo_description);
$res->save();
}
}
}
// Часть Леши - визуальная форма наша
if ($err) {
$eraray = implode(",", $err);
$eraray = 'Изменены следующие ID:
'.$eraray;
}
?>
<p>Доступные плейсхолдеры: {Наименование} {Маркировка} {Серия}</p>
<? echo $eraray;?>
<form method="post" action="">
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Заголовок (PAGETITLE)</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="pagetitle" value="<? echo $_POST['pagetitle'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Расширенный заголовок (LONGTITLE)</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="longtitle" value="<? echo $_POST['longtitle'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Описание (Description)</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="description" value="<? echo $_POST['description'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">H1</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="seo_h1" value="<? echo $_POST['seo_h1'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Title</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="seo_title" value="<? echo $_POST['seo_title'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Description</label>
<div class="x-form-element" style="padding-left:0;">
<input type="text" size="20" autocomplete="on" class="x-form-text x-form-field" title="" style="width:calc(100% - 10px);" name="seo_description" value="<? echo $_POST['seo_description'];?>">
</div>
<div class="x-form-clear-left"></div>
</div>
<div class="x-form-item x-tab-item" tabindex="-1">
<label for="seopro-keywords" style="width:auto;" class="x-form-item-label">Номера страниц (строго через запятую)</label>
<div class="x-form-element" style="padding-left:0;">
<textarea autocomplete="on" class="x-form-textarea x-form-field" title="" style="width:calc(100% - 10px);" rows="10" name="urls"><? echo $_POST['urls'];?></textarea>
</div>
<div class="x-form-clear-left"></div>
</div>
<div style="text-align:center; margin-top:15px;">
<button type="submit" class="primary-button x-btn x-btn-text">Отправить</button>
</div>
</form>
На всякий случай уточню, что есть номера TV полей, а то мало ли, может кто еще чего напутает, я за 5 лет перестала удивляться многому :)
А, самое главное. Помните, что шаблоны эти {Цена} и {Маркировка} должны существовать в реальном мире. У Вас 100% не получится изменить у категории заголовок на
Купить диваный в Москве от {Цена} рублей
Если поле цены не назначено шаблоны категории. Просто напоминаю :)
Ну и все почти.
Правда менеджерам лениво искать айдишки в админке, по-этому еще и так делаем:
в шаблоне товара (ну или в карточке товара в категории) пишем его id только для менеджера. Удобно на fenom конечно, но данный сайт пришел сторонний и я не стала его переделывать, а использовала что есть.
Ставим компонент Personalize и пишем код в карточке после названия товара:
[ [!Personalize?
&yesChunk=`@CODE:<br /><small>№ </small>`
&context=`mgr`
] ]
В итоге на страницах только для менеджера сразу пишется какой номер у ресурса и не нужно ползать по админке. Если у владельца сайта принципиальных просьб нет, то эту айдишку можно замаскировать под что угодно: артикул, код модели и т.д. и не заморачиваться с ее сокрытием.
На этом моя часть закончилась. Идея Леши была вставлять не айдишки, а url страниц, которые массово требуется поменять. И мы все попросим его самого в комментарии добавить этот код, чтобы мы его заплюсовали ;)
Алексей Либер 30.09.2019 09:21 #
Илья Уткин 01.11.2019 16:26 #
Вараника 03.04.2020 12:32 #
Пришлось убирать $modx->db->escape
Рабочий код с другого проекта