Reputation: 1
I am new to liferay and currently trying to override config for CKEditor in JournalArticle to add buttons and then plugins.
I have created ConfigContributor and ConfigServletFilter to try override default configuration. Unfortunately both of them keep being overriden by something.
Contributor:
> import java.util.Locale;
> import java.util.Map;
>
> import com.liferay.item.selector.ItemSelector;
> import com.liferay.item.selector.criteria.image.criterion.ImageItemSelectorCriterion;
> import com.liferay.item.selector.criteria.url.criterion.URLItemSelectorCriterion;
>
> import com.liferay.portal.kernel.json.JSONArray;
> import com.liferay.portal.kernel.json.JSONFactoryUtil;
> import com.liferay.portal.kernel.json.JSONObject;
> import com.liferay.portal.kernel.json.JSONUtil;
> import com.liferay.portal.kernel.json.JSONFactory;
> import com.liferay.portal.kernel.util.GetterUtil;
> import org.osgi.service.component.annotations.Component;
> import com.liferay.portal.kernel.editor.configuration.BaseEditorConfigContributor;
> import com.liferay.portal.kernel.editor.configuration.EditorConfigContributor;
> import com.liferay.portal.kernel.portlet.RequestBackedPortletURLFactory;
> import com.liferay.portal.kernel.theme.ThemeDisplay;
> import com.liferay.portal.kernel.util.Validator;
> import org.osgi.service.component.annotations.Reference;
>
> import javax.portlet.PortletURL;
>
> @Component(
> property = {
> "editor.name=ckeditor",
> "javax.portlet.name=com_liferay_journal_web_portlet_JournalPortlet",
> "service.ranking:Integer=" + Integer.MAX_VALUE
> },
> service = EditorConfigContributor.class
> )
> public class CKEditorConfigContributor implements EditorConfigContributor {
>
> @Override
> public void populateConfigJSONObject(
> JSONObject jsonObject, Map<String, Object> inputEditorTaglibAttributes,
> ThemeDisplay themeDisplay, RequestBackedPortletURLFactory requestBackedPortletURLFactory) {
>
> jsonObject.put(
> "allowedContent",
> "a[*](*); div[*](*); figcaption; figure; iframe[*](*); img[*](*){*}; li ol ul; " +
> "p[*](*){text-align}; col[span]; colgroup[span]; table[border, cellpadding, " +
> "cellspacing]{width}; tbody td[colspan, headers, rowspan]{*}; th[abbr, colspan, " +
> "headers, rowspan, scope, sorted]{*}; thead tr; source[*](*); video[*](*);"
> ).put(
> "stylesSet", getStyleFormatsJsonArray(themeDisplay.getLocale())
> );
>
> String namespace = GetterUtil.getString(
> inputEditorTaglibAttributes.get("liferay-ui:input-editor:namespace"));
> String name = GetterUtil.getString(
> inputEditorTaglibAttributes.get("liferay-ui:input-editor:name"));
>
> populateFileBrowserURL(
> jsonObject, requestBackedPortletURLFactory, namespace + name + "selectItem");
>
> Custom configuration
> jsonObject.put("customConfig", "/o/frontend-editor-ckeditor-web/ckeditor/config.js");
>
> Additional toolbar and extraPlugins configuration
> String extraPlugins = jsonObject.getString("extraPlugins");
>
> if (Validator.isNotNull(extraPlugins)) {
> extraPlugins = extraPlugins + ",clipboard";
> else {
> extraPlugins = "clipboard";
> }
>
> jsonObject.put("extraPlugins", extraPlugins);
>
> /*JSONArray toolbar = JSONFactoryUtil.createJSONArray();
> toolbar.put(JSONFactoryUtil.createJSONArray().put("Undo").put("Redo"));
> toolbar.put(JSONFactoryUtil.createJSONArray().put("Styles").put("Bold").put("Italic").put("Underline"));
> toolbar.put(JSONFactoryUtil.createJSONArray().put("NumberedList").put("BulletedList"));
> toolbar.put(JSONFactoryUtil.createJSONArray().put("Link").put("Unlink"));
> toolbar.put(JSONFactoryUtil.createJSONArray().put("Source").put("Expand"));
>
> jsonObject.put("toolbar_simple", toolbar);*/
>
> Log the configuration for debugging purposes
> jsonObject.put("toolbar", "custom");
> System.out.println("CKEditorConfigContributor: " + jsonObject.toString());
> }
>
> private JSONArray getStyleFormatsJsonArray(Locale locale) {
> return JSONUtil.putAll(
> getStyleFormatJsonObject("Normal", "p", null),
> getStyleFormatJsonObject("Heading 1", "h1", null),
> getStyleFormatJsonObject("Heading 2", "h2", null),
> getStyleFormatJsonObject("Heading 3", "h3", null),
> getStyleFormatJsonObject("Heading 4", "h4", null),
> getStyleFormatJsonObject("Preformatted Text", "pre", null),
> getStyleFormatJsonObject("Cited Work", "cite", null),
> getStyleFormatJsonObject("Computer Code", "code", null),
> getStyleFormatJsonObject("Info Message", "div",
> "overflow-auto portlet-msg-info"),
> getStyleFormatJsonObject("Alert Message", "div",
> "overflow-auto portlet-msg-alert"),
> getStyleFormatJsonObject("Error Message", "div",
> "overflow-auto portlet-msg-error")
> );
> }
>
> private JSONObject getStyleFormatJsonObject(String styleFormatName, String element, String cssClass) {
> JSONObject styleJsonObject = jsonFactory.createJSONObject();
>
> if (Validator.isNotNull(cssClass)) {
> JSONObject attributesJsonObject = JSONUtil.put("class", cssClass);
> styleJsonObject.put("attributes", attributesJsonObject);
> }
>
> styleJsonObject.put("element", element).put("name", styleFormatName);
>
> return styleJsonObject;
> }
>
> private void populateFileBrowserURL(
> JSONObject jsonObject, RequestBackedPortletURLFactory requestBackedPortletURLFactory, String eventName) {
>
> PortletURL itemSelectorURL = itemSelector.getItemSelectorURL(
> requestBackedPortletURLFactory, eventName,
> new ImageItemSelectorCriterion(), new URLItemSelectorCriterion());
>
> jsonObject.put(
> "filebrowserImageBrowseLinkUrl", itemSelectorURL.toString()
> ).put(
> "filebrowserImageBrowseUrl", itemSelectorURL.toString()
> );
> }
>
> @Reference
> private ItemSelector itemSelector;
>
> @Reference
> private JSONFactory jsonFactory;
> }
ServletFilter:
import com.liferay.portal.kernel.util.StreamUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.component.annotations.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.net.URL;
@Component(
immediate = true,
property = {
"servlet-context-name=",
"servlet-filter-name=CKEditorConfigServletFilter",
"url-pattern=/o/frontend-editor-ckeditor-web/ckeditor/config.js"
},
service = Filter.class
)
public class CKEditorConfigServletFilter implements Filter {
private Bundle bundle;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("servlet filter zainicjalizowany");
bundle = FrameworkUtil.getBundle(this.getClass());
System.out.println("bundle: " + bundle);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
URL entryURL = bundle.getEntry("/META-INF/resources/js/ckeditor5/config.js");
System.out.println("do filter wystartowal: " + entryURL);
if (entryURL != null) {
response.setContentType("application/javascript");
StreamUtil.transfer(entryURL.openStream(), response.getOutputStream(), false);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
config.js: one of my tries of config.js:
CKEDITOR.editorConfig = function(config) {
// Define changes to default configuration here. For example:
// config.language = 'fr';
// config.uiColor = '#AADC6E';
// Define the toolbar groups as it is a more accessible solution.
console.log(config)
config.toolbarGroups = [
{ name: 'clipboard', groups: ['clipboard', 'undo'] },
{ name: 'editing', groups: ['find', 'selection', 'spellchecker'] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: ['mode', 'document', 'doctools'] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
{ name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
// Remove some buttons provided by the standard plugins, which we don't need to have.
config.removeButtons = 'Underline,Subscript,Superscript';
// Set the most common block elements.
config.format_tags = 'p;h1;h2;h3;pre';
// Simplify the dialog windows.
config.removeDialogTabs = 'image:advanced;link:advanced';
// Additional configuration options
config.extraPlugins = 'divarea,clipboard';
config.removePlugins = 'elementspath';
// Custom toolbar definition
config.toolbar_custom = [
['Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'SelectAll', 'RemoveFormat'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', '-', 'Smiley', 'SpecialChar']
];
config.toolbar = "custom";
console.log('end')
};
portal-ext.properties:
editor.wysiwyg.default=ckeditor
editor.wysiwyg.portal-impl.portlet.ddm.text_html.ftl=ckeditor
editor.wysiwyg.portal-web.docroot.html.portlet.announcements.edit_entry.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.portlet.blogs.edit_entry.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.portlet.mail.edit.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.portlet.mail.edit_message.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.portlet.message_boards.edit_message.html.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.taglib.ui.discussion.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.taglib.ui.email_notification_settings.jsp=ckeditor
editor.wysiwyg.portal-web.docroot.html.jsp=ckeditor
So my config is overrided correctly in /o/frontend-editor-ckeditor-web/ckeditor/config.js. It seems like liferay reads it, but then something else is overriding it. I don't have any other Contributors or implementations that could interfere with CKEditor. I have also tried adding another config like toolbar_custom and setting config.toolbar to custom, override default config of config.toolbar_simple but all the time config.toolbar keeps being overrided to "simple" and my config.toolbar_simple is being overrided as well. Do you guys have any idea how to solve it? I will be very thankful for any help.
Upvotes: 0
Views: 338