Поэтому разрешите выложить решения проблем, которые мучали лично меня, возможно и кого-то ещё.
Какие были проблемы:
1) При вставке текста из другого сайта получалась каша, перенимались все стили, естественно. Плавали переходы строк, параграфы и т.д.
2) Было не понятно, когда добавляется новая строка (br), когда новый параграф (p).
Для начала, общие понятия.
Конфиг редактора лежит тут:
common/templates/frontend/libs/js/engine/settings.js
(Вопрос попутный к более опытным, почему почти такой же конфиг лежит тут:
common/templates/frontend/ls/js/settings.js и для чего он ?)
Получается, что все настройки редактора выстраиваются тут (если всё по умолчанию).
Тут же можно добавить новые кнопки, плагины и другие настройки.
Кнопки можно взять с оф.сайта https://www.tinymce.com/
—
Начнём с последнего вопроса, т.к. тупо легче и привычнее нажимать Enter и понимать, что у тебя вставляется новая строчка этого же параграфа.
Что делаем?
В настройках выставляем:
В блок « this.presets.tinymce['default'] = function(){ »
force_br_newlines: true,
forced_root_block: '', // Needed for 3.x
force_p_newlines: false,
Теперь порядок такой:
Enter, Enter+CTRL — новая строчка
Enter+Shift — Новый параграф
Вопрос первый, объёмнее.
Проблема:
При вставке текста из другого сайта получалась каша, перенимались все стили, естественно. Плавали переходы строк, параграфы и т.д. Убивалось куча времени на редактирование этого добра. Хотя должен быть простой копи-паст.
Решение:
В 2х словах: используем https://github.com/WEACOMRU/html-formatting для обработки входящего текста для TinyMCE на лету. Написано программерами для какого-то новостного портала. Решение не моё, но очень удобное.
Можно самостоятельно писать правила обработки входящего текста, который идёт с html тегами. Убирать все стили, оставлять что-то конкретное. Мануал написал неудачно, но штука работает.
Процесс:
1) Для начала зальём файл html-formatting.min.js (из репозитория) сюда
\common\templates\skin\experience\assets\js\experience\ (каждый заливает в свой шаблон)
2) Далее подключаем файл в шаблоне:
common/templates/skin/experience/settings/config/assets.php
Добавлем ниже всех js файлов:
$config['assets']['default']['js'][] = «___path.skin.dir___/assets/js/experience/html-formatting.min.js»;
3) Далее настройки параметров редактора.
Файл: common/templates/frontend/libs/js/engine/settings.js
В этот блок: this.presets.tinymce['default'] = function(){
Вставляем следующее:
а) В Параметр plugins добавляем «paste» (т.е. добавляем включение плагина paste в TinyMCE)
б) добавляем Параметр paste_auto_cleanup_on_paste : truе,
в) и обработчик paste_postprocess
Вот как по итогу выглядит новый код:
plugins: "paste advlist autolink autosave link lists media pagebreak autoresize table code altoimage snippets photoset username spoiler",
paste_auto_cleanup_on_paste : true,
paste_postprocess : function(pl, o) {
// Content DOM node containing the DOM structure of the clipboard
var headerRule = {
'br': {
process: function (node) {
var parent = node.parentNode,
space = document.createTextNode(' ');
parent.replaceChild(space, node);
}
}
};
var valid_elements = {
'h1': {
convert_to: 'h2',
valid_styles: '',
valid_classes: '',
no_empty: true,
valid_elements: headerRule
},
'h2,h3,h4': {
valid_styles: '',
valid_classes: '',
no_empty: true,
valid_elements: headerRule
},
'p': {
valid_styles: 'text-align',
valid_classes: '',
no_empty: true
},
a: {
valid_styles: '',
valid_classes: '',
no_empty: true,
process: function (node) {
var host = 'http://' + window.location.host + '/';
if (node.href.indexOf(host) !== 0) {
node.target = '_blank';
}
}
},
'br': {
valid_styles: '',
valid_classes: ''
},
'blockquote,b,strong,i,em,s,strike,sub,sup,kbd,ul,ol,li,dl,dt,dd,time,address,thead,tbody,tfoot': {
valid_styles: '',
valid_classes: '',
no_empty: true
},
'table,tr,th,td': {
valid_styles: 'text-align,vertical-align',
valid_classes: '',
no_empty: true
},
'embed,iframe': {
valid_classes: ''
}
};
htmlFormatting(o.node, valid_elements);
},
Опустим описание правил. Это написано на гит-репозитории плагина.
Вот как по итогу выглядит у меня блок параметров
this.presets.tinymce['default'] = function(){
return {
selector: '.js-editor-wysiwyg',
theme: 'modern',
skin: 'custom',
relative_urls: false,
menubar: false,
toolbar: "undo redo styleselect | bold italic strikethrough underline blockquote snippets | alignleft aligncenter alignright | bullist numlist table | link unlink | altoimage media | code pagebreak removeformat",
toolbar_items_size: 'small',
image_advtab: false,
style_formats: [
{title: 'H1', block: 'h1'},
{title: 'H2', block: 'h2'},
{title: 'H3', block: 'h3'},
{title: ls.lang.get('panel_title_h4'), block: 'h4'},
{title: ls.lang.get('panel_title_h5'), block: 'h5'},
{title: ls.lang.get('panel_title_h6'), block: 'h6'}
],
object_resizing: true,
forced_root_block: '', // Needed for 3.x
force_br_newlines: true,
force_p_newlines: false,
custom_elements : "alto:photoset",
self_closing_elements: "alto:photoset",
//convert_urls: false,
extended_valid_elements: "embed[src|type|allowscriptaccess|allowfullscreen|width|height],alto:photoset[from|to|style|position|topic],alto:user[login|style],alto:spoiler[style|title]",
pagebreak_separator: "<cut>",
media_strict: false,
language: TINYMCE_LANG ? TINYMCE_LANG : 'ru',
inline_styles: false,
plugins: "paste advlist autolink autosave link lists media pagebreak autoresize table code altoimage snippets photoset username spoiler",
paste_auto_cleanup_on_paste : true,
paste_postprocess : function(pl, o) {
// Content DOM node containing the DOM structure of the clipboard
var headerRule = {
'br': {
process: function (node) {
var parent = node.parentNode,
space = document.createTextNode(' ');
parent.replaceChild(space, node);
}
}
};
var valid_elements = {
'h1': {
convert_to: 'h2',
valid_styles: '',
valid_classes: '',
no_empty: true,
valid_elements: headerRule
},
'h2,h3,h4': {
valid_styles: '',
valid_classes: '',
no_empty: true,
valid_elements: headerRule
},
'p': {
valid_styles: 'text-align',
valid_classes: '',
no_empty: true
},
a: {
valid_styles: '',
valid_classes: '',
no_empty: true,
process: function (node) {
var host = 'http://' + window.location.host + '/';
if (node.href.indexOf(host) !== 0) {
node.target = '_blank';
}
}
},
'br': {
valid_styles: '',
valid_classes: ''
},
'blockquote,b,strong,i,em,s,strike,sub,sup,kbd,ul,ol,li,dl,dt,dd,time,address,thead,tbody,tfoot': {
valid_styles: '',
valid_classes: '',
no_empty: true
},
'table,tr,th,td': {
valid_styles: 'text-align,vertical-align',
valid_classes: '',
no_empty: true
},
'embed,iframe': {
valid_classes: ''
}
};
htmlFormatting(o.node, valid_elements);
},
setup: function (editor) {
editor.on('change', function() {
tinyMCE.triggerSave();
});
},
formats: {
underline: {inline: 'u', exact: true},
strikethrough: {inline: 's', exact: true}
},
}
};
Далее чистим кэш (http:// site.ru /admin/tools-reset/) и проверяем. Это сделано для редактора Топиков. То же самое можно сделать и для редактора комментов.
Тут у разных людей мнения расходятся. Кто-то, как ты, считает, что должен быть перевод строки. Кто-то категорично утверждает, что однозначно должен быть новый параграф. Было и такое мнение: одиночный перевод строки — это <br>, а две пустых строки подряд — параграф.
Идеально было бы, конечно, это все во внешние настройки вынести.
Идеально, конечно, было бы так: при вставке текста делать аякс-запрос и прогонять через штатный типограф движка. Но и этот вариант вполне рабочий, думаю, многим сгодится.
Спасибо, что поделился!