Intereting Posts
Получение тысяч спама регистрации Как настроить основные страницы администратора в теме? Бэкэнд-поиск; включить CPT meta? Permalink ничего не возвращает на странице результатов поиска Изменение заголовка на странице после листинга в области администратора Отправка электронной почты с помощью функции на странице или правильное действие на другой странице Перенаправить на сообщение только с идентификатором сообщения в URL-адресе и в post_type / post ID обновления к содержимому страницы wp возвращают меня на главную страницу и не будут сохранять Как вставить короткий код в тег заголовка другого? get_next_post_link () и get_previous_post_link () возвращают неправильные записи Как отключить фильтрацию стиля в сообщении? Более эффективный запрос для отображения сообщений в одной и той же подкатегории? При создании страницы изменяются многоузловые ссылки Как изменить имя отправителя электронной почты с wordpress на (myblogname) в электронной почте «потерянный пароль»? Выдержка теперь отображается на странице сообщения

Добавление пользовательских текстовых шаблонов в визуальный редактор WP 4.5

4.5 отсутствует и с ним новые текстовые шаблоны . Я хотел бы узнать, как добавить свои собственные шаблоны.

wp-includes/js/tinymce/plugins/wptextpattern/plugin.js на wp-includes/js/tinymce/plugins/wptextpattern/plugin.js он выглядит довольно прямолинейно.

 var spacePatterns = [ { regExp: /^[*-]\s/, cmd: 'InsertUnorderedList' }, { regExp: /^1[.)]\s/, cmd: 'InsertOrderedList' } ]; var enterPatterns = [ { start: '##', format: 'h2' }, { start: '###', format: 'h3' }, { start: '####', format: 'h4' }, { start: '#####', format: 'h5' }, { start: '######', format: 'h6' }, { start: '>', format: 'blockquote' }, { regExp: /^(-){3,}$/, element: 'hr' } ]; var inlinePatterns = [ { start: '`', end: '`', format: 'code' } ]; 

33300.6.patch выглядит идеально:

 add_filter( 'tiny_mce_before_init', 'textpatterns_test' ); function textpatterns_test( $init ) { $init['wptextpattern_inline_patterns'] = '{ strong: { start: "*", end: "*", format: "bold" }, strong2: { start: "**", end: "**", format: "bold" }, em: { start: "_", end: "_", format: "italic" } }'; return $init; } 

К сожалению, из того, что я могу сказать, эти шаблоны не подключаются, и этот патч никогда не попадал в выпуск 4.5.

Итак, на данный момент, возможно, лучшим решением является дублирование этого плагина, удаление существующих шаблонов (чтобы не дублировать шаблоны) и добавление пользовательских шаблонов? Если это так, то какова наилучшая практика добавления плагинов tinymce в правильном порядке, чтобы добавить эту новую функциональность?

Или есть другое решение, которое менее очевидно?

Solutions Collecting From Web of "Добавление пользовательских текстовых шаблонов в визуальный редактор WP 4.5"

Вот способ протестировать основной патч # 33300.6 от Andew Ozz , через тестовый плагин в WP 4.5.2, чтобы попробовать фильтр текстурного шаблона.

демонстрация

Вот пример зачеркивания, используя ~

 $init['wpsetextpattern_inline_patterns'] = '{ strong: { start: "*", end: "*", format: "bold" }, strong2: { start: "**", end: "**", format: "bold" }, em: { start: "_", end: "_", format: "italic" }, strikethrough: { start: "~", end: "~", format: "strikethrough" } }'; 

в тестовом плагине. Он работает следующим образом:

просачивание

Тестовый плагин

Структура тестового плагина:

 /plugins/custom-text-patterns/ custom-text-patterns.php js/ plugin.js 

где находятся файлы:

