Coder Social home page Coder Social logo

nshenderov / strapi-plugin-ckeditor Goto Github PK

View Code? Open in Web Editor NEW
80.0 2.0 48.0 12.82 MB

Integrates CKEditor 5 into your Strapi project as a fully customizable custom field. (Unofficial integration)

Home Page: https://www.npmjs.com/package/@_sh/strapi-plugin-ckeditor

License: MIT License

JavaScript 100.00%
ckeditor ckeditor5 strapi strapi-cms strapi-plugin wysiwyg wysiwyg-html-editor

strapi-plugin-ckeditor's Introduction

CKEditor 5 for Strapi

Integrates CKEditor 5 into your Strapi project as a fully customizable custom field. (Unofficial integration)

๐Ÿ‘‹ Get Started

โœจ Features

  • Media library integration
  • Supports responsive images
  • Supports Strapi's theme switching with the ability to set a custom theme
  • Supports i18n and different UI translations
  • Few predefined editor configs with the ability to add custom ones
  • Possible to add new plugins

๐Ÿ”ง Installation


  • Inside your Strapi app, add the package:
npm install @_sh/strapi-plugin-ckeditor

or

yarn add @_sh/strapi-plugin-ckeditor
  • Then run build:
npm run build

or

yarn build

โš™๏ธ Configuration


The plugin uses Strapi custom fields API and CKEditor dll build

The plugin configuration should be defined in the /config/ckeditor.txt file.

It's highly recommended to explore the official ckeditor documentation

Content of ckeditor.txt will be passed into the script tag during the initialization process.

๐Ÿ“‚ Default configs: admin/src/components/Input/CKEditor/configs

๐Ÿ“‚ Default theme: admin/src/components/Input/CKEditor/theme

ckeditor.txt example:

