linking to internal pages using ckeditor 4

It’s functionality that already exists in other editors such as tinyMCE, i am surprised that linking to internal pages using ckeditor cannot be acheived in an easier (native built-in) way.

So, when i develop CMS’s for various clients, i always use CKEditor, and 9 times out of 10, the client needs to link to internal pages – news articles, events, documents… all linked to from within their “editor”.

I always use the following method to add to the existing link plugin.

This is using CKEditor 4 – the syntax is slightly different to that of CKEditor 3, i will point out where, and an alternative for previous CKEditor versions)

There are 4 main additions needed to the link.js file (located in plugins directory).

1. declare the partIds

On line 41, a variable declatation looks like this:
[code language=”js”]
// Handles the event when the "Type" selection box is changed.
var linkTypeChanged = function() {
var dialog = this.getDialog(),
partIds = [ ‘urlOptions’, ‘anchorOptions’, ’emailOptions’ ],

[/code]

Add in our partIds, so it should look like this:

[code language=”js”]
// Handles the event when the "Type" selection box is changed.
var linkTypeChanged = function() {
var dialog = this.getDialog(),
partIds = [ ‘urlOptions’, ‘anchorOptions’, ’emailOptions’, ‘newsOptions’, ‘eventOptions’, ‘docOptions’, ‘localPageOptions’ ],
…[/code]

2. Configure and add the data for dialogs

Around line 327 a return starts. we need to add to the items array:

[code language=”js”]
return {
title: linkLang.title,
minWidth: 350,
minHeight: 230,
contents: [
{
id: ‘info’,
label: linkLang.info,
title: linkLang.info,
elements: [
{
id: ‘linkType’,
type: ‘select’,
label: linkLang.type,
‘default’: ‘url’,
items: [
[ linkLang.toUrl, ‘url’ ],
[ linkLang.toAnchor, ‘anchor’ ],
[ linkLang.toEmail, ’email’ ]
],

[/code]

we need to add ours, so items looks like:

[code language=”js”]
items: [
[ linkLang.toUrl, ‘url’ ],
[ linkLang.toAnchor, ‘anchor’ ],
[ linkLang.toEmail, ’email’ ],
[ ‘Page’, ‘localPage’ ], // extra items
[ ‘Document’, ‘docPage’ ],
[ ‘Event’, ‘eventPage’ ],
[ ‘News’, ‘newsPage’ ]
],

[/code]

3. Declare and map the data

This code is right under the items array we just edited, and looks like:

[code language=”js”]
// News
{
type : ‘vbox’,
id : ‘newsPageOptions’,
children : [
{
type : ‘select’,
label : ‘Select news article to link to’,
id : ‘newsPage’,
title : ‘Select news article to link to’,
items: eval(document.getElementById("newsListJSON").value),
setup : function( data )
{
if ( data.newsPage )
this.setValue( data.newsPage );
},
commit : function( data )
{
if ( !data.newsPage )
data.newsPage = {};
data.newsPage = this.getValue();
}
}]
},
[/code]

You’ll see that the items array in this code refers to the value of a text input – this is how i have loaded the JSON. My hidden input currently looks like this:

[code]
<input type="hidden" id="newsListJSON" name="newsListJSON" value="[[‘news title’, ‘/news/article/url’], [‘other news title ‘/news/article/other/url’]]" />
[/code]

It’s not best practice to use a hidden input (though it works perfectly well as long as you have sanitized / cleaned it before sending it).

I will be slightly updating this so that the items will pull in JSON from an actual .json file or even from the server.

4. Make the links actually work…

Right down toward the bottom of this file, there is a function called onOk, we need to add a few lines:

Inside the switch, we need to add our cases:

[code language=”js”]
case ‘newsPage’:
attributes[‘data-cke-saved-href’] = data.newsPage;
break;
[/code]

One for each of course. I have only shown one here.

What about CKEditor 3?

The syntax is slightly different, previously we had to do:

[code language=”js”]
attributes._cke_saved_href = data.newsPage;
[/code]




1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *