Block / embed meta markup in CKEditor

I am working on a custom CMS where CKEditor (4.5.1) is integrated to create friendly HTML content.

One of the functions we send is the ability to limit parts of a page to specific user groups, and the cleanest way to do this, as far as I could tell, is to create a new tag and use it to track content, for example <restrict data-usertype="1,2,3">restricted content for user types 1, 2, 3 here</restrict> , which will be removed from the backend.

The problem is that my custom tag must implicitly support both block and inline tags, and I'm not sure how to properly configure this.

I tried various combinations of things that either prohibit any content added at all, or completely disable the plugin (because it does not correspond to the reality of the ACF check); right now the configuration that I have will allow me to add a <restrict> block, allow me to edit it in a dialog box (including double-clicking), but it will not allow me to embed any content of any type and cause CKEditor to throw away 'could not read attributes of zero warning when returning to the initial mode.

My current configuration of this plugin is as follows:

  CKEDITOR.dtd.restrict = { a: 1, abbr: 1, address: 1, area: 1, article: 1, aside: 1, audio: 1, b: 1, bdi: 1, bdo: 1, blockquote: 1, br: 1, button: 1, canvas: 1, cite: 1, code: 1, command: 1, datalist: 1, del: 1, details: 1, dfn: 1, div: 1, dl: 1, em: 1, embed: 1, fieldset: 1, figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1, hr: 1, i: 1, iframe: 1, img: 1, input: 1, ins: 1, kbd: 1, keygen: 1, label: 1, map: 1, mark: 1, meter: 1, noscript: 1, object: 1, ol: 1, output: 1, progress: 1, p: 1, pre: 1, q: 1, ruby: 1, s: 1, samp: 1, script: 1, section: 1, select: 1, small: 1, span: 1, strong: 1, sub: 1, sup: 1, table: 1, textarea: 1, time: 1, u: 1, ul: 1, 'var': 1, video: 1, wbr: 1, '#': 1 }; // Allow <restrict> as a valid tag. CKEDITOR.dtd.$block.restrict = 1; CKEDITOR.dtd.$inline.restrict = 1; CKEDITOR.dtd.$blockLimit.restrict = 1; // Treat <restrict> as a block limiter tag CKEDITOR.dtd.$removeEmpty.restrict = 1; // Remove <restrict /> tags if they are empty CKEDITOR.dtd.$transparent.restrict = 1; // Treat the tag as transparent as far as content models go CKEDITOR.dtd.body.restrict = 1; // Allow it in the body, div and p tags. CKEDITOR.dtd.div.restrict = 1; CKEDITOR.dtd.p.restrict = 1; var allowedEls = ['restrict']; for (var i in CKEDITOR.dtd.restrict) { if (CKEDITOR.dtd.restrict.hasOwnProperty(i) && i != '#') { allowedEls.push(i); } } // Define the widget. editor.widgets.add( 'restrict', { button: 'Restricted Content', dialog: 'restrictDialog', template: '<restrict />', editables: {}, allowedContent: allowedEls.join(' ') + '[*]{*}(*)', // All the above elements, with any attributes, styles or classes. requiredContent: 'restrict[data-*]', upcast: function (element) { return element.name == 'restrict'; }, init: function () { // Some stuff which iterates through the various // properties I care about, grabs from data // attributes and pushes to this.setData(). }, data: function () { // Some stuff that just fetches vars from this.data, // sets the relevant data attribute and also sets an // attribute on the span created by CKEditor since // styling and ::before content is used to show who // the block is visible to - the result is much like // the Show Blocks plugin. This stuff all works // correctly and being omitted changes nothing. } } ); 

I suppose that I incorrectly configured editables and possibly the common permitted content for this tag, but I donโ€™t see how I should create such a tag, and I canโ€™t imagine that creating such a phantom tag that will be parsed outside the browser will be new a problem.

Thanks in advance!

+8
ckeditor
source share
1 answer

I really found an alternative answer to this problem, basically redefining the problem a bit.

Firstly, I realized that almost all the time the CMS will restrict the content, it will do it in a block context, and not in a linear one way or another - entire div sections will be deleted, not part of the line.

As soon as I realized this, I realized that this is not a widget that I need to create, but a more ordinary plugin.

Then I started using the insert-div plugin for CKEditor and started customizing it. In the plugin initialization method, the following initial settings exist:

 CKEDITOR.dtd.restrict = {}; CKEDITOR.tools.extend(CKEDITOR.dtd.restrict, CKEDITOR.dtd.div); CKEDITOR.dtd.$block.restrict = 1; CKEDITOR.dtd.$blockLimit.restrict = 1; // Treat <restrict> as a block limiter tag CKEDITOR.dtd.$removeEmpty.restrict = 1; // Remove <restrict /> tags if they are empty CKEDITOR.dtd.body.restrict = 1; // Allow it in the body, div and p tags. CKEDITOR.dtd.div.restrict = 1; 

This pretty much adjusts the needs of the plugin, but I work from a pre-created copy of CKEditor, and I have neither the time nor the desire to set up the CKEditor repair / restore process, which is a problem here because $blockLimit used only at startup, and adding to it doesnโ€™t work at the plugin level, because the only time it has been rated has already been run before the plugins were downloaded. To counter this, the plugin clones the closure and definition of CKEDITOR.dom.editorPath after the plugin starts so that it evaluates the DTD methods correctly.

In addition, I appropriately changed all the links 'creatediv' / 'editdiv' / 'removediv' to '* restrict', changed the places he checks for 'div' to 'restriction' and replaced the definition of the dialog with the Dialog that I really needed, which is very useful for a particular case. Since this is mainly work with copy and paste, it doesnโ€™t actually seem useful to provide what code I can, since bits that are not copied / pasted belong to the product.

What made this more complicated is the fact that I also dynamically control the style of the restriction element to create a similar view, similar to the Show Blocks tag, where the list of restrictions is documented in the tag itself through restrict::before { content: '...' } , which points to the attribute of the most restrictive tag itself, cke-restrict-description, which is updated every time the dialog is launched, and also every time the editor switches to WYSIWYG mode (once per Ready instance, once on editor.on ('mode'), where editor.mode == 'wysiwyg')

+1
source share

All Articles