2015-08-07 9 views
8

Sto lavorando su un CMS personalizzato in cui CKEditor (4.5.1) è integrato per la generazione di contenuti HTML amichevoli.Blocco/inline 'meta markup' in CKEditor

Una delle funzionalità che stiamo spedendo è la possibilità di limitare parti della pagina a gruppi specifici di utenti e il modo più semplice per farlo è stato creare un nuovo tag e utilizzarlo per il tracciamento di contenuto, ad es <restrict data-usertype="1,2,3">restricted content for user types 1, 2, 3 here</restrict> che verrebbe rimosso dal backend.

Il problema che ho è che il mio tag personalizzato richiede implicitamente sia il blocco sia i tag in linea e non sono sicuro di come impostarlo correttamente.

Ho provato una varietà di combinazioni di cose che non consentono di aggiungere alcun contenuto o di disabilitare completamente il plug-in (perché non rientra nel controllo di integrità di ACF); in questo momento la configurazione che ho mi permetterà di aggiungere il blocco <restrict>, consentendomi di modificarlo nella finestra di dialogo (anche facendo doppio clic) ma non mi permetterà di annidare alcun contenuto di alcun tipo e farà sì che CKEditor lanci un 'non potrebbe leggere gli attributi di null 'warning quando si ritorna alla modalità sorgente.

Il mio attuale configurazione di questo plugin è la seguente:

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. 
     } 
    }); 

Credo che ho impostato in modo non corretto editables e, probabilmente, il generale ha permesso roba contenuti per questo tag, ma non riesco a vedere come mi' Dovevo creare un tag simile, e non posso immaginare che la creazione di un tag fantasma che verrà analizzato al di fuori del browser sarebbe un nuovo problema.

Grazie in anticipo!

risposta

1

In realtà ho trovato una risposta alternativa a questo problema, principalmente ridefinendo un po 'il problema.

In primo luogo, mi sono reso conto che quasi sempre il CMS limiterà il contenuto, lo farà in un contesto di blocco piuttosto che in linea comunque - intere sezioni div saranno rimosse anziché parti di una riga.

Una volta che me ne sono reso conto, mi sono reso conto che non era proprio un widget che avevo bisogno di costruire, ma un plugin più convenzionale.

Ho quindi iniziato prendendo il plugin insert-div per CKEditor e iniziando a personalizzarlo per adattarlo. Nel metodo init del plugin, v'è la seguente configurazione iniziale:

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; 

Questo in gran parte costituito esigenze del plugin, ma sto lavorando da una copia pre-costruito di CKEditor, e non ho né il tempo né la voglia di impostare un processo per ricostruire/reminify CKEditor - che è un problema qui perché $blockLimit viene utilizzato solo all'avvio e aggiungendolo a livello di plugin non funziona perché l'unica volta che viene valutata è già stata eseguita prima che i plug-in vengano caricati. Per contrastare questo, il plugin clona la chiusura e la definizione di CKEDITOR.dom.editorPath dopo che il plugin è stato eseguito in modo da rivalutare correttamente i metodi DTD.

A parte questo, ho modificato tutti i riferimenti 'creatediv'/'editdiv'/'removediv' a '* restrict' in modo appropriato, ho cambiato le posizioni che controlla 'div' in 'restrict' e sostituito la definizione di dialog con la finestra di dialogo che effettivamente ho bisogno, che è molto specifica del caso d'uso. Poiché si tratta principalmente di un lavoro di copia/incolla, non sembra davvero utile fornire il codice che posso, poiché i bit che non sono copia/incolla sono specifici del prodotto.

Ciò che ha reso questo più complesso è il fatto che ho anche lo styling dinamico gestito sull'elemento limitare, per produrre un look simile a quello del tag Mostra blocchi, in cui l'elenco di restrizioni è documentata nel tag stesso attraverso restrict::before { content: '...' } che punta a un attributo sul tag restrict stesso, cke-restrict-description, che viene aggiornato ogni volta che viene eseguita la finestra di dialogo e ogni volta che l'editor passa alla modalità WYSIWYG (una volta su instanceReady, una volta su editor.on ('modalità ') dove editor.mode ==' wysiwyg ')