заказ текста patterns.php:

 <?php /** * Plugin Name: Custom Text Patterns for WordPress 4.5 * Description: Trying out the core patch #33300.6 by azaozz, to test textpattern filtering. * Version: 1.0.0 */ /** * Remove the current wptextpattern plugin */ add_filter( 'tiny_mce_plugins', function( $plugins ) { $key = array_search ( 'wptextpattern', $plugins ); if( false !== $key ) unset( $plugins[$key] ); return $plugins; } ); /** * Register patch #33300.6 as an external TinyMCE plugin */ add_filter( 'mce_external_plugins', function( $plugins ) { $plugins['wpsetextpattern'] = plugin_dir_url( __FILE__ ) . 'js/plugin.js'; return $plugins; } ); /** * Custom text patterns */ add_filter( 'tiny_mce_before_init', function( $init ) { $init['wpsetextpattern_inline_patterns'] = '{ strong: { start: "*", end: "*", format: "bold" }, strong2: { start: "**", end: "**", format: "bold" }, em: { start: "_", end: "_", format: "italic" }, strikethrough: { start: "~", end: "~", format: "strikethrough" } }'; $init['wpsetextpattern_enter_patterns'] = '{ h2: { start: "##", format: "h2" }, h3: { start: "###", format: "h3" }, h4: { start: "####", format: "h4" }, h5: { start: "#####", format: "h5" }, h6: { start: "######", format: "h6" }, blockquote: { start: ">", format: "blockquote" }, hr: { regExp: /^(-){3,}$/, element: "hr" } }'; $init['wpsetextpattern_space_patterns'] = '{ ul: { regExp: /^[*-]\s/, cmd: "InsertUnorderedList" }, ol: { regExp: /^1[.)]\s/, cmd: "InsertOrderedList" } }'; return $init; } ); 

