Ben Sinclair
Ben Sinclair

Reputation: 3986

CKEditor 4: Replacing code when in editor view

My software allows people to upload images to a "Files" section on my site. I want to allow users to insert those images into a CKEditor 4 instance but I want to control where those images are hosted.

Instead of inserting the following:

<img src="http://domain.com/image.jpg" />

I want it to insert:

<img src="[file:12345678]" />

I can then use PHP to control what URL will be displayed on the website.

The issue is, in the WYSIWYG view of CKEditor, it shows as the image could not be found. Is there anyway I can create a plugin that replaces the [file:12345678] with the image code when in WYSIWYG view but in source view it reverts back to [file:12345678]?

Kind of like how the BBCode plugin works. When you go to source view you see:

The [b]brown fox[/b] jumped over the log

But the editor view you see:

The brown fox jumped over the log

I tried to work out the code from the BBCode plugin but the BBCode parsers seems to be something built-in.

I found the following code but it only applies to the source view. I can't seem to find out if there is a similar function of the WYSIWYG view.

editor.dataProcessor.htmlFilter.addRules(
{
    elements :
    {
        img : function( element )
        {
            // I can get the src of any image and then replace it.
            element.attributes.src
        }
    }
});

Thanks for any advice you can give ;)

Upvotes: 2

Views: 2061

Answers (1)

Reinmar
Reinmar

Reputation: 22023

There are two type of filters in htmlDataProcessor (which is the default data processor) - htmlFilter which is used to filter HTML format, so the format used "inside" editor while editing; and dataFilter which is used to filter data format, so the format used "outside" editor - the one you see in source mode or when you call editor.getData(). Those names can be confusing, but it helps when you remember that "data" is outside (because editor.getData()).

So I guess that when loading data to editor (transforming data to HTML) you want to replace [file:\d+] URLs with addresses from some hash and when getting data back (transforming HTML to data) you want to make the opposite transformation.

Therefore you need to extend both filters - htmlFilter and dataFilter. This is how the dataFilter may look:

editor.dataProcessor.dataFilter.addRules( {
    elements: {
        img: function( el ) {
            el.attributes.src = fileIdToUrlHash[ el.attributes.src ];
        }
    }
} );

Similar operation you have to do in the htmlFilter.

Upvotes: 4

Related Questions