Задача. Оптимизатор должен иметь возможность ходить по сайту и вставлять в текст ссылки. Сделать это нужно как можно проще для оптимизатора, чтобы его работа проходила как можно быстрее.
Итак, первое, что мы делаем — создаем чанк editLinksNet, в который пропишем функционал для фронтенда (здесь для работы с выделенным текстом я использую плагин отсюда, ну и у вас должен быть подключен JQuery):
Вы можете скачать готовый пакет для перелинковки сайта: modx.com/extras/package/editlinksnet (инструкция)
<div id="popUpBox"
style="position:absolute; display:none;
background:#fff; cursor: pointer; border:3px solid #ccc;
color: #333; font: bold 14px arial; padding:5px 15px;">
<form action="[[~[[*id]]]]?act=editLink" method="post" class="form">
<input type="text" name="url" id="url"
value="[[++site_url]][[~[[*parent]]]]">
<textarea style="display: none;" name="outer" id="outer"></textarea>
<input type="hidden" name="id" value="[[*id]]">
<input type="submit" name="submit" value="OK"
style="width: 40px; height: 28px;" class="btn primary">
</form>
</div>
<div style="position:fixed;z-index:1000;left:5px;top:70px;">
<a href="[[~[[*id]]]]?act=cancel"
style="display: block; color: #fff;
text-decoration: none; padding: 5px;
background: #779937; border-radius: 3px;
border: 1px solid #5C7F17; margin: 0 auto 5px;">
Отмена последней ссылки</a>
</div>
<script type="text/javascript" src="/js/selection.js"></script>
<script type="text/javascript">
jQuery(function($) {
var $txt = "";
$("#content").bind("mouseup", function(e){
var txt = $.selection().get().text
if (txt!=""){
$('abbr').replaceWith($('abbr').html());
$.selection().set('<abbr style="color: #00c;
text-decoration: underline;">'
+ txt + '</abbr>');
$("#popUpBox").css({"display":"block", "left":e.pageX-60+"px",
"top":e.pageY+15+"px"});
$("#url").focus();
$("#url").select();
$("#outer").html($('#content').html());
} else {
$("#popUpBox").css({"display":"none"});
$('abbr').replaceWith($('abbr').html());
}
});
});
</script>
Этот чанк выводит на страницу кнопку отмены последней ссылки (на случай, если ссылка была поставлена некорректно), и форму, в которую нужно вставлять адрес ссылки.Если подробнее, то выглядит все так:
пользователь выделает какой-то текст, который он хочет сделать ссылкой. Скрипт выделяет этот текст цветом, помещает новый текст в textarea для передачи сниппету и показывает поле для ввода адреса ссылки. После отправки формы сниппет получает все данные и производит замену нужного текста на ссылку.
Сам сниппет editLinksNet выглядит так:
<?php
if (!$_GET['act']) return false;
// Данные из формы получаем с помощью FormIt.
// Так что убедитесь, что он у вас есть
if (!$id) $id = $hook->getValue('id');
if (!$url) $url = $hook->getValue('url');
if (!$outer) $outer = $hook->getValue('outer');
if (!$id || !$url || !$outer) return false;
// Заменяем нужный текст на ссылку
$newContent = str_replace('<abbr style="color: #00c;
text-decoration: underline;">',
'<a href="'.$url.'">',$outer);
$newContent = str_replace('</abbr>','</a>',$newContent);
// Если есть сохраненное предыдущее состояние, получаем его
$backup = $_SESSION[$id.'_backup'];
// Если пользователь попросил отменить предыдущую ссылку, $backup
if ($_GET['act'] == 'cancel' && $_SESSION[$id.'_backup']) {
$content = $backup;
} else {
$content = $newContent;
}
// Получаем ресурс по id ресурса
$resource = $modx->getObject('modResource',$id);
// Запоминаем текущее значение content для возможности отмены
if ($_GET['act'] != 'cancel') {
$_SESSION[$id.'_backup'] = $resource->get('content');
}
// Устанавливаем нужные значения
$resource->set('content',$content);
// Сохраняем ресурс
if ($resource->save()) {
// Очищаем кеш, чтобы изменения были видны сразу
$modx->cacheManager->refresh();
if ($_GET['act'] == 'cancel') {
$modx->sendRedirect($modx->makeUrl($id));
} else {return true;}
}
return false;
Теперь это все нужно вывести на странице. Для этого используем плагин editLinksNet (событие onWebPagePrerender):<?php
if($modx->resource->get('content_type') != 1) return;
if ($modx->event->name == 'OnWebPagePrerender') {
if (!$modx->user->isAuthenticated('mgr')) {return;}
// Проверяем, включена ли перелинковка
if ($_COOKIE['editLinksNet']) {
$modx->runSnippet('FormIt', array(
'hooks' => 'editLinksNet,redirect',
'redirectTo' => $modx->resource->get('id'),
'submitVar'=>'url',
'validate'=>'outer:allowTags'));
// Запускаем наш сниппет, если отправлен запрос на отмену
if ($_GET['act'] == 'cancel') $modx->runSnippet('editLinksNet',
array('id' => $modx->resource->get('id'),
'url' => 'cancel',
'outer' => $_SESSION[$modx->resource->get('id').'_backup']));
// А здесь выводим на страницу наш чанк
$html = "\n".$modx->getChunk('editLinksNet');
} else {
// Если перелинковка выключена, просто выводим ссылку на включение
$html = "\n".'<div style="position:fixed;
z-index:1000;
left:5px;top:70px;">
<a href="'.$modx->makeUrl($modx->resource->get('id')).'?act=on"
style="display: block; color: #fff; text-decoration: none;
padding: 5px; background: #779937; border-radius: 3px;
border: 1px solid #5C7F17; margin: 0 auto 5px;">
Включить перелинковку</a>
</div>';
// И, соответственно, включаем перелинковку на 5 часов
if ($_GET['act'] == 'on') {
SetCookie("editLinksNet","editLinksNetOn",time()+18000);
$modx->sendRedirect($modx->makeUrl($modx->resource->get('id')));
}
}
$modx->resource->_output .= $html;
}
Ну и на последок, ссылка на готовый для установки пакет. Закачайте его в папку core/packages и вы сможете установить его прямо из админки MODX.
UPD. Забыл сказать, что у вас [[*content]] должен находиться в диве с id=«content»:
<div id="content"> [[*content]] </div>
G+
UPD-2. Перенес топик в соответствующий блог.
Оригинал статьи community.modx-cms.ru/blog/tips_and_tricks/8394.html
Объектная
url: /?act=cancel
ошибка: Fatal error: Call to a member function getValue() on a non-object in /home/user/docs/core/cache/includes/elements/modsnippet/26.include.cache.php on line 11
Да и собственно сами ссылки не проставляются