В двух словах. На одном сайте приходится редакторам работать с текстом, который просто напичкан внутренними ссылками. Работа кропотливая и нудная. И тут появилась идея - автоматизировать вставку ссылок, которые являются ссылками на элементы инфоблоков.
Кому интересно - далее под катом.
[spoiler]
В чем суть. Редактор пишет текст. Например,
И вот тут надо бы Вову и Медведа выделить ссылками на их персональные странички. Ну ладно если это две ссылки на странице. А если их 10? А если страниц 50?
Решение пришло в голову довольно быстро (визуальное), а вот над кодом пришлось попотеть. Во многом ОГРОМНОЕ спасибо разработчикам визуального редактора - там черт ногу сломит. Помог скрипт Михаила Крячека с табами - демки кода содрал оттуда (имею в виду по его коду хоть понял как это все заводится
).

Как работает. Выделяем слово, которое хотим обернуть в ссылку на элемент каталога людей. Жмакаем кнопку, там выбираем в селекте. И вуа-ля, ссылка сформировалась. Просто и удобно.
Но с кодом пришлось попотеть.
Два минуса, за которые меня надо пинать ногами:
Поясню.
Насчет первого. Чтобы дернуть элементы, мне надо бы обратиться к php-скрипту. Все бы ничего, дергаем стандартно AJAX'ом Битрикса урл и получаем селект. Но AJAX там не заработал. Пришлось тупо писать код.
Насчет второго. Посмотрел бегло как работает обработчик кода в Битриксе, вставляя ссылку - ужас. Воспользовался "стандартной" функцией __getSelection. Родной перехват я так и не осилил. Тут же, никак не создаю элемент. Просто:
insertHTML('<a href="/...
Если делать по-родному, то там надо создавать ссылки, присваивать им временные href'ы и много чего еще. Вобщем код занял бы несколько сотен строк. Может и ошибаюсь.
Остальное все стандартно. Если кому-то еще пригодится - буду рад.
Вот код. Сорри что сюда, просто чтобы было перед глазами. Если разработчики Битрикса это читают, то... ребят, это не дело. Редактор нужно описать прям по кнопочкам, пока он для разработки просто мертв.
В init.php
Этот самый pers.php кидаем в /bitrix/admin/htmleditor2/
pers.php
Иконку кидаем по пути /bitrix/images/pers_insert.gif

Вот собственно что получилось:

Кому интересно - далее под катом.
[spoiler]
В чем суть. Редактор пишет текст. Например,
Премьер-министр РФ, Владимир Путин, провел встречу в Кремле с президентом Дмитрием Медведевым. |
Решение пришло в голову довольно быстро (визуальное), а вот над кодом пришлось попотеть. Во многом ОГРОМНОЕ спасибо разработчикам визуального редактора - там черт ногу сломит. Помог скрипт Михаила Крячека с табами - демки кода содрал оттуда (имею в виду по его коду хоть понял как это все заводится


Как работает. Выделяем слово, которое хотим обернуть в ссылку на элемент каталога людей. Жмакаем кнопку, там выбираем в селекте. И вуа-ля, ссылка сформировалась. Просто и удобно.
Но с кодом пришлось попотеть.
Два минуса, за которые меня надо пинать ногами:
- JS-крипт как PHP обрабатывается и там же и PHP вставляется.
- Тупой перехват селектированной области и вставка ее в ссылку. Никакой умной обработки.
Поясню.
Насчет первого. Чтобы дернуть элементы, мне надо бы обратиться к php-скрипту. Все бы ничего, дергаем стандартно AJAX'ом Битрикса урл и получаем селект. Но AJAX там не заработал. Пришлось тупо писать код.
Насчет второго. Посмотрел бегло как работает обработчик кода в Битриксе, вставляя ссылку - ужас. Воспользовался "стандартной" функцией __getSelection. Родной перехват я так и не осилил. Тут же, никак не создаю элемент. Просто:
insertHTML('<a href="/...
Если делать по-родному, то там надо создавать ссылки, присваивать им временные href'ы и много чего еще. Вобщем код занял бы несколько сотен строк. Может и ошибаюсь.
Остальное все стандартно. Если кому-то еще пригодится - буду рад.
Вот код. Сорри что сюда, просто чтобы было перед глазами. Если разработчики Битрикса это читают, то... ребят, это не дело. Редактор нужно описать прям по кнопочкам, пока он для разработки просто мертв.
В init.php
AddEventHandler("fileman", "OnBeforeHTMLEditorScriptsGet", "HTMLEditorPersInsert"); function HTMLEditorPersInsert($editorName, $arEditorParams) { return Array( "JS" => Array('pers.php') ); } |
Этот самый pers.php кидаем в /bitrix/admin/htmleditor2/
pers.php
function __getSelection (w) { var s = w.document.getSelection(); if (s) return s; else for (var f =0; f < w.frames.length; f++) { s = __getSelection(w.frames[f]); if (s) return s; } } window.bBitrixTabs = false; arButtons['tab'] = ['BXButton', { id : 'tab', codeEditorMode : false, src : '/bitrix/images/pers_insert.gif', name : 'Вставить ссылку на персонажа', handler : function () { this.bNotFocus = true; this.pMainObj.OpenEditorDialog("pers_insert", false, 400, {window: window, document: document}); }, OnSelectionChange: function () { var oRange = BXGetSelectionRange(this.pMainObj.pEditorDocument, this.pMainObj.pEditorWindow); var currentElement = this.pMainObj.GetSelectionObject(); } } ]; if (!window.lightMode) { oBXEditorUtils.appendButton('tab', arButtons['tab'], 'standart'); } else { for(var bxi = 0, bxl = arGlobalToolbar.length; bxi < bxl; bxi++) { if (arGlobalToolbar[bxi +1] == 'line_end') break; } arGlobalToolbar = arGlobalToolbar.slice(0, bxi).concat([arButtons['tab']], arGlobalToolbar.slice(bxi + 1)); } arEditorFastDialogs['pers_insert'] = function(pObj) { <? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); if (CModule::IncludeModule("iblock")) { $str = ''; $str .= '<select name="pers_select" id="pers_select">'; $str .= '<option value=""></option>'; $rsPers = CIBlockElement::GetList(array("SORT" => "ASC", "NAME" => "ASC"), array("IBLOCK_ID" => 2), false, false, array("NAME", "CODE")); while ($arPers = $rsPers->GetNext()) { $str .= '<option value="'.$arPers["CODE"].'">'.$arPers["NAME"].'</option>'; } $str .= '</select>'; } ?> var persSelect = '<?= $str?>'; var str = '<table height="100%" width="100%" border="0" style="margin-top:10px">' + '<tr>' + '<td align="right">' + 'Выберите персонажа' + ':' + '</td>' + '<td>' + persSelect + '</td>' + '</tr>' + '<tr valign="top">' + '<td align="right" valign="middle" style="height:40px"><input type="button" id="bx_tabsection_save" value="' + BX_MESS.TBSave + '"></td>' + '<td align="left" valign="middle" style="height:40px"><input type="button" id="bx_tabsection_close" value="' + BX_MESS.TBCancel + '"></td>' + '</tr>' + '</table>'; var OnClose = function(){pObj.Close();}; var OnSave = function(t) { var selectedBlock = __getSelection(window); var linkCode = document.getElementById('pers_select').options[document.getElementById('pers_select').selectedIndex].value; var linkText = document.getElementById('pers_select').options[document.getElementById('pers_select').selectedIndex].text; if (linkCode.length <= 0) return alert('Выберите персонажа из списка'); BXSelectRange(oPrevRange, pObj.pMainObj.pEditorDocument, pObj.pMainObj.pEditorWindow); pObj.pMainObj.insertHTML('<a href="/pers/'+linkCode+'/" title="'+linkText+'">'+(selectedBlock!=null ? selectedBlock : linkText)+'</a>'); OnClose(); }; return { title: "Вставка ссылки на персонажа", innerHTML : str, OnLoad: function() { window.oPrevRange = BXGetSelectionRange(pObj.pMainObj.pEditorDocument, pObj.pMainObj.pEditorWindow); var bs = document.getElementById("bx_tabsection_save"); bs.onclick = OnSave; document.getElementById("bx_tabsection_close").onclick = OnClose; } }; } |
Иконку кидаем по пути /bitrix/images/pers_insert.gif

Вот собственно что получилось:
