Fork me on GitHub

Developer's How-to: External Link Picker Button in the RichText Editor

Configurations

As explained in the Installation page, all the configurations for the exdocpickerbase CKEditor plugin are set in the ckeditor.config.appended.json property (please see CKEditor configuration properties for the detail on ckeditor.config.appended.json property.) like the following example:

{
  "exdocpickerbase" : {
    "buttonLabel" : "Link to Hippo Blog Articles",
    "buttonIcon" : "/cms/images/hippoblogpicker.png",
    "dialogTitle" : "Hippo Blog Article Browser",
    "dialogMinWidth" : 640,
    "dialogMinHeight" : 480,
    "defaultDocumentIcon" : "/cms/images/onehippo-default.png",
    "getSearchURL" : "return '/cms/examples/hippoblogarticles.jsp?q=' + encodeURI(data.query);",
    "getLinkAttributes" : "var attrs = {}; attrs['href'] = item.href; attrs['data-custom1'] = item['data-custom1']; return attrs;"
  }
}
        

Here's the detail on each configuration:

Property name Description Example value(s) Default value(s)
buttonLabel The label for the link button shown in the CKEditor. "Link to Hippo Blog Articles" "Link to External Document"
buttonIcon The icon image URI for the link button shown in the CKEditor. "/cms/images/hippoblogpicker.png" exdocpickerbase.png
dialogTitle The title of the external document searching popup dialog which is to show when user clicks on the link button. "Hippo Blog Article Browser" "External Document Browser"
dialogMinWidth The minimum width of the external document searching popup dialog. 640 640
dialogMinHeight The minimum height of the external document searching popup dialog. 480 480
defaultDocumentIcon The default document icon image URI, which is used instead if icon property is empty in a document item JSON Object. /cms/images/onehippo-default.png
getSearchURL

The function body string which is to be invoked by the plugin when user clicks on 'Search' button in the popup dialog.

This function body is responsible for returning a valid REST Service URL based on the search query term entered by the user. See the example implementation as shown above.

Note: The function body can expect 'data' object argument. An example 'data' object argument looks like '{ "query" : "a_search_term" }'. In other words, you can use 'data.query' in the function body to get the string input value in the search text box.

getLinkAttributes

The function body string which is to be invoked by the plugin when user selects an external document item after a search and clicks on OK button in order to set attributes of the (new) link element.

This function body is responsible for extracting attributes from a search result item and sets required/optional attributes in the generated link element (<a ... >). See the example implementation as shown above, which sets the "data-custom1" attribute as well as the normal "href" attribute.

Note: The function body can expect 'item' object argument. An example 'item' object argument is exactly the same as the selected item of the result list from your own REST service. So, you can use 'item.href' in the function body, for instance, to get the href attribute value from the search result item.
Please take a look at an example REST service output in the demo project here: https://github.com/bloomreach-forge/external-document-picker/tree/master/demo/cms/src/main/webapp/examples/hippoblogarticles.jsp

Wait! Why function body string configurations instead of JavaScript function itself?

Good question! :) Yeah, it is a bit ugly with function body strings. :(

However, unfortunately, that's how we can handle it for getSearchURL and getLinkAttributes properties for now (at least until 7.9).

The reason is that the internal Hippo CMS7 CKEditor Plugin parses the custom CKEditor configurations to org.json.JSONObject objects first and merge them with other default properties in the Java code. So, it cannot handle JavaScript function object properly.

Therefore, a workaround solution came out to solve this problem: If you provide function body as string instead, then this CKEditor plugin creates JavaScript functions by using Function constructor. That's why those function body string properties were born for this plugin.

Implementing your own REST Service for External Document Searches

You should provide a valid REST service URL in the getSearchURL function body property as shown above.

Please take a look at a very simple REST service implementation JSP page (residing in the demo project): https://github.com/bloomreach-forge/external-document-picker/tree/master/demo/cms/src/main/webapp/examples/hippoblogarticles.jsp

Basically, your REST service implementation should return a JavaScript array, each item of which can be in any forms because it's totally up to you to extract attributes from each result item and set link attributes in the generated link in getLinkAttributes function body property.

Note 1: Because the REST service is invoked by client-side CKEditor plugin, the REST Service URL must be from the same origin in order to avoid security problems.

Note 2: If you want to secure your REST service which is not based on Apache Wicket components and/or if you want to get access to the same Wicket Session and JCR Session for the currently authenticated CMS user, then please refer to How to build secure non-Wicket-component based pages?.

Handling Custom Links in Delivery Tier

Maybe you're also interested in having a custom behavior handling the links generated by this plugin. In that case, you might want to implement a custom org.hippoecm.hst.content.rewriter.ContentRewriter for that. Please refer to HST-2 Rewriting rich text field runtime page and its child pages for examples.