Laravel Vue.js integration with CKeditor 4 and CKFinder3 (file manager) - laravel-5

I have some problems with integration CKeditor 4 and CKFinder 3 in My Laravel Vue app.
I just want the functionality when I click on "image button" in my Ckeditor - CKFinder window appears and I'm able to upload all needed images.
What problems I have? (a few, but they must be related with each other):
I have that error in my devtools console: "[CKEDITOR] Error code: cloudservices-no-token-url." (I'm supposing that issue must be resolved when I properly integrate CKeditor with CKFinder)
(as WARN in devtools) - " [CKEDITOR] Error code: editor-plugin-conflict. {plugin: "image", replacedWith: "easyimage"} "
"Image Button" in my CKeditor disappeared (ckeck screenshot below):
You can see my Vue component code with config for ckeditor:
...
export default {
components: { VueCkeditor },
data() {
return {
content: '',
config: {
toolbar: [
{ name: 'styles', items : [ 'Styles','Format', 'FontSize' ] },
{ name: 'clipboard', items : ['Undo','Redo' ] },
{ name: 'editing', items : [ 'Scayt' ] },
{ name: 'insert', items : [ 'Image','Table','HorizontalRule','SpecialChar','Iframe' ] },
{ name: 'tools', items : [ 'Maximize' ] },
'/',
{ name: 'basicstyles', items : [ 'Bold','Italic','Strike','RemoveFormat' ] },
{ name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote' ] },
{ name: 'links', items : [ 'Link','Unlink','Anchor' ] },
],
height: 400,
extraPlugins: 'autogrow,uploadimage',
filebrowserBrowseUrl: '/filemanager_storage?type=Files',
filebrowserUploadUrl: '/filemanager_storage/upload?type=Files&_token='+window.Laravel.csrfToken,
},
};
},
...
Other details which may be useful:
I use CKFinder 3 Package for Laravel 5.5+ (https://github.com/ckfinder/ckfinder-laravel-package)
In my ckfinder.php (configurations for CKFinder) I set temporally that code:
$config['authentication'] = function () {
return true;
};
I'm not sure in that paths (in my config object in vue):
filebrowserBrowseUrl: '/filemanager_storage?type=Files',
filebrowserUploadUrl: '/filemanager_storage/upload?type=Files&_token='+window.Laravel.csrfToken,
},
*I created 'filemanager_storage' directory in my 'public' directory
Thanks guys a lot for any help!

I was facing similar issues regarding a ckeditor4.x integration I did recently in an opencart site with php. While it's not the same environment with vue, maybe this could prove useful to you.
Instead of using the easyimage plugin for managing the image upload , I replaced it with the image2 (enhanced image plugin) . After you've downloaded the image2 plugin and placed it under the ckeditor4/plugins/ directory, make sure to add this in your ckeditor instance:
extraPlugins : 'image2',
removePlugins: 'easyimage,cloudservices'
Regarding the urls in the ckeditor instance, while I'm not using the filebrowserBrowseUrl , I've declared the filebrowserUploadUrl as such :
filebrowserUploadUrl: '/path_where_ckfinder_is_installed/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json
While in my case it made the image upload possible, I'm still getting the warning [CKEDITOR] Error code: editor-plugin-conflict. {plugin: "image", replacedWith: "image2"} " This is something that I haven't been able to solve yet, but at least the image upload works in my case with no fuss.
Also, make sure in the config.php of ckfinder that you've declared the BaseUrl and root path for the user files directory, i.e
$config['backends'][] = array(
'name' => 'default',
'adapter' => 'local',
'baseUrl' => $your_file_path,
'root' => '/your_root_dir/' . $your_file_path, // Can be used to explicitly set the CKFinder user files directory.
'chmodFiles' => 0777,
'chmodFolders' => 0755,
'filesystemEncoding' => 'UTF-8'
);
Let me know if this solution suits your case.

Related

vuepress local search not showing up [version 2.0.0-beta.22]

I am new to vueppress.
I followed the docs here to create a documentation site. things went well but the search field/input didn't show up. I tried to follow the plugin installation docs here but I got:
I need to install #vuepress/shared-utils
after that I had to install #vue/component-compiler-utils too
but was unable to see the search input. I also tried to add the following to my ./docs/.vuepress/config.ts but still no luck.
plugins: [
[
'#vuepress/plugin-search',
{
searchMaxSuggestions: 10
}
],
]
I don't want to use Algoia search as this is internal documentation.
I had the same issue. Everything was working except the search box was not visible.
The issue was that my ...docs/.vuepress/config.ts was not structured properly. To fix it I followed exactly what the VuePress documentation instructed.
The working config.ts structure
import { defaultTheme } from '#vuepress/theme-default'
import { searchPlugin } from '#vuepress/plugin-search'
module.exports = {
theme: defaultTheme({
...
}),
plugins: [
searchPlugin({
...
})
]
}
Currently I am using VuePress v2.0.0-beta.45
and I used the following to install what I needed:
npm i -D #vuepress/plugin-search#next
npm i -D #vuepress/plugin-register-components#next
Detailed config.ts that is working for me
import { path } from '#vuepress/utils'
import { defaultTheme } from '#vuepress/theme-default'
// Plugins
import { searchPlugin } from '#vuepress/plugin-search'
import { registerComponentsPlugin } from '#vuepress/plugin-register-components'
import navBarItems from './public/navbar'
import sideBar from './public/sidebar'
// SEE: https://v2.vuepress.vuejs.org/reference/default-theme/config.html#config
module.exports = {
// Site Config: https://v2.vuepress.vuejs.org/reference/config.html#site-config
lang: 'en-US',
title: 'Title on Tab and Navbar',
description: '',
// https://v2.vuepress.vuejs.org/reference/default-theme/config.html
theme: defaultTheme({
logo: 'logo-light.png',
logoDark: 'logo-dark.png',
//https://v2.vuepress.vuejs.org/reference/default-theme/config.html#navbar
navbar: navBarItems,
// https://v2.vuepress.vuejs.org/reference/default-theme/config.html#sidebar
sidebar: sideBar
}),
plugins: [
// https://v2.vuepress.vuejs.org/reference/plugin/register-components.html
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components')
}),
// https://v2.vuepress.vuejs.org/reference/plugin/search.html#search
searchPlugin({
// getExtraFields: (page) => page.frontmatter.tags,
maxSuggestions: 15,
hotKeys: ['s', '/'],
locales: {
'/': {
placeholder: 'Search',
}
}
})
],
}
Note that I keep my sidebar array and navbar object in different files.
Also I couldn't find any TypeScript reference for the config in VuePress 2x

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)
}

