New Plugin (Link) at CKEditor - ckeditor

today i want to add a new plugin in our CKEDITOR of our PIM System.
Therefore i load the "Link" Plugin from CKEEditor.
First step - i include the plugin to my CKE-Installation under the following path:
ckeditor\js\ckeditor\plugins\link
After that i try to change my "ckeeditor.Config.js"
It looks like the following config:
var CKEDITOR_CONFIGS = (function() {
var module = {};
var configs = {
'default': {
toolbar: [
[ 'Cut','Copy','Paste','PasteText','PasteFromWord','Undo','Redo'],
['NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv',
'-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
['Link','Unlink','Anchor'],
['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar'],
['Bold','Italic','Underline','Strike','Subscript','Superscript',
'Source','Save','NewPage','DocProps','Preview', 'Print','-','Templates',
'SpellChecker', 'Find','Replace','-','SelectAll','-','Scayt'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton',
'HiddenField'],
['RemoveFormat','-','BidiLtr','BidiRtl'],
['PageBreak','Iframe','Styles','Format','Font','FontSize', 'TextColor','BGColor',
'Maximize', 'ShowBlocks','-','About']
]
}
};
module.getConfiguration = function(args) {
return configs['default'];
};
return module;
}());
By reading some posts i found out that i have to add the following code to the config data
config.extraPlugins = 'link';
Can someone tell my wherer i have to add the "config.extraPlugins ='link';
I have already tried out many places in the code, but without any success.
Have someone the same problems? Have i overlooked something?
Thanks in advance
Tim

Directly in your config.js configuration can be. Modify this code:
CKEDITOR.editorConfig = function (config)
You less a parameter, plus this parameter and then configure:
Config.extraPlugins = 'link'
I also have a custom plug-in, is this done.

Related

How to import/use ckeditor 5 from online-builder in Vue 3?

I create custom ckeditor 5 build in https://ckeditor.com/ckeditor-5/online-builder/ (based on "decoupled component" type), at the end i download zip with files. But what I am supposed to do next how to import it in main.js / package.js and finnaly to component ?
All materials I was able to find are https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html , got decoupled-document preset build working, but wanted to add image resize, so created custom build and am stuck at that point.
Tnx for any response.
This post is maybe longer but its super easy 5min done.
[2022 updated, still works, just config moved in another file, also people may return there because of higher Vue version ckeditor5 toolbar disappear and update/reinstall is needed]
This example is for full document type of ckeditor 5, decoupled-document is almost everything You need, just it lacks image-resize, to add it go to https://ckeditor.com/ckeditor-5/online-builder/ click it all way and add image-resize or all other fun stuff (You do not need premium Ckfinder, but You probably need CKFinder upload adapter for images uplad which is free), and download zip file, do not forget to pick same type in step 1 as one you will use/install.
Install (like in classic guide - https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs-v3.html)
npm install --save #ckeditor/ckeditor5-vue #ckeditor/ckeditor5-build-decoupled-document
(if here because of re-install, just remove package.json #ckeditor lines and run above install command again)
In main.js
import CKEditor from '#ckeditor/ckeditor5-vue';
createApp(App)
.use(router)
.use(CKEditor)
.mount("#app");
In your component
import DocumentEditor from '#ckeditor/ckeditor5-build-decoupled-document';
Now add config to data, You can find this config generated inside files you got from online-builder generator its copy/paste so do not freak out :) . You can find it in /src/ckeditor.js in defaultConfig, if you do not set it its possible You'll see an warning about missing "toolbar" options. Do not copy what you see below, use your custom generated config, its only for illustration :
data: function () {
return{
editorConfig: {
ckfinder: {
uploadUrl: 'https://page.com/api/uploadckeditor'
},
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'link',
'bulletedList',
'numberedList',
'|',
'outdent',
'indent',
'|',
'imageUpload',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'alignment',
'codeBlock',
'fontBackgroundColor',
'fontColor',
'fontFamily',
'fontSize',
'highlight',
'horizontalLine',
'htmlEmbed',
'imageInsert',
'pageBreak',
'removeFormat',
'strikethrough',
'underline',
'style'
]
},
language: 'cs',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:side',
'imageStyle:alignLeft',
'imageStyle:alignRight',
'imageStyle:alignCenter',
'imageStyle:alignBlockLeft',
'imageStyle:alignBlockRight',
'linkImage'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
fontFamily: {
options: [
'default',
'indieflowerregular',
'Arial, sans-serif',
'Verdana, sans-serif',
'Trebuchet MS',
'Apple Color Emoji',
'Segoe UI Emoji',
'Segoe UI Symbol',
]
},
licenseKey: ''
}
};
}
Now use it in component html
<ckeditor :editor="editor" #ready="onReady" v-model="editorData" :config="editorConfig"></ckeditor>
Decoupled component ckeditor package need #ready="onReady" othervise it will not initialize (classic do not need this)
here is method :
methods: {
onReady( editor ) {
// Insert the toolbar before the editable area.
editor.ui.getEditableElement().parentElement.insertBefore(
editor.ui.view.toolbar.element,
editor.ui.getEditableElement()
);
},
Ok now You have almost everything done just last magic thing to do .
In files you downloaded go to /build folder and COPY all the files into
"node_modules#ckeditor\ckeditor5-build-decoupled-document\build" and override initial decoupled-document. This is key thing to do, even thought it sounds pretty horrible.
Bonus : I wanted to have also image upload so added to config
**ckfinder: {
uploadUrl: 'http://mypage/api/uploadckeditor'
},**
Here is php side implementation its just basic one wit no error handling
$uploaddir = '../www/adminUpload/';
$uploadfile = $uploaddir . basename($_FILES['upload']['name']);
if (move_uploaded_file($_FILES['upload']['tmp_name'], $uploadfile)) {
//$this->sendJson(array("message"=>"sucess"));
} else {
//$this->sendJson(array("message"=>"failed"));
}
$returnArray = array();
$returnArray["uploaded"] = true;
$returnArray["url"] = "http://www.mypage.com/adminUpload/".$_FILES['upload']['name'];
header('Content-type: application/json');
$this->sendJson($returnArray);
$this->terminate();
For last 2 rows they are Nette php framework specific, just send out $returnArray as json response.
Here is how I integrated CKEDITOR with Vue3.js
Install required packages
npm install --save #ckeditor/ckeditor5-vue #ckeditor/ckeditor5-build-classic
main.ts
import CKEditor from '#ckeditor/ckeditor5-vue'
const app = createApp(App)
app.use( CKEditor ).mount('#app')
Then in your component where you wnat to use ckeditor
<template>
<ckeditor :editor="editor" v-model="data.description"></ckeditor>
</template>
<script>
import {onMounted, reactive, computed} from "vue"
import ClassicEditor from '#ckeditor/ckeditor5-build-classic'
export default{
name:'Add',
setup() {
//....
const data = reactive({
description: '',
})
return {
data,
editor: ClassicEditor
}
}
}
</script>
enter code here
I faced a problem image uploading inside ckeditor5-build-classic,
for image uploading I'm using Node.js server and S3, here is how returned the json response from Node.js server, uploaded flag is more important:
exports.upload_file_ckeditor = async(req, res) => {
let obj = {
"uploaded" : true,
"url" : 'http://example.com/upload/xyz.png'
}
return res.send(obj)
}

Creating a custom plugin for CKEDITOR 5 in an angular application, throws TypeError: Cannot read property '0' of undefined

I am trying to add a custom plugin to add to the ckeditor5-build-decoupled-document editor.
When I add my custom plugin to the ckeditor5-build-decoupled-document build code and then running npm run build. But I get the error TypeError: Cannot read property '0' of undefined when I add the ckeditor.js build file to my angular project.
The editor toolbar is no longer displayed on the screen and I cannot edit the text, however, the plugin seems to be performing its purpose of allowing inline style in the editor.
I have 2 questions:
Have I created the plugin correctly?
Is there something missing from my configuration within my Angular project?
These are the steps I followed and the code used
Created Plugin
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
export default class Extension extends Plugin {
constructor( editor ) {
super( editor );
}
init() {
const editor = this.editor;
let allowedAttributes = [
'width', 'height', 'style', 'stylex', 'target', 'class', 'id', 'name', 'title', 'type', 'olddisplay', 'text-align', 'align',
'border', 'cellspacing','padding', 'cellpadding', 'color', 'valign', 'clear', 'src', 'shapes', '&amp',
'prefix', 'tagtype', 'datetime', 'cite', 'cols', 'colspan', 'noshade', 'text-decoration',
'shape', 'start', 'alt', 'strong', 'files', 'hr', 'font-size',
'com', 'background-color', 'rowspan', 'span', 'page', 'content',
'action', 'value', 'autofocus', 'maxlength', 'rows', 'for', 'aria-label', 'checked', 'selected',
'rel', 'scope', 'location', 'cellpacing', 'block-id', 'lang',
'original-style', 'datatype', 'property', 'controls', 'controlslist', 'data-attr', 'poster', 'preload',
'tabindex', 'role', 'aria-describedby', 'aria-disabled','aria-haspopup',
'href', 'col', 'doc', 'attach', 'pls', 'vspace', 'hspace', 'slatepath'];
//creates a new schema to to keep preexisting styles
editor.model.schema.extend('$root', { allowAttributes: allowedAttributes });
editor.model.schema.extend('$block', { allowAttributes: allowedAttributes });
editor.model.schema.extend('$text', { allowAttributes: allowedAttributes });
for (var i = 0; i < allowedAttributes.length; i++) {
editor.conversion.attributeToAttribute({ model: this.allowedAttributes[i], view: this.allowedAttributes[i] });
}
editor.model.schema.extend('paragraph', { allowAttributes: '__style' });
editor.conversion.for('upcast').attributeToAttribute({
model: {
key: '__style',
name: 'paragraph'
},
view: 'style'
});
editor.conversion.for('downcast').add(dispatcher => {
dispatcher.on('attribute:__style:paragraph', (evt, data, conversionApi) => {
conversionApi.consumable.consume(data.item, evt.name);
const viewElement = conversionApi.mapper.toViewElement(data.item);
conversionApi.writer.setAttribute('style', data.attributeNewValue, viewElement);
});
});
}
}
I then added the plugin to the ckeditor.js file
import Extension from "../ckeditor5-extension/src/extension.js";
DecoupledEditor.builtinPlugins = [
*
*
PasteFromOffice,
Table,
TableToolbar,
Extension
];
Following this, I run npm run build which generates the ckeditor.js in the build folder.
Next, I copied the ckeditor.js (and corresponding translation files )from the build folder into the assets folder of my angular project.
Then add my custom editor to my file.
import * as CustomEditor from 'src/assets/ckeditor.js';
public Editor = CustomEditor;
In the tsconfig.json
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowJs": true,
"importHelpers": true,
"target": "es2015",
"typeRoots": [
"node_modules/#types"
],
"lib": [
"es2018",
"dom"
]
}
In the console when I print out the plugins for the editor my custom plugin is showing undefined.
["Essentials", "Alignment", "FontSize", "FontFamily", "Highlight", "CKFinderUploadAdapter", "Autoformat", "Bold", "Italic", "Strikethrough", "Underline", "BlockQuote", "CKFinder", "EasyImage", "Heading", "Image", "ImageCaption", "ImageStyle", "ImageToolbar", "ImageUpload", "Link", "List", "MediaEmbed", "Paragraph", "PasteFromOffice", "Table", "TableToolbar", undefined]
So the issue was caused not by any angular / Ckeditor5 integrations but rather a simple mistake in the code.
I originally built the code in Angular when I was familiarizing myself with the process of creating a PLUGIN and transferred the code from my angular app to the cloned repo to create my custom plugin.
The error was a simple reference error.
The line
editor.conversion.attributeToAttribute({ model: this.allowedAttributes[i], view: this.allowedAttributes[i] });
Should have been
editor.conversion.attributeToAttribute({ model: allowedAttributes[i], view: allowedAttributes[i] });
Minus this. reference.
For anyone creating a custom plugin, when you build the plugin there is a sample editor in the repo, that will allow you to test your code with the latest changes. You can make sure the code works before transferring to the Angular app, allowing you to rule out any integration issues with your custom plugin and the Angular app.
I think you need to add pluginName:
export default class Extension extends Plugin {
constructor( editor ) {
super( editor );
}
static get pluginName() {
return 'Extension';
}
init() { ...

ag-grid does not work properly with angular 1.x

I am trying to use ag-grid for one of my project work and was trying to configure it with webpack & Angular 1.6
i have configured it as follow
Module
var agGrid = require('ag-grid');
agGrid.initialiseAgGridWithAngular1(angular);
module.exports = angular.module('transModule', ['agGrid'])
.component('transComponent', transComponent)
.name;
Controller
var columnDefs = [
{headerName: "Make", field: "make"},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
var rowData = [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
$scope.gridOptions = {
columnDefs: columnDefs,
rowData: rowData
};
html
<div ag-grid="gridOptions" class="ag-fresh" style="height: 100%;"></div>
but when i use i, it displays as follow
then i tried adding the stylesheets as follow
require('ag-grid/dist/styles/ag-grid.css');
require('ag-grid/dist/styles/theme-fresh.css');
yet again it the table want render properly and it will show as follow
is there anything um missing?? I would much appreciate if you could give me some headsup??
I noticed in ag-grid's package.json it was referenced main.js as entry point, and I actually found the whole lib folder content loaded in the Source tab of Chrome DevTools.
This was due to the way I was requiring ag-grid:
var agGrid = require('ag-grid');
// get ag-Grid to create an Angular module and register the ag-Grid directive
agGrid.initialiseAgGridWithAngular1(angular);
var myApp = 'myApp';
module.exports = myApp;
angular
.module(myApp, [
'agGrid'
])
Even if the "get-started" docs don't list a Webpack based solution, they do say to include the dist/ag-grid.js file or one of the minified/noStyle versions, so I changed the first line like this:
var agGrid = require('ag-grid/dist/ag-grid.min.js');

Configurable redirect URL in DocPad

I'm using DocPad to generate system documentation. I am including release notes in the format
http://example.com/releases/1.0
http://example.com/releases/1.1
http://example.com/releases/1.2
http://example.com/releases/1.3
I want to include a link which will redirect to the most recent release.
http://example.com/releases/latest
My question: how do I make a link that will redirect to a relative URL based on configuration? I want this to be easily changeable by a non-programmer.
Update: I've added cleanurls into my docpad.js, similar to example below. (see code below). But using "grunt docpad:generate" seems to skip making the redirect (is this an HTML page?). I've a static site. I also confirmed I'm using the latest cleanurls (2.8.1) in my package.json.
Here's my docpad.js
'use strict';
var releases = require('./releases.json'); // list them as a list, backwards: ["1.3", "1.2", "1.1", "1.0"]
var latestRelease = releases.slice(1,2)[0];
module.exports = {
outPath: 'epicenter/docs/',
templateData: {
site: {
swiftype: {
apiKey: 'XXXX',
resultsUrl: '/epicenter/docs/search.html'
},
ga: 'XXXX'
},
},
collections: {
public: function () {
return this.getCollection('documents').findAll({
relativeOutDirPath: /public.*/, isPage: true
});
}
},
plugins: {
cleanurls: {
simpleRedirects: {'/public/releases/latest': '/public/releases/' + latestRelease}
},
lunr: {
resultsTemplate: 'src/partials/teaser.html.eco',
indexes: {
myIndex: {
collection: 'public',
indexFields: [{
name: 'title',
boost: 10
}, {
name: 'body',
boost: 1
}]
}
}
}
}
};
When I run grunt docpad:generate, my pages get generated, but there is an error near the end:
/data/jenkins/workspace/stage-epicenter-docs/docs/docpad/node_modules/docpad-plugin-cleanurls/node_modules/taskgroup/node_modules/ambi/es6/lib/ambi.js:5
export default function ambi (method, ...args) {
^^^^^^
I can't tell if that's the issue preventing this from running but it seems suspicious.
Providing that your configuration is available to the DocPad Configuration File, you can use the redirect abilities of the cleanurls plugin to accomplish this for both dynamic and static environments.
With a docpad.coffee configuration file, it would look something like this:
releases = require('./releases.json') # ['1.0', '1.1', '1.2', '1.3']
latestRelease = releases.slice(-1)[0]
docpadConfig =
plugins:
cleanurls:
simpleRedirects:
'/releases/latest': '/releases/' + latestRelease
module.exports = docpadConfig

Integrating filebrowser plugin and CKEditor 4.3 standard

I am struggling with this integration. Any help greatly appreciated.
I want to have the file browser option only on the link tab of the image dialog. In addition, I want it to default to a specific folder.
I've downloaded both filebrowser and popup plugins (4.3 standard did not list them in the plugins folder) and modified config.js with:
// enable plugin
config.extraPlugins = 'filebrowser';
config.extraPlugins = 'popup';
I call the CK instance from an include(contentEditor.js)
var config3 = {
toolbar:
[
[ 'Paste', 'PasteFromWord', '-', 'Bold', 'Italic', 'Underline', '-', 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Source' , 'Templates', 'Link', 'Image' ]
],
uiColor: "#dafb3f",
height: "570px",
resize_enabled: false,
extraPlugins:'templates,filebrowser,popup',
on: { change: CKonChange }
};
// Initialize the editor.
// Callback function can be passed and executed after full instance creation.
$( 'textarea#nodeContents' ).ckeditor(config3); // nodeContents for city,state,country,resources editors
});
Now, I'm lost. How do I activate the browser button and pass the image path back to the instance?
1/28 UPDATE
As I could not find any documentation on how to integrate filebrowser plugin, I am looking at integrating a custom browse script.
So, in my config.js fle, I've got:
// Custom template files referenced in this array
config.templates_files = [ 'http://dev.wtpcentral.com/js/CK_templates_city.js' ];
// Image browser
config.filebrowserImageBrowseLinkUrl : "/include/filebrowser/browse.php?type=Images&dir="+encodeURIComponent('content/images');
// config.filebrowserImageBrowseUrl : "/include/filebrowser/browse.php?type=Images&dir="+encodeURIComponent('content/images');
// Custom Image upload
config.filebrowserUploadUrl ='/include/classUpload/upload_CK.php';
// enable plugin
// config.extraPlugins = 'filebrowser,popup';
And, I put browse.php into my /include/filebrowser folder.
BUT, this throws an error:
SyntaxError: invalid label config.filebrowserImageBrowseUrl : "/include/filebrowser/browse.php
AND my custom image upload script now does not load.
As you might see in my inline notes, I tried config.filebrowserImageBrowseUrl with the same results.
Any help greatly appreciated.
In this case you must use "=" instead of ":". Change this line
config.filebrowserImageBrowseLinkUrl: "/include/filebrowser/browse.php?type=Images&dir="+encodeURIComponent('content/images');
to
config.filebrowserImageBrowseLinkUrl = "/include/filebrowser/browse.php?type=Images&dir="+encodeURIComponent('content/images');

Resources