plugin.js: Слияние с патчем # 33300.6 , заменив wptextpattern на wpsetextpattern :

 /** * Text pattern plugin for TinyMCE * * @since 4.3.0 * * This plugin can automatically format text patterns as you type. It includes two patterns: * - Unordered list (`* ` and `- `). * - Ordered list (`1. ` and `1) `). * * If the transformation in unwanted, the user can undo the change by pressing backspace, * using the undo shortcut, or the undo button in the toolbar. */ ( function( tinymce, setTimeout ) { if ( tinymce.Env.ie && tinymce.Env.ie < 9 ) { return; } tinymce.PluginManager.add( 'wpsetextpattern', function( editor ) { var VK = tinymce.util.VK, settings = editor.settings, extend = tinymce.extend, each = tinymce.each, chars = [], canUndo; /** * Setting for the patterns can be added or replaced by using the * 'tiny_mce_before_init' filter (from PHP). * * The editor options are: wptextpattern_space_patterns, * wptextpattern_enter_patterns, and wptextpattern_inline_patterns. * The format is same as below: an object of objects containing the pattrern settings. * * Note: the keys in the settings objects are not signigicant. They can be used * to override the default settings if needed. * * Example: * add_filter( 'tiny_mce_before_init', 'textpatterns_test' ); * function textpatterns_test( $init ) { * $init['wptextpattern_inline_patterns'] = '{ * strong: { start: "*", end: "*", format: "bold" }, * strong2: { start: "**", end: "**", format: "bold" }, * em: { start: "_", end: "_", format: "italic" } * }'; * * return $init; * } */ var spacePatterns = extend( { ul: { regExp: /^[*-]\s/, cmd: 'InsertUnorderedList' }, ol: { regExp: /^1[.)]\s/, cmd: 'InsertOrderedList' } }, settings.wpsetextpattern_space_patterns || {} ); var enterPatterns = extend( { h2: { start: '##', format: 'h2' }, h3: { start: '###', format: 'h3' }, h4: { start: '####', format: 'h4' }, h5: { start: '#####', format: 'h5' }, h6: { start: '######', format: 'h6' }, blockquote: { start: '>', format: 'blockquote' }, hr: { regExp: /^(-){3,}$/, element: 'hr' } }, settings.wpsetextpattern_enter_patterns || {} ); var inlinePatterns = extend( { code: { start: '`', end: '`', format: 'code' } }, settings.wpsetextpattern_inline_patterns || {} ); // Convert to array and sort descending by start length. function toSortedArray( patterns ) { patterns = tinymce.map( patterns, function( pattern ) { return pattern; } ); patterns.sort( function( a, b ) { if ( a.start && b.start ) { if ( a.start.length > b.start.length ) { return -1; } if ( a.start.length < b.start.length ) { return 1; } } return 0; }); return patterns; } spacePatterns = toSortedArray( spacePatterns ); enterPatterns = toSortedArray( enterPatterns ); inlinePatterns = toSortedArray( inlinePatterns ); each( inlinePatterns, function( pattern ) { each( ( pattern.start + pattern.end ).split( '' ), function( c ) { if ( tinymce.inArray( chars, c ) === -1 ) { chars.push( c ); } } ); } ); editor.on( 'selectionchange', function() { canUndo = null; } ); editor.on( 'keydown', function( event ) { if ( ( canUndo && event.keyCode === 27 /* ESCAPE */ ) || ( canUndo === 'space' && event.keyCode === VK.BACKSPACE ) ) { editor.undoManager.undo(); event.preventDefault(); event.stopImmediatePropagation(); } if ( event.keyCode === VK.ENTER && ! VK.modifierPressed( event ) ) { enter(); } }, true ); editor.on( 'keyup', function( event ) { if ( event.keyCode === VK.SPACEBAR && ! event.ctrlKey && ! event.metaKey && ! event.altKey ) { space(); } else if ( event.keyCode > 47 && ! ( event.keyCode >= 91 && event.keyCode <= 93 ) ) { inline(); } } ); function inline() { var rng = editor.selection.getRng(); var node = rng.startContainer; var offset = rng.startOffset; var startOffset; var endOffset; var pattern; var format; var zero; if ( ! node || node.nodeType !== 3 || ! node.data.length || ! offset ) { return; } if ( tinymce.inArray( chars, node.data.charAt( offset - 1 ) ) === -1 ) { return; } function findStart( node ) { var offset; each( inlinePatterns, function( currentPattern ) { pattern = currentPattern; offset = node.data.indexOf( pattern.end ); if ( offset !== -1 ) { return false; } } ); return offset; } startOffset = findStart( node ); endOffset = node.data.lastIndexOf( pattern.end ); if ( startOffset === endOffset || endOffset === -1 ) { return; } if ( endOffset - startOffset <= pattern.start.length ) { return; } if ( node.data.slice( startOffset + pattern.start.length, endOffset ).indexOf( pattern.start.slice( 0, 1 ) ) !== -1 ) { return; } format = editor.formatter.get( pattern.format ); if ( format && format[0].inline ) { editor.undoManager.add(); editor.undoManager.transact( function() { node.insertData( offset, '\u200b' ); node = node.splitText( startOffset ); zero = node.splitText( offset - startOffset ); node.deleteData( 0, pattern.start.length ); node.deleteData( node.data.length - pattern.end.length, pattern.end.length ); editor.formatter.apply( pattern.format, {}, node ); editor.selection.setCursorLocation( zero, 1 ); } ); // We need to wait for native events to be triggered. setTimeout( function() { canUndo = 'space'; editor.once( 'selectionchange', function() { var offset; if ( zero ) { offset = zero.data.indexOf( '\u200b' ); if ( offset !== -1 ) { zero.deleteData( offset, offset + 1 ); } } } ); } ); } } function firstTextNode( node ) { var parent = editor.dom.getParent( node, 'p' ), child; if ( ! parent ) { return; } while ( child = parent.firstChild ) { if ( child.nodeType !== 3 ) { parent = child; } else { break; } } if ( ! child ) { return; } if ( ! child.data ) { if ( child.nextSibling && child.nextSibling.nodeType === 3 ) { child = child.nextSibling; } else { child = null; } } return child; } function space() { var rng = editor.selection.getRng(), node = rng.startContainer, parent, text; if ( ! node || firstTextNode( node ) !== node ) { return; } parent = node.parentNode; text = node.data; each( spacePatterns, function( pattern ) { var match = text.match( pattern.regExp ); if ( ! match || rng.startOffset !== match[0].length ) { return; } editor.undoManager.add(); editor.undoManager.transact( function() { node.deleteData( 0, match[0].length ); if ( ! parent.innerHTML ) { parent.appendChild( document.createElement( 'br' ) ); } editor.selection.setCursorLocation( parent ); editor.execCommand( pattern.cmd ); } ); // We need to wait for native events to be triggered. setTimeout( function() { canUndo = 'space'; } ); return false; } ); } function enter() { var rng = editor.selection.getRng(), start = rng.startContainer, node = firstTextNode( start ), text, pattern, parent; if ( ! node ) { return; } text = node.data; each( enterPatterns, function( currentPattern ) { if ( currentPattern.start ) { if ( text.indexOf( currentPattern.start ) === 0 ) { pattern = currentPattern; return false; } } else if ( currentPattern.regExp ) { if ( currentPattern.regExp.test( text ) ) { pattern = currentPattern; return false; } } } ); if ( ! pattern ) { return; } if ( node === start && tinymce.trim( text ) === pattern.start ) { return; } editor.once( 'keyup', function() { editor.undoManager.add(); editor.undoManager.transact( function() { if ( pattern.format ) { editor.formatter.apply( pattern.format, {}, node ); node.replaceData( 0, node.data.length, ltrim( node.data.slice( pattern.start.length ) ) ); } else if ( pattern.element ) { parent = node.parentNode && node.parentNode.parentNode; if ( parent ) { parent.replaceChild( document.createElement( pattern.element ), node.parentNode ); } } } ); // We need to wait for native events to be triggered. setTimeout( function() { canUndo = 'enter'; } ); } ); } function ltrim( text ) { return text ? text.replace( /^\s+/, '' ) : ''; } } ); } )( window.tinymce, window.setTimeout );