Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CKEditor: How to show a block of code differently in preview

I want to create an element that users can insert it in the editor. The hard part is that it needs to be shown differently from its source. For example, I want to users insert this in the preview part:

23

And in the source part it should be shown like this:

<span class="tagSpecialClass">{{birthYear}}</span> 

The main purpose is to show the mustache tags in a way that users can avoid writing them and just insert them from toolbar that automatically inserts the correct html and preview to it.

My issue is my understanding over CKEditor and the terms I need to read about them in order to implement such a plugin.

How can I force CKEditor to parse/compile/preview a specific tag differently?

Please tell me if my question is too generic!

like image 864
Dijam Avatar asked May 09 '14 14:05

Dijam


1 Answers

This sounds like a job for CKEditor widgets (demos)!

Please take a look at the following example (JSFiddle). It will give you some basic idea how to use widgets to solve your problem. If you follow this official tutorial, you'll know how to implement editable parts in your widgets and enable editing with dialogs, which also might be helpful.

// Some CSS for the widget to make it more visible.
CKEDITOR.addCss( '.tagSpecialClass { background: green; padding: 3px; color: #fff } ' );

CKEDITOR.replace( 'editor', {
    // A clean-up in the toolbar to focus on essentials.
    toolbarGroups: [ 
        { name: 'document', groups: [ 'mode' ] },
        { name: 'basicstyles' },
        { name: 'insert' }
    ],
    removeButtons: 'Image,Table,HorizontalRule,SpecialChar',
    extraPlugins: 'widget',
    on: {
        pluginsLoaded: function() {
            var editor = this;

            // Define a new widget. This should be done in a separate plugin
            // to keep things clear and maintainable.
            editor.widgets.add( 'sampleWidget', {
                // This will be inserted into the editor if the button is clicked.
                template: '<span class="tagSpecialClass">23</span>',

                // A rule for ACF, which permits span.tagSpecialClass in this editor.
                allowedContent: 'span(tagSpecialClass)',

                // When editor is initialized, this function will be called
                // for every single element. If element matches, it will be
                // upcasted as a "sampleWidget".
                upcast: function( el ) {
                    return el.name == 'span' && el.hasClass( 'tagSpecialClass' );
                },

                // This is what happens with existing widget, when
                // editor data is returned (called editor.getData() or viewing source).
                downcast: function( el ) {
                    el.setHtml( '{{birthYear}}' );
                },

                // This could be done in upcast. But let's do it here
                // to show that there's init function, which, unlike
                // upcast, works on real DOM elements.
                init: function() {
                    this.element.setHtml( '23' );
                }
            } );

            // Just a button to show that "sampleWidget" 
            // becomes a command.
            editor.ui.addButton && editor.ui.addButton( 'SampleWidget', {
                label: 'Some label',
                command: 'sampleWidget',
                toolbar: 'insert,0'
            } );            
        }
    }
} );

HTML

<textarea id="editor">
    <p>Some text.</p>
    <p>And there's the widget <span class="tagSpecialClass">{{birthYear}}</span></p>
    <p>Some text <span class="tagSpecialClass">{{birthYear}}</span>.</p>
</textarea>    

Happy coding!

like image 57
oleq Avatar answered Sep 30 '22 06:09

oleq