RE: Liferay 7: Adding external plugins to CKEditor

thumbnail
Zsombor Nagy, modified 8 Years ago. New Member Posts: 22 Join Date: 3/22/17 Recent Posts

EXAMPLE: adding YouTube plugin to CKEditor in Liferay 7

I created a DynamicInclude based module and an EditorConfigContributorbased based one according to the official tutorials: Modifying an Editor’s Configuration and Adding New Behavior to an Editor

In the DynamicInclude based module:
  • I pasted the plugin files to src/main/resources/ckeditor/plugins/youtube/
  • In the component's include method I transferred each file to the respose object the following way:
// CKEDIROT_PLUGINS_PATH = "/META-INF/resources/ckeditor/plugins/";

ClassLoader classLoader = DynamicIncludeTest.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(CKEDIROT_PLUGINS_PATH+"youtube/plugin.js");
StreamUtil.transfer(inputStream, response.getOutputStream(), false);

inputStream = classLoader.getResourceAsStream(CKEDIROT_PLUGINS_PATH+"youtube/lang/ar.js");
StreamUtil.transfer(inputStream, response.getOutputStream(), false);

inputStream = classLoader.getResourceAsStream(CKEDIROT_PLUGINS_PATH+"youtube/lang/cs.js");
StreamUtil.transfer(inputStream, response.getOutputStream(), false);
// ... the other language js files...


In the EditorConfigContributor based module's populateConfigJSONObject method:
  • I appended "youtube" to the external plugins:
String extraPlugins = jsonObject.getString("extraPlugins");
extraPlugins = extraPlugins + ",youtube,";
jsonObject.put("extraPlugins", extraPlugins);
  • I inserted the button into toolbar:
JSONArray toolbarLiferay = jsonObject.getJSONArray("toolbar_liferay");
JSONArray newTools = JSONFactoryUtil.createJSONArray();
newTools.put("Youtube");
toolbarLiferay.put(newTools);

I deployed the two modules and have a fully functional Youtube plugin, with a small problem.

PROBLEM: - The button won't have an icon

I cannot transfer the plugin's png icon in the DynamicInclude based module's include method, since a DynamicInclude module...
...allows anyone to inject JavaScript code right after the editor instantiation to configure/change the editor.

In my example if I try to pass the YouTube plugin's png icons, like...
inputStream = classLoader.getResourceAsStream(CKEDIROT_PLUGINS_PATH+"youtube/images/icon.png");
StreamUtil.transfer(inputStream, response.getOutputStream(), false);

... I'll just get parse errors:
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1922): Parse error. illegal character
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1922): Parse error. missing } after function body
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1923): Parse error. illegal character
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1923): Parse error. missing } after function body
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1924): Parse error. illegal character
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1924): Parse error. missing } after function body
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:116] (http://localhost:8080/group/guest/~/control_panel/manage:1924): Parse error. illegal character
ERROR [http-nio-8080-exec-1][GoogleJavaScriptMinifier:129] {0} error(s), {1} warning(s)


QUESTION
  • How can I pass a plugin's icons to be able to see it on it's respective button in CKEditor?
  • Is there a simpler approach to resolving this problem scenario?

Thank you for reading and assisting!
thumbnail
Zsombor Nagy, modified 8 Years ago. New Member Posts: 22 Join Date: 3/22/17 Recent Posts
Bump!
No response for a month emoticon
Anyone, any help?
thumbnail
Tim Telcik, modified 7 Years ago. New Member Posts: 10 Join Date: 4/1/10 Recent Posts

Hello Zsombor,

 

maybe I can help umbump the static image loading issue you reported.

 

Discussions and sample solutions for using static images in OSGi modules are available at:

 

 

However, you still need to patch the ckeditor youtube plugin config to work around a limitation in Liferay OSGi static image servlet proxy.

 

The default image resource path is relative to the Liferay Portal 7.x "frontend-editor-ckeditor-web" module, which is incorrect.

 

Hence, update the youtube plugin script (plugin.js) with this snippet (or equivalent) :

 

            editor.ui.addButton('Youtube', {
                label : editor.lang.youtube.button,
                toolbar : 'insert',
                command : 'youtube',
                //icon : this.path + 'images/icon.png'
                icon : '/o/YOUR-LIFERAY-PORTAL-OSGI-MODULE-NAME/ckeditor/plugins/youtube/' + 'images/icon.png'
            });

 

This approach is working for me.

 

I would prefer the Liferay Portal 7.x "frontend-editor-ckeditor-web" module to behave in a more consistent manner which honours the static image path of the ckeditor extension module.

 

Let me know if this helps.

 

Regards,

 

Tim

 

thumbnail
Antonio Musarra, modified 7 Years ago. Junior Member Posts: 66 Join Date: 8/9/11 Recent Posts

Hi.

You have resolved?

You can share your project?

 

Thanks

thumbnail
Amos Fong, modified 7 Years ago. New Member Posts: 18 Join Date: 3/6/12 Recent Posts
Hi,

I'm trying to add the htmlbuttons plugin (https://ckeditor.com/cke4/addon/htmlbuttons) to ckeditor in my Liferay 7.1.2 GA3 instance, like this:

@Component(immediate = true, service = DynamicInclude.class)
public class RvmCKEditorDynamicInclude implements DynamicInclude {

  @Override
  public void include(HttpServletRequest request, HttpServletResponse response, String pKey) throws IOException {
    Bundle bundle = _bundleContext.getBundle();
    URL entryURL = bundle.getEntry("/META-INF/resources/ckeditor/plugins/htmlbuttons/plugin.js");
    StreamUtil.transfer(entryURL.openStream(), response.getOutputStream(), false);
  }

  @Override
  public void register(DynamicIncludeRegistry dynamicIncludeRegistry) {
    dynamicIncludeRegistry.register("com.liferay.frontend.editor.ckeditor.web#ckeditor#additionalResources");
  }

  @Activate
  protected void activate(BundleContext bundleContext) {
     _bundleContext = bundleContext;
  }

  private BundleContext _bundleContext;
}

​​​​​​​However, I get this bizarre behavior when I try to edit a web content:



As you can see, the plugin is not added correctly to Liferay's ckeditor, it is loaded along with the content of the Web Content Editor portlet. Anyone knows what I am missing?

Thank you!
​​​​​​​