globalThis.CKEditorConfig = {

    /* By default custom configs and theme
    defined in this file are going to be spread into
    default configs and theme these two properties below
    allow you to redefine default objects completely: */

    //configsOverwrite:true,
    //themeOverwrite:true,

    /* Here you can redefine default configs
    or add completely new ones.
    Each config includes: 
    "styles", "field" and "editorConfig" properties.
    Property "field" is required. */

    configs:{
        toolbar:{
            // styles:``,
            // field:{},
            // editorConfig:{}
        },
        custom:{
            
            /* Styles for this specific editor version.
            This will be passed into the editor's parent container. */

            styles:`
            //     --ck-focus-ring:3px dashed #5CB176;

            //     .ck.ck-content.ck-editor__editable {
            //       &.ck-focused:not(.ck-editor__nested-editable) {
            //         border: var(--ck-focus-ring) !important;
            //       }
            //     }
            //     .ck.ck-content.ck-editor__editable.ck-rounded-corners.ck-editor__editable_inline.ck-blurred{
            //       min-height: 400px;
            //       max-height: 400px;
            //     }
            //     .ck.ck-content.ck-editor__editable.ck-rounded-corners.ck-editor__editable_inline.ck-focused{
            //       min-height: 400px;
            //       max-height: 1700px;
            //     }
            `,

            /* Custom field option */
            field: {
                key: "custom",
                value: "custom",
                metadatas: {
                  intlLabel: {
                    id: "ckeditor5.preset.custom.label",
                    defaultMessage: "Custom version",
                  },
                },
            },
            /* CKEditor configuration */
            editorConfig:{
                /* You can find all available built-in plugins
                in the admin/src/components/Input/CKEditor/configs/base.js */
                plugins: [
                    CKEditor5.autoformat.Autoformat,
                    CKEditor5.basicStyles.Bold,
                    CKEditor5.basicStyles.Italic,
                    CKEditor5.essentials.Essentials,
                    CKEditor5.heading.Heading,
                    CKEditor5.image.Image,
                    CKEditor5.image.ImageCaption,
                    CKEditor5.image.ImageStyle,
                    CKEditor5.image.ImageToolbar,
                    CKEditor5.image.ImageUpload,
                    CKEditor5.indent.Indent,
                    CKEditor5.link.Link,
                    CKEditor5.list.List,
                    CKEditor5.paragraph.Paragraph,
                    CKEditor5.pasteFromOffice.PasteFromOffice,
                    CKEditor5.table.Table,
                    CKEditor5.table.TableToolbar,
                    CKEditor5.table.TableColumnResize,
                    CKEditor5.table.TableCaption,
                    CKEditor5.strapiPlugins.StrapiMediaLib,
                    CKEditor5.strapiPlugins.StrapiUploadAdapter,
                  ],

                  /* By default, the language of the plugin's UI will be chosen
                  based on the language defined in this config file
                  or on the preferred language from the strapi's user config
                  and if both of them are not set then 'en' will be used as a fallback.
                  ( language.ui -> preferred language -> 'en' ) */

                  /* For content it will chose the language based on i18n (if! ignorei18n)
                  or on language.content property defined here
                  and it will use UI language as a fallback.
                  ignorei18n ? language.content : i18n; -> language.ui */

                  language:{
                    // ignorei18n: true,
                    // ui:'he',
                    // content:'he'
                  },
                  toolbar: [
                    'heading',
                    '|',
                    'bold', 'italic', 'link', 'bulletedList', 'numberedList',
                    '|',
                    'strapiMediaLib', 'insertTable',
                    '|',
                    'undo', 'redo'
                  ],
                  heading: {
                    options: [
                      { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
                      { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
                      { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
                      { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
                      { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },
                    ]
                  },
                  image: {
                    toolbar: [
                      'imageStyle:inline',
                      'imageStyle:block',
                      'imageStyle:side',
                      '|',
                      'toggleImageCaption',
                      'imageTextAlternative'
                    ]
                  },
                  table: {
                    contentToolbar: [
                      'tableColumn',
                      'tableRow',
                      'mergeTableCells',
                      '|',
                      'toggleTableCaption'
                    ]
                  }
            }
        }
    },

    /* Here you can customize the plugin's theme.
    This will be passed as "createGlobalStyle". */
    theme:{
        // common:``,
        // light:``,
        // dark:``,
        // additional:``
    }

}

If you use the default (local) upload provider you should specify the url property in the config/server.js in order to get the full URL on uploaded files eg:

module.exports = ({ env }) => ({
  url: env("PUBLIC_URL", "http://localhost:1337"),
  host: env('HOST', '0.0.0.0'),
  port: env.int('PORT', 1337),
  app: {
    keys: env.array('APP_KEYS'),
  },
});

In order to display a content from an external source in your admin you should configure your middlewares.js check the docs about this

How to add plugins


Markdown plugin example

  • Inside your app:
yarn add @ckeditor/ckeditor5-markdown-gfm

or

npm install @ckeditor/ckeditor5-markdown-gfm
  • your-app/src/admin/app.js
import ckeditor5Dll from "ckeditor5/build/ckeditor5-dll.js";
import ckeditor5MrkdownDll from "@ckeditor/ckeditor5-markdown-gfm/build/markdown-gfm.js";


const config = {};

const bootstrap = (app) => {};

export default {
  config,
  bootstrap,
};
  • your-app/config/ckeditor.txt
globalThis.CKEditorConfig = {
    configs:{
        markdown:{
            field: {
                key: "markdown",
                value: "markdown",
                metadatas: {
                  intlLabel: {
                    id: "ckeditor.preset.markdown.label",
                    defaultMessage: "Markdown version",
                  },
                },
            },
            editorConfig:{
                placeholder: 'Markdown editor',
                plugins: [
                    CKEditor5.essentials.Essentials,
                    CKEditor5.autoformat.Autoformat,
                    CKEditor5.blockQuote.BlockQuote,
                    CKEditor5.basicStyles.Bold,
                    CKEditor5.heading.Heading,
                    CKEditor5.image.Image,
                    CKEditor5.image.ImageCaption,
                    CKEditor5.image.ImageStyle,
                    CKEditor5.image.ImageToolbar,
                    CKEditor5.image.ImageUpload, 
                    CKEditor5.indent.Indent,
                    CKEditor5.basicStyles.Italic,
                    CKEditor5.link.Link,
                    CKEditor5.list.List,
                    CKEditor5.mediaEmbed.MediaEmbed,
                    CKEditor5.paragraph.Paragraph,
                    CKEditor5.table.Table,
                    CKEditor5.table.TableToolbar,
                    CKEditor5.sourceEditing.SourceEditing, 
                    CKEditor5.strapiPlugins.StrapiMediaLib,
                    CKEditor5.strapiPlugins.StrapiUploadAdapter,
                    CKEditor5.markdownGfm.Markdown,
                    CKEditor5.basicStyles.Code, 
                    CKEditor5.codeBlock.CodeBlock,
                    CKEditor5.list.TodoList,
                    CKEditor5.basicStyles.Strikethrough,
                    CKEditor5.horizontalLine.HorizontalLine
                ],
                toolbar: {
                    items: [
                        'heading',
                        '|',
                        'bold',
                        'italic',
                        'strikethrough',
                        'link',
                        '|',
                        'bulletedList',
                        'numberedList',
                        'todoList',
                        '|',
                        'code',
                        'codeBlock',
                        '|',
                        'uploadImage',
                        'strapiMediaLib',
                        'blockQuote',
                        'horizontalLine',
                        '-',
                        'sourceEditing',
                        '|',
                        'outdent',
                        'indent',
                        '|',
                        'undo',
                        'redo'
                    ],
                    shouldNotGroupWhenFull: true
                },
                image: {
                    toolbar: [ 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side', '|', 'toggleImageCaption', 'imageTextAlternative' ]
                },
                codeBlock: {
                    languages: [
                        { language: 'css', label: 'CSS' },
                        { language: 'html', label: 'HTML' },
                        { language: 'javascript', label: 'JavaScript' },
                        { language: 'php', label: 'PHP' }
                    ]
                },
            }
        }
    }
}
  • Then rebuild your app:
npm run build

or

yarn build

๐Ÿ›  Contributing


This section covers the way how to configure your environment if you want to contribute to this package.

Setting up the environment

In order to start making changes in the plugin you first need to install Strapi infrastructure on top of the plugin repository.

npx create-strapi-app --quickstart strapi
cd strapi

By default Strapi does not create plugins folder so we need to create it.

mkdir -p src/plugins

Now we should clone this repository so we can work on it.

git clone [email protected]:nshenderov/strapi-plugin-ckeditor.git src/plugins/strapi-plugin-ckeditor

Let's add an entry inside ./package.json file so, we won't need to use yarn inside plugin itself.

"workspaces": ["./src/plugins/strapi-plugin-ckeditor"]

Install dependencies:

yarn install

Now we need to register plugin so strapi can use it. In order to do that we need to create (if not already created) ./config/plugins.js file and add entry to it.

module.exports = ({ env }) => ({
  ckeditor5: {
    enabled: true,
    resolve: "./src/plugins/strapi-plugin-ckeditor"
  },
});

Rebuild the project and start the server:

yarn build
yarn develop

โš ๏ธ Requirements


Strapi v4.13.0+

Node >=18.0.0 <=20.x.x

strapi-plugin-ckeditor's People

Contributors

davidjasik avatar ddazal avatar emmarvpol avatar esgeh avatar ihmpavel avatar lamuertepeluda avatar lkho avatar marob avatar nshenderov avatar ovieokeh avatar timraasveld avatar vishalkanu01 avatar zadinvit avatar zonayedpca avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

strapi-plugin-ckeditor's Issues

Oembedly Plugin is Useful for Previews Only while editing; How-to disable this plugin?

In relation to #42

It is important to note, this plugin allows for PREVIEWING the embeded content, but the ` html attribute must be converted into proper HTML for the item to be displayed.

๐Ÿ˜“

This plugin is useless unless you either:

  1. Pay embedly or iframely money
  2. Program your own syntax to convert attributes into an <iframe> template formatting.

the HTML syntax used in Strapi CK5editor.

<figure class="media"><oembed url="https://www.youtube.com/watch?v=bX_Ihr0"></oembed></figure>

To display that syntax in HTML, we either use 1. a payed provider to convert it for us or 2. we program it our selves or 3. we require the author andor editor to copy / paste the video iframe directly from the website i.e. youtube.com.

The actual code that is needed to display the video.

<iframe width="560" height="315" src="https://www.youtube.com/embed/DvkQo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

How to disable this plugin?

How to lazyload images and change paths

It's a very nice plugin but my client has an image heavy website (photograph) so I would like to know if it's possible to change path for uploaded media ? Currently CKEditor ouputs the image with relative path so I'd like to be able to output this :

https://api.example.org + path

Also is it possible to lazyload images, at the very least add a loading="lazy" ?

Bug + Fix: Full Screen Source Mode Has No Scroll

Tested on FF 107.0 (64-bit)

  1. Open up editor with a large document that extends beyond the vertical screen.
  2. Goto Fullscreen
  3. Goto Source edit

Notice the Fullscreen + Source edit doesn't scroll.

Footnotes

Is it possible to add footnotes for the next release? This would really be a top feature addition.

The UI & Content Language (Does Not) change by default to the language defined in the user profile. (contradictory to Docs in this package)

It clearly says in the โœจ Features section of the README File in this package that it does support automatic UI and content selection based on the language defined in the strapi user profile, but it does not. it always defaults to English.

So is there any fix to this problem? I really need the automatic selection to work, because running a bilingual website requires content in two or more languages and some language are RTL some are LTR, so please consider fixing this issue and thanks.

NOTE: The CKEditor does not have a text direction option in the toolbar items options and I don't know why?? since you guys have the RTL Feature developed (coded) already when I hard code that the Language of content is ar (Arabic) in the config/plugins.js file in strapi?.
So why you don't just add a toolbar item button to change the direction on runtime while the end user is writing the content in CKEditor5 Editor?

because you have the scenario where The content is mixed between two languages (Arabic/English) for example.

   "@_sh/strapi-plugin-ckeditor": "^1.1.2",
    "@strapi/plugin-i18n": "4.4.1",
    "@strapi/plugin-users-permissions": "4.4.1",
    "@strapi/provider-upload-cloudinary": "^4.4.1",
    "@strapi/strapi": "4.4.1",
    "pg": "^8.6.0",
    "pg-connection-string": "^2.5.0"
   
     Node: 16.15.0

     Tried on both Dev and prod environments, error occurs on both.

installation error "path" argument undefined

Hi, I'm trying to install following the provided instructions.

yarn add @_sh/strapi-plugin-ckeditor

// config/plugins.js

module.exports = () => {
    return {
        ckeditor: true
    }
}

strapi dev

strapi:dev: cc_strapi             | [2022-05-21 22:18:14.292] debug: โ›”๏ธ Server wasn't able to start properly.
strapi:dev: cc_strapi             | [2022-05-21 22:18:14.293] error: The "path" argument must be of type string. Received undefined
strapi:dev: cc_strapi             | TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
strapi:dev: cc_strapi             |     at new NodeError (node:internal/errors:372:5)
strapi:dev: cc_strapi             |     at validateString (node:internal/validators:120:11)
strapi:dev: cc_strapi             |     at join (node:path:1172:7)
strapi:dev: cc_strapi             |     at Object.loadPlugins (/app/node_modules/@strapi/strapi/lib/core/loaders/plugins/index.js:89:34)
strapi:dev: cc_strapi             |     at async Strapi.loadPlugins (/app/node_modules/@strapi/strapi/lib/Strapi.js:284:5)
strapi:dev: cc_strapi             |     at async Promise.all (index 1)
strapi:dev: cc_strapi             |     at async Strapi.register (/app/node_modules/@strapi/strapi/lib/Strapi.js:316:5)
strapi:dev: cc_strapi             |     at async Strapi.load (/app/node_modules/@strapi/strapi/lib/Strapi.js:414:5)
strapi:dev: cc_strapi             |     at async Strapi.start (/app/node_modules/@strapi/strapi/lib/Strapi.js:163:9)
strapi:dev: cc_strapi exited with code 1

[strapi 4.3.3] It works normally in development mode, but an error occurs after build.

In strapi version 4.1.11, it worked well in any situation.

The version was upgraded to strapi 4.3.3 version. After that, it works fine in Develop mode, but if you proceed with the Start script after executing the Build command, the corresponding error occurs.

My environment is like this.

node version v16.15.1
"@_sh/strapi-plugin-ckeditor": "^1.1.2",
"@strapi/strapi": "4.3.3",
npm install 
npm run build
npm run start 

works fine

When I enter the Content Manager page, the editor doesn't work and throws that error.

Uncaught (in promise) TypeError: Property description must be an object: null
    at defineProperties (<anonymous>)
    at Ea._getConfig (main.8f200ec4.js:5:30318)
    at Ea.<anonymous> (main.8f200ec4.js:5:29268)
    at Generator.next (<anonymous>)
    at main.8f200ec4.js:1:644
    at new Promise (<anonymous>)
    at S0 (main.8f200ec4.js:1:464)
    at Ea._initializeEditor (main.8f200ec4.js:5:28866)
    at Ea.<anonymous> (main.8f200ec4.js:5:28553)
    at Generator.next (<anonymous>)

Isn't there some good way? I've tried to solve it on my own, but I can't seem to get it to work, so I'm asking for help.

Question, MediaEmbed providers

MediaEmbed only adds

<figure class="media">
     <oembed url="...."></oembed>
</figure>

I want him to add an iframe for youtube.

editor:{
  mediaEmbed: {
    providers: [
      {
        name: 'youtube',
        url: [
          /^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,
          /^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,
          /^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,
          /^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/
        ],
        html: match => {
          const id = match[ 1 ];
          const time = match[ 2 ];

          return (
            '<div class="youtube-embed" style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">' +
              `<iframe src="https://www.youtube.com/embed/${ id }${ time ? `?start=${ time }` : '' }" ` +
                'style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;" ' +
                'frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>' +
              '</iframe>' +
            '</div>'
          );
        }
      }
    ]
  },
}

I tried to add youtube provider manually, but it does not work, what am I doing wrong?

Using this ckeditor inside react app (but still upload to strapi media library)

Hi,

I was wondering if there was a way to use this build of the CKEDITOR inside my react app, but still be able to upload images into the strapi media library, just inside react app, which is connected to the strapi CMS database.

Is this possible to do that, or would I have to create my own plugin that is totally separate from this?

I really just want to be able to use this ckeditor build in my react app too, not just with the default rich text wysywyg in strapi cms, and be able to upload images directly to the strapi media library like this plugin allows. This all worked in version 3 of strapi, but since migrating to version 4, the react custom ckeditor I used to have no longer works.

Can someone point me in the right direction? I was asking about this in the strapi discord, and they suggested I had to build my own plugin from scratch.

default-src resources blocking youtube content

Hi ๐Ÿ‘‹

My nginx server is blocking youtube embed content when I paste the link into the ckeditor. Is there anything else that needs to be done after I allow *.youtube.com? After adding that to my frame-src, frame-ancestors and even tested with default-src, resulted in the same error shown below.

The pageโ€™s settings blocked the loading of a resource at https://www.youtube.com/embed/Ndfsgsdfg6Pno (โ€œdefault-srcโ€)

The video embeds, but no previews or image is shown for the video.

Update: I disabled my nginx CSP temporarily and continue to receive the same error.

Add Document list feature

Hi,
is there any way to add block element into list li tag?

In the official CKEditor docs we can found information about "Document list feature" - which enables adding any type of allowed elements into li tag.

https://ckeditor.com/docs/ckeditor5/latest/features/lists/document-lists.html

But as far as we cannot install any external CKEditor plugin to this library, is there any other solution to put lets say, table element into the list?

Thanks in advance for any hint.

Make plugin compatible with Node V18

Now that node V18 is LTS, and Strapi now supports node V18, this plugin should also support running under node V18. When trying to do "yarn install" under node V18, am receiving the following error:

**error @_sh/[email protected]: The engine "node" is incompatible with this module. Expected version ">=14.x.x <=16.x.x". Got "18.12.0"**

Just a thank you!

Dear @nshenderov,

huge thank you for maintaining this package. Its such a simple drop-in replacement for the barely usable ootb Strapi Editor!

This saved us a lot of time and the users are happy!

๐Ÿ’–๐Ÿš€

Are you sure you want to leave this page?

Hi. Thanks for the great plugin.

I've run into a minor issue on content types that feature a CK editor. To reproduce the issue:

  1. Add or edit an entry that features a CK editor
  2. Don't make any changes to the content
  3. Navigate to a different page

What happens
CK editor thinks that content has been modified and a browser alert asks 'Are you sure you want to leave this page?'

What should happen
If no content has been modified, it should be possible to navigate away without an alert.

Strapi version: v4.3.6
Node vserion: v14.20

Feature Request: A save button while in full-screen

A small feature request to be able to save ones work while in full-screen mode.

The feature request would have a save button in top right or a floating button that isn't in the way for the author to focus on writing only.

On saving the document, the full screen will exit and use the save feature already built into Strapi.

baseURL is not working

Hi guys! I am currently working with strapi v4 and we have implemented this CKEditor which has great features. However I am facing a problem with this baseURL configuration which is not working properly IMO. Or I am doing something wrong.
So I provided changes according to your documentation:
Zrzut ekranu 2022-10-21 o 10 32 32

My config/api.js

module.exports = ({ env }) => ({
  baseURL: env('PUBLIC_URL', 'http://localhost:1337'),
});

The result:

Zrzut ekranu 2022-10-21 o 10 55 54

So after adding adding baseURL to config/api.js nothing is happening and sources for uploaded images inside text editor are not prefixed with provided URL.

Is there any possible solution for that issue?

[Strapi v4.2.2] Cannot edit "editor" config

Hello,

I tried to edit the Strapi configuration to change the available font family, disable font background color...etc but I cannot make it work.

Here's my config file

module.exports = () => {
  return {
    ckeditor: {
      enabled: true,
      config:{
        editor:{
          removePlugins: ['FontBackgroundColor'],

          // https://ckeditor.com/docs/ckeditor5/latest/features/toolbar/toolbar.html
          toolbar: {
            items: [
              'paragraph',
              'heading1',
              'heading2',
              '|',
              'bold',
              'italic',
              'fontFamily',
              'underline',
              'fontSize',
              'removeFormat',
              '|',
              'bulletedList',
              'todoList',
              'numberedList',
              '|',
              'alignment',
              'outdent',
              'indent',
              'horizontalLine',
              '|',
              'StrapiMediaLib',
              'insertTable',
              'blockQuote',
              'mediaEmbed',
              'link',
              'highlight',
              '|',
              'htmlEmbed',
              'sourceEditing',
              'code',
              'codeBlock',
              '|',
              'subscript',
              'superscript',
              'strikethrough',
              'specialCharacters',
              '|',
              'heading',
              "fullScreen",
              'undo',
              'redo'
            ]
          },
          // https://ckeditor.com/docs/ckeditor5/latest/features/font.html
          fontSize: {
            options: [
              12,
              14,
              'default',
              16,
              22,
              30,
              40,
              50,
            ],
            supportAllValues: false
          },
          fontFamily: {
            options: [
              'default',
              'acumin-pro, sans-serif',
            ],
            supportAllValues: false
          },
          fontColor: {
            columns: 5,
            documentColors: 10,
          },
          // https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
          language: 'fr',
          // https://ckeditor.com/docs/ckeditor5/latest/features/headings.html
          heading: {
            options: [
              { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
              { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'page-title' },
              { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'section-title' },
              { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'section-subtitle' },
              { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'sub-section-title' },
            ]
          },
        }
      }
    }
  }
}

Any idea ? Is there a previous Strapi version I should use or is it a known issue that will be fixed ?

Thanks a lot,

V.4.4.3 CKEditor not loading in Production

Hello ๐Ÿ‘‹ after upgrading to the newest version my CKEditor plugin is not loading in my Heroku instance. It does load in my local dev environment though. I just downgraded to V.4.4.1 and it works fine again. My version of Strapi is inherited from TS Beta 1.

I checked heroku logs and no error was found, it just doesn't load the editor at all, even calls are made to CKEditor plugin:


> 2022-10-07T07:24:11.482798+00:00 heroku[router]: at=info method=GET path="/ckeditor/config/plugin" host=urbanist-travel-strapi-v4.herokuapp.com request_id=76b8b943-e7a7-4e26-8b17-83dce8a21582 fwd="212.102.48.217" dyno=web.1 connect=0ms service=21ms status=200 bytes=4893 protocol=https
> 2022-10-07T07:24:11.481343+00:00 app[web.1]: [2022-10-07 07:24:11.481] http: GET 
> /ckeditor/config/plugin (19 ms) 200
> 2022-10-07T07:24:11.795687+00:00 app[web.1]: [2022-10-07 07:24:11.795] http: GET 
> /ckeditor/config/uploadcfg (21 ms) 200
> 2022-10-07T07:24:11.797042+00:00 heroku[router]: at=info method=GET path="/ckeditor/config/uploadcfg" host=urbanist-travel-strapi-v4.herokuapp.com request_id=1aa50dc5-900c-413b-a50f-55ce5e128fad fwd="212.102.48.217" dyno=web.1 connect=0ms service=23ms status=200 bytes=1013 protocol=https

heroku
strapi: 4.4.3
strapi-plugin-ckeditor1.1.2
node 16.17.1
DB: PostGres

Error compiling with Strapi 4.3.3

how can i solve this error
when I do "npm run build" it compiles normally, but when I do "npm start" I get that error
image

I need help thanks

Mention Plugin is not working

In the documentation it is mentioned that Mention plugin is included.
So I tried out following config inside /config/plugins.js with following code return:

{
        ckeditor: {
            enabled: true,
            config: {
                editor: {
                    toolbar: {
                        items: [
                            "bold",
                            "italic"
                        ]
                    }
                },
                plugin: {
                    mention: {
                        feeds: [{
                            marker: "@",
                            feed: ["@Kishore", "@Kumar", "@Barik"]
                        }]
                    }
                }
            }
        }
    }

I don't see the mentions appear.

Additional info

"@strapi/strapi": "4.1.9"
"@_sh/strapi-plugin-ckeditor": "^1.1.0"

adding addTargetToExternalLinks in plugins.js

Hi!

I would like my links to open in a new tab and I found some documentation about this in the docs

Now I've implemented this but probably the wrong way, can anyone help? My plugins.js looks as follows:

module.exports = ({env}) => ({
    'transformer'         : {
        enabled: true,
        config : {
            prefix            : '/api/',
            responseTransforms: {
                removeAttributesKey: true,
                removeDataKey      : true,
            }
        }
    },
    'seo'                 : {
        enabled: true,
    },
    'measurement-protocol': {
        config: {
            apiSecret          : 'LUGGNONmQVW5U0ZrlK6AxQ',
            measurementId      : 'G-JKZ4XHRX11',
            useValidationServer: false,
        }
    },
    'ckeditor'            : {
        enabled: true,
        plugins: {
            strapiTheme: false,
        },
        editor : {
            link: {
                decorators: {
                    addTargetToExternalLinks: {
                        mode      : 'automatic',
                        attributes: {
                            target: '_blank',
                            rel   : 'noopener noreferrer'
                        }
                    }
                }
            }
        }
    }
});

Media library hidden on fullscreen editor

Hi! ๐Ÿ‘‹

Firstly, thanks for your work on this project! ๐Ÿ™‚

Today I used patch-package to patch @_sh/[email protected] for the project I'm working on.

When opening the editor in fullscreen and using the media library the modal opens behind the editor--

Here is the diff that solved my problem:

diff --git a/node_modules/@_sh/strapi-plugin-ckeditor/admin/src/components/CKEditor/index.js b/node_modules/@_sh/strapi-plugin-ckeditor/admin/src/components/CKEditor/index.js
index a1bcdcc..84a9e84 100644
--- a/node_modules/@_sh/strapi-plugin-ckeditor/admin/src/components/CKEditor/index.js
+++ b/node_modules/@_sh/strapi-plugin-ckeditor/admin/src/components/CKEditor/index.js
@@ -19,6 +19,9 @@ ${({ custom }) => custom}
 	position: relative;
 	width:100%;
 }
+#fullscreeneditor {
+  z-index: 3!important;
+}
 `;
 const Wrapper = styled(Box)``;
 

This issue body was partially generated by patch-package.

config.editor is not working

Hi
yesterday I see your wonderful component in strapi marketplace and I just install it and use it. everything works fine on the first try but when I try to change the default config for example add fonts or make it rtl it doesn't work.
first I create file ckeditor-config.js like following:

const ckEditorConfig = {
    enabled: true,
    config:{
      plugin:{
     // styles applies to editor container
        styles:``
      },
     // editor default config 
      editor:{
        toolbar: {
          items: [
            'paragraph',
            'heading1',
            'heading2',
            '|',
            'bold',
            'italic',
            'fontColor',
            'fontBackgroundColor',
            'fontFamily',
            'underline',
            'fontSize',
            'removeFormat',
            '|',
            'bulletedList',
            'todoList',
            'numberedList',
            '|',
            'alignment',
            'outdent',
            'indent',
            'horizontalLine',
            '|',
            'StrapiMediaLib',
            'insertTable',
            'blockQuote',
            'mediaEmbed',
            'link',
            'highlight',
            '|',
            'htmlEmbed',
            'sourceEditing',
            'code',
            'codeBlock',
            '|',
            'subscript',
            'superscript',
            'strikethrough',
            'specialCharacters',
            '|',
            'heading',
            "fullScreen",
            'undo',
            'redo'
          ]
        },
        fontSize: {
          options: [
              9,
              11,
              13,
              'default',
              17,
              19,
              21,
              27,
              35,
              "tiny",
              "small",
              "big",
              "huge"
          ],
          supportAllValues: false
        },
        fontFamily: {
          options: [
            'default',
            'bolbol',
            'Arial, Helvetica Neue, Helvetica, Source Sans Pro, sans-serif',
            'Courier New, Courier, monospace',
            'Georgia, serif',
            'Lucida Sans Unicode, Lucida Grande, sans-serif',
            'Tahoma, Geneva, sans-serif',
            'Times New Roman, Times, serif',
            'Trebuchet MS, Helvetica, sans-serif',
            'Verdana, Geneva, sans-serif',
            'Roboto, Roboto Black, Roboto Medium, Roboto Light, sans-serif',
          ],
          supportAllValues: true
        },
        fontColor: {
          columns: 5,
          documentColors: 10,
        },
        fontBackgroundColor: {
          columns: 5,
          documentColors: 10,
        },
        language: 'ar',
        image: {
          resizeUnit: "%",
          resizeOptions: [ {
            name: 'resizeImage:original',
            value: null,
            icon: 'original'
          },
          {
            name: 'resizeImage:25',
            value: '25',
            icon: 'small'
          },
          {
            name: 'resizeImage:50',
            value: '50',
            icon: 'medium'
          },
          {
            name: 'resizeImage:75',
            value: '75',
            icon: 'large'
          } ],
          toolbar: [
            'toggleImageCaption',
            'imageTextAlternative',
            'imageStyle:inline',
            'imageStyle:block',
            'imageStyle:side',
            'linkImage',
            'resizeImage:25', 'resizeImage:50', 'resizeImage:75', 'resizeImage:original'
          ]
        },
        table: {
          contentToolbar: [
            'tableColumn',
            'tableRow',
            'mergeTableCells',
            'tableCellProperties',
            'tableProperties',
            'toggleTableCaption'
          ]
        },
        heading: {
          options: [
            { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
            { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
            { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
            { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
            { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' },
            { model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' },
            { model: 'heading6', view: 'h6', title: 'Heading 6', class: 'ck-heading_heading6' },
            {
                model: 'h1b',
                view: {name: 'h1', classes: 'ck-heading_h1_b'}, title: 'H1 (border)', class: 'ck-heading_heading1', converterPriority: 'high'
            },
            {
              model: 'h2b',
              view: {name: 'h2', classes: 'ck-heading_h2_b'}, title: 'H2 (border)', class: 'ck-heading_heading2', converterPriority: 'high'
            },
            {
            model: 'h3b',
            view: {name: 'h3', classes: 'ck-heading_h3_b'}, title: 'H3 (border)', class: 'ck-heading_heading3', converterPriority: 'high'
            },
            {
              model: 'h4b',
              view: {name: 'h4', classes: 'ck-heading_h4_b'}, title: 'H4 (border)', class: 'ck-heading_heading4', converterPriority: 'high'
            },
            {
              model: 'h5b',
              view: {name: 'h5', classes: 'ck-heading_h5_b'}, title: 'H5 (border)', class: 'ck-heading_heading5', converterPriority: 'high'
            },
            {
              model: 'h6b',
              view: {name: 'h6', classes: 'ck-heading_h6_b'}, title: 'H6 (border)', class: 'ck-heading_heading6', converterPriority: 'high'
            }
          ]
        }
      }
    }
  }

  module.exports = {ckEditorConfig}

then I change plugin.js:

const { ckEditorConfig } = require("./ckeditor-config");

module.exports = ({ env }) => ({
  "measurement-protocol": {
    config: {
      apiSecret: 'key',
      measurementId: 'key',
      useValidationServer: false,
      ckeditor: ckEditorConfig
    }
  },
});

CKEditor is load and work but non of above confit is taking effect and it's run but it's default config

maxLengthCharacters property without 'options.' prefix crashes admin panel

I added this plugin and upgraded to Strapi v4.5.3.

The file node_modules/@ckeditor/strapi-plugin-ckeditor/admin-src/index.js contains a line which lists maxLengthCharacters as a value for a particular property. When you build your admin panel, Chrome shows an error:

Uncaught (in promise) Invariant Violation: 'maxLengthCharacters' must be prefixed with 'options.' at t (http://localhost:1337/admin/main.a627abc1.js:572:555) at http://localhost:1337/admin/main.a627abc1.js:175:22198 at Array.forEach (<anonymous>) at w.register (http://localhost:1337/admin/main.a627abc1.js:175:22145) at Object.register (http://localhost:1337/admin/main.a627abc1.js:181:33) at http://localhost:1337/admin/admin-app.4993638d.chunk.js:66:12701 at Array.forEach (<anonymous>) at ar.<anonymous> (http://localhost:1337/admin/admin-app.4993638d.chunk.js:66:12670) at Generator.next (<anonymous>) at http://localhost:1337/admin/admin-app.4993638d.chunk.js:66:5295

Prefixing this value with 'option.' in the appropriate main.js file fixes the problem. So, perhaps a change needs to be made somewhere in this plugin or how the build step handles this object during compilation?

Could not load js config file $folder/node_modules/@_sh/strapi-plugin-ckeditor/strapi-server.js: Unexpected token '?'

Installing the plugin on [email protected] running node v12.22.12 (lts) and after building the admin UI via npm run build, I'm unable to start the strapi server with npm run dev.

[2022-07-25 15:01:45.839] debug: โ›”๏ธ Server wasn't able to start properly.
[2022-07-25 15:01:45.841] error: Could not load js config file $folder/node_modules/@_sh/strapi-plugin-ckeditor/strapi-server.js: Unexpected token '?'
Error: Could not load js config file $folder/node_modules/@_sh/strapi-plugin-ckeditor/strapi-server.js: Unexpected token '?'
    at loadJsFile ($folder/node_modules/@strapi/strapi/lib/core/app-configuration/load-config-file.js:18:11)
    at loadFile ($folder/node_modules/@strapi/strapi/lib/core/app-configuration/load-config-file.js:35:14)
    at Object.loadPlugins ($folder/node_modules/@strapi/strapi/lib/core/loaders/plugins/index.js:96:26)
    at async Strapi.loadPlugins ($folder/node_modules/@strapi/strapi/lib/Strapi.js:284:5)
    at async Promise.all (index 1)
    at async Strapi.register ($folder/node_modules/@strapi/strapi/lib/Strapi.js:316:5)
    at async Strapi.load ($folder/node_modules/@strapi/strapi/lib/Strapi.js:414:5)
    at async Strapi.start ($folder/node_modules/@strapi/strapi/lib/Strapi.js:163:9)

Unable to change CKEditor's config

Hello!

First off, thanks a lot for this plugin, the default configuration is incredible!

However, I cannot manage to allow attributes in my HTML, just as #19 , however my file should be registered by CKEditor

// config/plugins.js (was .ts, but just in case...)

module.exports = () => ({
    ckeditor: {
        enabled: true,
        config: {
            editor: {
                htmlSupport: {
                    allow: [
                        {
                            name: /.*/,
                            attributes: true,
                            classes: true,
                        }
                    ]
                },
            }
        }
    },
})

I found this snippet here, but even after rebuilding, I still get my attributes stripped.

edit

Ok so I copied the configuration from someone at #19 , removed the regex since I've read how everything was transformed to JSON, AND renamed the file back to plugins.ts, and it works. I don't know what worked in my process, but I'm glad it did. Sooo... Thanks I guess!

Strapi build hangs

Hi, reporting a very strange issue here. When I add the plugin to my strapi installation, the build process get stuck at around 20% (sometimes is 21, other 22, never went past 23). No error reported, the process just hangs there, I've tried waiting more than 30 minutes with no success. Without the plugin the build process completes in less than a minute.
The machine I'm trying to build is a MacBook air with the latest macOS, node version 16.15 (but I've tried version 14 as well), and strapi 4 at the latest version.

Change language content by i18n active language

Change config language content to actual select language by i18n strapi plugin. We can read country/language code from url query params.

I need change text direction dynamically by languages so for example for "en" I need ltr direction and for "ar" I need rlt text direction.

Centered image doesn't get a class applied

It seems that when I want to center an image there isn't any class added to the image.
It does work for the alignment to the right or resizing of the image.
image

I'm using the default configuration.

Please let me know if you need anymore information.

Edit:
I noticed that class: image acts as the 'centered class', but I don't think that's desired behavior. image-style-center would be a better classname imo.

I managed to center the images with this css though:

.image-style-side{
    margin-left: auto;
    margin-right: 0 !important
}

.image {
    margin: 0 auto;
}

How to control whether to turn on responsive pictures

I found that when I selected a picture, a responsive picture was automatically generated. However, there are some material images, which are of low quality. I want to directly use their original images instead of generating responsive images. Can this enable the user to automatically control whether it is enabled?

Refused to frame 'https://www.youtube.com/' because it violates the following Content Security Policy directive

I am getting following error in browser console and I cant see the preview in the editor when embedding videos

Refused to frame 'https://www.youtube.com/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.

main.95e79f29.js:15982 Refused to frame 'https://player.vimeo.com/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.

main.95e79f29.js:15982 Refused to frame 'https://www.youtube.com/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.

main.95e79f29.js:15982 Refused to frame 'https://player.vimeo.com/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.

And this is what I see in browser

Screenshot 2022-11-01 at 14 53 16

Following is my middlware.js in strapi.

module.exports = [
  "strapi::errors",
  {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "default-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com",
            "lh3.googleusercontent.com",
            "platform-lookaside.fbsbx.com",
            "dl.airtable.com",
            "https://www.youtube.com/",
            "https://www.youtube.com/embed/",
            "https://player.vimeo.com/",
          ],          
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com",
            "lh3.googleusercontent.com",
            "platform-lookaside.fbsbx.com",
            "dl.airtable.com",
            "https://www.youtube.com/",
            "https://www.youtube.com/embed/",
            "https://player.vimeo.com/",
          ],
          "media-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com",
            "lh3.googleusercontent.com",
            "platform-lookaside.fbsbx.com",
            "dl.airtable.com",
            "https://www.youtube.com/",
            "https://www.youtube.com/embed/",
            "https://player.vimeo.com/",
          ],
          "frame-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com",
            "lh3.googleusercontent.com",
            "platform-lookaside.fbsbx.com",
            "dl.airtable.com",
            "https://www.youtube.com/",
            "https://www.youtube.com/embed/",
            "https://player.vimeo.com/",
          ],
          "iframe-src": [
            "'self'",
            "data:",
            "blob:",
            "res.cloudinary.com",
            "lh3.googleusercontent.com",
            "platform-lookaside.fbsbx.com",
            "dl.airtable.com",
            "https://www.youtube.com/",
            "https://www.youtube.com/embed/",
            "https://player.vimeo.com/",
          ],          
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  "strapi::security",
  "strapi::cors",
  "strapi::poweredBy",
  {
    name: "strapi::cors",
    config: {
      enabled: true,
      headers: "*",
      origin: ["*"],
    },
  },
  "strapi::logger",
  "strapi::query",
  "strapi::body",
  "strapi::session",
  "strapi::favicon",
  "strapi::public",
];

any idea?

Adding Custom Plugin

Sorry I could not find any information anywhere else about how to go about adding ckeditor plugins to this setup.

What is the suggested and/or best way to go about adding additional custom ckeditor plugins to this strapi plugin? (i.e. add toolbar button to trigger simple plugin)

Any information would be greatly appreciated.

Thanks in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.