Web Design Blog

Adding the "rel" and "title" attributes to image links in CKEditor 3

01.08.2010 01:37PM by Evan Johnson

CKEditor is the new and improved successor to the venerable FCKeditor JavaScript WYSIWYG editor. I've used TinyMCE and FCKeditor before, but this was my first time trying out the new CKEditor 3.1. I am using it on a new Drupal website via the Drupal CKEditor module. The problem I ran into, however, is using Lightbox2 on images inserted via CKEditor. CK does not provide a way to add the "rel" attribute to image links (or any links for that matter). CK also doesn't allow adding the "title" attribute to image links. Lightbox uses both of these to determine which images to display, group together in galleries, provide a caption, etc. I found a patch for FCKeditor which allows adding a "rel" attribute to image links, but I couldn't find one for the new CKEditor. So here we are. :)

This is a total hack, since I have not looked in to how to properly make a plugin for the new CKEditor, but it works pretty well. Maybe someone who knows how to make plugins to CKEditor can show me the way.

To start hacking, we need to first copy over the minified ckeditor\plugins\image\dialogs\image.js with the indented ckeditor\_source\plugins\image\dialogs\image.js, since it's really hard to work with the minified image.js.

In image.js all of the tabs and fields in the Image popup dialog are defined in the "contents" array (below the onHide function). We will add our new "rel" and "title" fields to the content array, in the "Link" tab's sub-array. I added the new code at the end of the Link tab's definition array after the txtUrl, browse, and cmbTarget fields (around line 1146). The code I added is:

{
id : 'txtTitle',
type : 'text',
label : editor.lang.link.advisoryTitle,
'default' : '',
setup : function( type, element )
{
	if ( type == LINK )
	{
		this.setValue( element.getAttribute( 'title' ) );
	}
},
commit : function( type, element )
{
	if ( type == LINK )
	{
		if ( this.getValue() || this.isChanged() )
		{
			element.setAttribute( 'title', this.getValue() );
		}
	}
}
},
{
id : 'txtRel',
type : 'text',
label : editor.lang.link.rel,
'default' : '',
setup : function( type, element )
{
	if ( type == LINK )
	{
		this.setValue( element.getAttribute( 'rel' ) );
	}
},
commit : function( type, element )
{
	if ( type == LINK )
	{
		if ( this.getValue() || this.isChanged() )
		{
			element.setAttribute( 'rel', this.getValue() );
		}
	}
}
},

This adds a _txtTitle_ and _txtRel_ field to the Link tab on the Insert Image CKEditor dialog. Look out for commas! The first time I did this I missed a comma between the cmbTarget and txtTitle declarations, which borked everything.

The final thing we need to do is create the "editor.lang.link.rel" English translation definition so the new _txtRel_ field is properly labeled in the dialog (I re-used the existing "editor.lang.link.advisoryTitle" translation for _txtTitle_). To do this, open up _ckeditor\lang\en.js_. I added the following snipped between _styles_ and _selectAnchor_ in the "Link" block, but just make sure it's in the "Link" block of translations.

rel:'Rel',

You could probably hard-code this label, but I kept with the translation system. I didn't do any labels except the English one, but you get the idea. If you are using another language insert the "rel" label into the appropriate file for that language.

You can now set the "rel" and "title" attributes on the image link, and use them with the Lightbox of your choice!

Comment

Gravatar Image
On Jan 11, 07:42 PM, (Link)
Wesley said:

Evan,

How does CKeditor’s markup output look compared to TinyMCE? I’ve used TinyMCE quite a bit but I’ve been disappointed with the quality of markup it produces, even after I customize it. I’ve been using Tidy on the server to clean up what I don’t like about TinyMCE but would rather avoid that process.

cheers,
Wes

Gravatar Image
On Jan 14, 11:25 AM, (Link)
Evan Johnson said:

@Wesley

Well, I mean nothing beats custom markup, but it seems to be okay. There is some extra whitespace in the lists, but everything renders OK. CK uses em instead of i and all that jazz too. Defining custom styles works well too. Good enough for me!

Gravatar Image
On Feb 2, 05:17 AM, (Link)
Dennis said:

It doens’t work for me :(… I do excactly what is said in the tutorial but my image popup dialog doesnt open. Does someone has a complete image.js where the rel code is added already?

thanks,

Dennis

Gravatar Image
On Feb 17, 03:41 PM, (Link)
Martin said:

Hey Evan, thank you very much for your hack!
BUT!!!! This is NOT correct if ( type LINK )

right way is… if ( type == LINK )

Thanks, bye.
m

Gravatar Image
On Feb 17, 04:44 PM, (Link)
Evan Johnson said:

@Martin – Right you are! The stupid Textile markup converter processes the "==" and removes it. I fixed the code in article above.

@Dennis – perhaps this fixed your problem as well?

Sorry folks, it should work now!

Gravatar Image
On Feb 26, 12:36 PM, (Link)
Jeff said:

How about create a diff patch for this? It’s hard to tell where to start the paste of your code, since there is no context.

Gravatar Image
On Feb 26, 01:19 PM, (Link)
Jeff said:

Also, just as a note: something similar can be achieved without hacking for Drupal users, using the Lightbox2 module. One can configure a class of image to have the lightbox rel link automatically included, so it’s as simple as adding a link and a class when inserting an image from CKEditor. The Lightbox2 module does the rest.

Gravatar Image
On Mar 3, 01:41 PM, (Link)
Mark Peters said:

FYI:

I was able to get this working on the recently updated v3.2 of CKeditor.

I had problems with getting the entry field label to appear using the the en.js language file until I copied over a the not minified js version from the source.

Gravatar Image
On Mar 3, 09:34 PM, (Link)
Evan Johnson said:

@Jeff – I have not had the time to roll a proper Diff, sorry it’s confusing about where to insert the code. I will try to get around to this eventually. Also, you make a good point about the Drupal Lightbox2 module. Thanks!

Gravatar Image
On Mar 9, 08:36 AM, (Link)
Joshua Lowery said:

Okay everyone…this frustrated the heck out of me but I finally got it to work. I figured I’d share it with you all and make your life’s a lot easier.

I’m using: – Drupal 6.16 – CKEditor 3.1 – My Brain

Replace ckeditor\plugins\image\dialogs\image.js with this file.

http://docs.google.com/leaf?id=0B-AxBjS8xkHmZDNiN2IwMTItMDkzMS00NzZmLTkxYjAtNzc1ZjBjODA5ZTEz&hl=en

Replace ckeditor\lang\en.js with this file.

http://docs.google.com/leaf?id=0B-AxBjS8xkHmNTFlZjNkMmYtNGQ1NS00Mzg0LThjNGYtZjMyYmVjMTI3OTQ3&hl=en

Here is a screenshot of what it looks like before:

http://docs.google.com/leaf?id=0B-AxBjS8xkHmMDJkOGNlMWEtN2QwMS00NTY2LWE0MmMtMjY0N2RhYjU1NTI5&hl=en

Here is a screenshot of what it looks like after:

http://docs.google.com/leaf?id=0B-AxBjS8xkHmNjNiN2IwYzctMDA4ZC00Yjg2LTgyZjUtNjQxMTQwYWU2Y2Y0&hl=en

  Subscribe to article comments