Strapi:配置使用CKEditor和TinyMCE富文本编辑器

1,326 阅读5分钟

前言

目前strapi已经更新到了v5版本,很多人在用strapi发布内容的时候会感觉到自带的富文本编辑器内容不够丰富,在这篇博客中,我将展示如何配置两款常用的富文本编辑器:CKEditor和TinyMCE。不管是新手还是有经验的开发者,都可以通过本文轻松地完成配置。

一、配置使用TinyMCE富文本编辑器

安装

在Strapi应用程序中,添加以下包:

使用npm:

npm install @sklinet/strapi-plugin-tinymce

使用yarn:

yarn add @sklinet/strapi-plugin-tinymce

config/plugins.js文件中添加:

tinymce:{
    enabled:true
};

如果还没有这个文件,直接拷贝下面的文本创建并添加,文件路径和名称就是上面那个config/plugins.js

module.exports = () => ({
    tinymce:{
      enabled:true
    };
})

还需要在config/middlewares.js文件中更新strapi::security中间件。如果没有这个文件的话可以直接拷贝下面的文件到config中:

//middlewares.js

 {
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,  
        directives: {
          "script-src": ["'self'", "*.tinymce.com", "*.tiny.cloud", "https:"],
          "connect-src": ["'self'", "*.tinymce.com", "*.tiny.cloud", "blob:", "*.strapi.io"],
          "img-src": [
            "'self'",
            "*.tinymce.com",
            "*.tiny.cloud",
            "data:",
            "blob:",
            "dl.airtable.com",
            "strapi.io",
            "s3.amazonaws.com",
            "cdn.jsdelivr.net",
          ],
          "style-src": [
            "'self'",
            "'unsafe-inline'",
            "*.tinymce.com",
            "*.tiny.cloud",
          ],
          "font-src": ["'self'", "*.tinymce.com", "*.tiny.cloud"],
        },
        upgradeInsecureRequests: null,
      },
    },
  },

然后运行:

npm run build

或者

yarn build

启动项目后,记得要在设置/Tinymce/configuration的管理面板中为TinyMCE编辑器添加API密钥,这个密钥是在TinyMCE官网注册申请好以后,直接在这填写就行,类似于使用百度地图等需要添加使用密钥。

image.png

如果TinyMCE编辑器不出现在您的富文本字段中,请检查控制台是否有任何提示,您可能已经错误设置了您的中间件。

配置

接下来我们可以在config/plugins.js中,来配置富文本编辑器的配置:

注意!!!是plugins.js而不是plugin.js

官方默认配置:

// plugins.js
module.exports = ({ env }) => ({
    tinymce: {
        enabled: true,
        config: {
            editor: {
                outputFormat: "html",
                editorConfig: {
                    language: "sk",
                    height: 500,
                    menubar: false,
                    extended_valid_elements: "span, img, small",
                    forced_root_block: "",
                    convert_urls: false,
                    entity_encoding: "raw",
                    plugins:
                        "advlist autolink lists link image charmap preview anchor \
                        searchreplace visualblocks code fullscreen table emoticons nonbreaking \
                        insertdatetime media table code help wordcount",
                    toolbar:
                        "undo redo | styles | bold italic forecolor backcolor | \
                        alignleft aligncenter alignright alignjustify | \
                        media table emoticons visualblocks code|\
                        nonbreaking bullist numlist outdent indent | removeformat | help",
                    style_formats: [
                        {
                            title: "Headings",
                            items: [
                                { title: "h1", block: "h1" },
                                { title: "h2", block: "h2" },
                                { title: "h3", block: "h3" },
                                { title: "h4", block: "h4" },
                                { title: "h5", block: "h5" },
                                { title: "h6", block: "h6" },
                            ],
                        },

                        {
                            title: "Text",
                            items: [
                                { title: "Paragraph", block: "p" },
                                {
                                    title: "Paragraph with small letters",
                                    block: "small",
                                },
                            ],
                        },
                    ],
                },
            },
        },
    },
});

如果还想要更多的配置可以直接在官网查看具体的不同配置,此时我们在心怎过一个集合类型,会发现默认的富文本编辑器已经变成了tinymce了:

image.png

image.png


二、配置使用CKEditor5富文本编辑器

🔧 安装

  • 在Strapi 应用程序中,添加包:
npm install @_sh/strapi-plugin-ckeditor

或者

yarn add @_sh/strapi-plugin-ckeditor
  • 然后运行构建:
npm run build

或者

yarn build

⚙️ 配置

该插件使用Strapi 自定义字段 APICKEditor dll 构建

插件配置应该在/config/ckeditor.txt文件中定义。

可以在ckeditor 官方文档查看全部的配置。

ckeditor.txt的内容会在初始化过程中传递到script标签中。

📂 默认配置:admin/src/components/Input/CKEditor/configs

📂 默认主题:admin/src/components/Input/CKEditor/theme

ckeditor.txt示例:

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:``
    }

}

如果是在本地启动的服务,涉及到上传的地址问题,则需要在config/server.js文件中指定url以获取上传文件的完整 URL,例如:

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'),
  },
});

为了在你的代码中显示来自外部源的内容,admin你应该配置你的 middlewares.js,查看关于此内容的文档

如何添加插件

Markdown 插件示例

  • 在您的应用程序内:
yarn add @ckeditor/ckeditor5-markdown-gfm

或者

npm install @ckeditor/ckeditor5-markdown-gfm
  • 在:/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,
};
  • 你的应用程序/配置 /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' }
                    ]
                },
            }
        }
    }
}
  • 然后重新启动应用程序:
npm run build

或者

yarn build

这时候我们在集合中创建一个新字段,会发现多一个custom的字段类型,就是我们刚配置好的ckeditor,可以直接选择使用了!

image.png

image.png

好了,到目前为止使用strapi5配置不同的富文本编辑器就已经全部完成,希望这篇文章可以对你有帮助,我们下期见!