Задача. Оптимизатор должен иметь возможность ходить по сайту и вставлять в текст ссылки. Сделать это нужно как можно проще для оптимизатора, чтобы его работа проходила как можно быстрее.
Итак, первое, что мы делаем — создаем чанк 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
Да и собственно сами ссылки не проставляются