Yesterday I was working on the planning of a new site to be built with ExpressionEngine and was wondering about the best way to let editors link to other entries from within the body of an entry they’re creating or editing. ExpressionEngine doesn’t have this sort of functionality built into it by default so I asked on Twitter to find out if anyone knew of any add-ons that had been created that might do this.
One of the replies I got from Eric Barstad mentioned epEditor which does indeed include this functionality. epEditor also has its own built-in image and file manager but I don’t really like some of its HTML output and there’s no documentation that goes with it so I don’t know if it can be configured to change this or any other settings. It seems that the internal linking feature if only available if you’re also using the Structure module.
I have used Structure on more than one occasion, but I don’t use it exclusively, so I began thinking about whether it would be possible to achieve what I wanted with the WYSIWYG editor I usually use, TinyMCE. Then I remembered about the External Link List URL option which does in fact allow you to provide a list of links that editors can insert into their content. Configuring TinyMCE was fairly simple, so then it was just a question of working out how to get ExpressionEngine to output a list of links that TinyMCE could read.
The process
First you need to tell TinyMCE which file contains the array of links to include. These days I’m exclusively using either the LG TinyMCE 2 or MX TinyBrowser (with TinyMCE support) Fieldframe fieldtypes for creating WYSIWYG areas. Both include a tinymce_config folder where you can create different configuration files which feature different buttons, size, appearance etc. According to the TinyMCE Wiki documentation, you add the following to your javascript configuration file:
external_link_list_url : "myexternallist.js"
To get a list or links from within ExpressionEngine, the path to myexternallist.js needs to be changed to a template on your site. So first we need to create that template. For my example, I’m creating a template group called tinymce which will contain an index template file. By default, when creating a new template group, ExpressionEngine will populate that folder with an index page saved as a ‘web page’. So the first thing to do after having created the template group is to select the preferences for that group where you can change the type of the index template from web page to javascript. You’ll also want to allow PHP to be parsed in the template (and leave the parsing stage as output).
(It should be noted that if you save your templates as files, as I do, even though you’ve selected javascript as the type, the file will be saved with a .php extension.)
Next you’ll want to add some ExpressionEngine code to your template to retrieve the list of entries that you want to appear in the link list.
< ?php
header('Content-type: text/javascript');
print "var tinyMCELinkList = new Array(";
?>
{exp:weblog:entries weblog="site" disable="categories|member_data|pagination|trackbacks" dynamic="off"}
["{title}", "{path={url_title}}"]{if count != total_results},{/if}
{/exp:weblog:entries}
< ?php
print ");";
?>
In my example, I’ve selected a weblog called site which I usually use for static, stand-alone pages (i.e. not part of another section) so the URI for these pages is always site_name / url_title, but if you want to populate your list with links from other sections too, you’d just add more exp:weblog:entries tags with each one outputting a slightly different path. If you do use more than one exp:weblog:entries tag, you’d leave {if count != total_results},{/if} until the very last one, because this is to add a comma to the end of every line except for the very last one.
You can test that the template is outputting in the correct format by viewing it directly in the browser. It should output in this format:
var tinyMCELinkList = new Array( // Name, URL ["Link 1", "http://www.example1.com"], ["Link 2", "http://www.example2.com"], ["Link 3", "http://www.example3.com"] );
Then you just need to edit your TinyMCE config file so that it has the correct path, so in my example it would be /index.php/tinymce/index.js.
If you’ve followed everything correctly, you should have a Link List dropdown appear in the link popup window below the Link URL field when publishing or editing an entry. If there a lot of entries, the dropdown will be one big long list which isn’t very usable, but you could perhaps make it easier to differentiate between items by adding the name of the weblog or section at the beginning. And it’s certainly better than asking the editor to copy and paste a link.
Tyssen Design
Nick | October 20th, 2009 at 9:43 am
Great article!
I’ve attempted such a configuration with MX Universal Editor (the newest version of MX Tinybrowser), but am not having any luck with getting the link list to pull. I’ve created many link lists with tinyMCE in the past, but never with EE.
As with MX Tinybrowser, the tinymce_config for MX Universal Editor has a few options to choose from, article.js, office.js, and tiny.js. I’ve edited the code for both article.js and tiny.js, adding the appropriate parameter for external_link_list_url, but nothing will pull up.
I’ve checked the js file that pulls in my weblogs and it displays accurately. I’ve also double check that edits to the config files. Any ideas why the link list will not appear?
John Faulds | October 20th, 2009 at 9:51 am
Hi Nick,
I’ve not actually had a chance to look at Max’s implementation of that feature yet yet so you may be better posting a question on the EE forums to get a quicker response.
Dan | December 5th, 2009 at 5:24 am
First off, great info! Thx
Just a quick question…since the JS file that will display the links is accessible through the web, do you foresee any security issues?
I couldn’t think of any since really its just a sitemap of the website in JS format, right?
Sjoerd | January 11th, 2010 at 10:10 am
I didn’t manage to make a link list with multiple weblogs. Can you post an example? Would it be possible to divide the weblogs with headers like Content, News, Products and so on?
John Faulds | January 11th, 2010 at 10:45 am
Hi Sjoerd, you’re actually better off using Wiseup Studios MX Universal Editor which includes a built-in link manager which came out after I wrote this article.