CKEditor not showing with easyadmin integration

I created a new Symfony4 project and installed EasyAdmin bundle (which works fine).
I tried to integrate CKeditor following the documentation : https://symfony.com/doc/master/bundles/EasyAdminBundle/integration/ivoryckeditorbundle.html
Here is my easyadmin.yaml:
easy_admin:
entities:
TestPage:
class: App\Entity\TestPage
form:
fields:
- { property: 'content', type: 'fos_ckeditor', type_options: { 'config': { 'toolbar': [ { name: 'styles', items: ['Bold', 'Italic', 'BulletedList', 'Link'] } ] } }}
here my fos_ckeditor.yaml :
twig:
form_themes:
- '#FOSCKEditor/Form/ckeditor_widget.html.twig'
fos_ck_editor:
input_sync: true
default_config: base_config
configs:
base_config:
toolbar:
- { name: "styles", items: ['Bold', 'Italic', 'BulletedList', 'Link'] }
The problem is it's still the regular textarea that is showing, not the ckeditor rich text one.
I tried to clear the cache, to add "- '#FOSCKEditor/Form/ckeditor_widget.html.twig'" in twig.yaml but i still can't see the ckeditor toolbar.
Anyone has an idea on what i'm missing ?
Thanks!
vkhramtsov on git has just advised me to add the "#FOSCKEditor/Form/ckeditor_widget.html.twig" form theme to "easyadmin:design: form_theme:list" in "config/packages/easy_admin.yaml" like this:
easy_admin:
design:
form_theme: # Both themes are needed for ckeditor integration
- "#EasyAdmin/form/bootstrap_4.html.twig"
- "#FOSCKEditor/Form/ckeditor_widget.html.twig"
This solved the problem for me. I think the docs need to be updated. The place they suggest to put the form template presently (twig:form_themes) does not work.

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() { ...

GatsbyJS/GraphQL won't connect to Drupal

I have tried following numerous tutorials on connecting Drupal, and GatsbyJS. For instance, in this article, I get to step 4.3b, "Pull Content from the Drupal 8 site using GraphQL" before everything fails.
I have followed every instruction, but GraphQL seems to be pulling from the temporary Gatsby page rather than the Drupal site I made. Queries such as "allNodeBlog" don't exist, and I'm not sure how to fix everything so I can get to pulling information from my Drupal JSON API page rather than the Gatsby site.
Any help/advice would be great. And/or articles that aren't simply the first Googled "Drupal and Gatsby" help sites (as I've looked at them all).
module.exports = {
siteMetadata: {
title: 'Gatsby Default Starter',
},
plugins: [
'gatsby-plugin-react-helmet',
{
resolve: 'gatsby-source-drupal',
options: {
baseUrl: 'http://gatsbydrupal.dd:8083/',
apiBase: 'api', // endpoint of Drupal server
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: 'gatsby-starter-default',
short_name: 'starter',
start_url: '/',
background_color: '#663399',
theme_color: '#663399',
display: 'minimal-ui',
icon: 'src/images/gatsby-icon.png', // This path is relative to the root of the site.
},
},
'gatsby-plugin-offline',
],
}

Resources