Strapi introduction

Strapi is a free open source headless CMS that allows you to quickly build your own apis.

  • Maintain control over data. With Strapi, you know where your data is stored and always have full control.
  • Since the escrow. You can host and extend Strapi projects in your own way. You can choose any hosting platform you want: AWS, Netlify, Heroku, VPS or dedicated servers. You can scale as you grow, 100% independent.
  • You can choose your favorite database. Strapi works with SQL and NoSQL databases: MongoDB, PostgreSQL, MySQL, MariaDB, and SQLite.
  • Customizable. Quickly build logic by fully customizing apis, routes, or plug-ins to fully satisfy requirements.

The installation

# Install using YARN
yarn create strapi-app my-project --quickstart
Use NPM/NPX or install
npx create-strapi-app my-project --quickstart
# Start development mode
yarn dev
# Production mode
yarn start
# rebuild
yarn build
Copy the code

You can open the config/server.js file to change the startup port number

After the initial installation, a page will pop up asking you to register an administrator account

use

After a successful login

  1. Click the content type Generator on the left menu bar

  2. Click create a new Content Type

  3. Enter a name. In advanced Settings, select Draft/ Publish System OFF and click Continue (the name is API /name)

  4. Select the fields you want and create them, and click Finish to restart the application.

  5. On the left menu barCOLLECTION TYPESUnder the category, the content you just created appears

  6. Click New, type and save (Publish next to save if OFF is not selected in step 3). At this point to http://localhost:1337/tests shows statusCode: 403.

  7. Click Settings/Roles and Permissions /Public on the left menu bar, select find and Find One, and save.

  8. At this point to http://localhost:1337/tests can display the data content

Custom rich text editor

Here, take CKEditor5 as an example. The customization tutorial looks at the “CKEditor5” rich text editor customization, and then copies the Ckeditor. Js and Translations folder in the Build folder.

1. Generate plug-ins and install dependencies

yarn strapi generate:plugin wysiwyg
cd plugins/wysiwyg
yarn add @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic
Copy the code

2. Create MediaLib

Path -. / plugins/wysiwyg/admin/SRC/components/MediaLib/index. Js

import React, { useEffect, useState } from 'react';
import { useStrapi, prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import PropTypes from 'prop-types';

const MediaLib = ({ isOpen, onChange, onToggle }) = > {
  const {
    strapi: {
      componentApi: { getComponent },
    },
  } = useStrapi();
  const [data, setData] = useState(null);
  const [isDisplayed, setIsDisplayed] = useState(false);

  useEffect(() = > {
    if (isOpen) {
      setIsDisplayed(true);
    }
  }, [isOpen]);

  const Component = getComponent('media-library').Component;

  const handleInputChange = data= > {
    if (data) {
      const{ url } = data; setData({ ... data,url: prefixFileUrlWithBackendUrl(url) }); }};const handleClosed = () = > {
    if (data) {
      onChange(data);
    }

    setData(null);
    setIsDisplayed(false);
  };

  if (Component && isDisplayed) {
    return (
      <Component
        allowedTypes={['images', 'videos', 'files']}
        isOpen={isOpen}
        multiple={false}
        noNavigation
        onClosed={handleClosed}
        onInputMediaChange={handleInputChange}
        onToggle={onToggle}
      />
    );
  }

  return null;
};

MediaLib.defaultProps = {
  isOpen: false.onChange: () = > {},
  onToggle: () = >{}}; MediaLib.propTypes = {isOpen: PropTypes.bool,
  onChange: PropTypes.func,
  onToggle: PropTypes.func,
};

export default MediaLib;
Copy the code

3. Create a WYSIWYG

Path -. / plugins/wysiwyg/admin/SRC/components/wysiwyg/index. Js

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { isEmpty } from 'lodash';
import { Button } from '@buffetjs/core';
import { Label, InputDescription, InputErrors } from 'strapi-helper-plugin';
import Editor from '.. /CKEditor';
import MediaLib from '.. /MediaLib';

const Wysiwyg = ({ inputDescription, errors, label, name, noErrorsDescription, onChange, value, }) = > {
  const [isOpen, setIsOpen] = useState(false);
  letspacer = ! isEmpty(inputDescription) ?<div style={{ height: '.4rem' }} /> : <div />;

  if(! noErrorsDescription && ! isEmpty(errors)) { spacer =<div />;
  }

  const handleChange = data= > {
    if (data.mime.includes('image')) {
      const imgTag = `<p><img src="${data.url}" caption="${data.caption}" alt="${data.alternativeText}"></img></p>`;
      const newValue = value ? `${value}${imgTag}` : imgTag;

      onChange({ target: { name, value: newValue } });
    }

    // Handle videos and other type of files by adding some code
  };

  const handleToggle = () = > setIsOpen(prev= >! prev);return (
    <div
      style={{
        marginBottom: '1.6 rem',
        fontSize: '1.3 rem',
        fontFamily: 'Lato'}} >
      <Label htmlFor={name} message={label} style={{ marginBottom: 10}} / >
      <div>
        <Button color="primary" onClick={handleToggle}>
          MediaLib
        </Button>
      </div>
      <Editor name={name} onChange={onChange} value={value} />
      <InputDescription
        message={inputDescription}
        style={! isEmpty(inputDescription) ? { marginTop: '1.4 rem'}:{}} / >
      <InputErrors errors={(! noErrorsDescription && errors) | | []}name={name} />
      {spacer}
      <MediaLib onToggle={handleToggle} isOpen={isOpen} onChange={handleChange} />
    </div>
  );
};

Wysiwyg.defaultProps = {
  errors: [].inputDescription: null.label: ' '.noErrorsDescription: false.value: ' '}; Wysiwyg.propTypes = {errors: PropTypes.array,
  inputDescription: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.func,
    PropTypes.shape({
      id: PropTypes.string,
      params: PropTypes.object,
    }),
  ]),
  label: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.func,
    PropTypes.shape({
      id: PropTypes.string,
      params: PropTypes.object,
    }),
  ]),
  name: PropTypes.string.isRequired,
  noErrorsDescription: PropTypes.bool,
  onChange: PropTypes.func.isRequired,
  value: PropTypes.string,
};

export default Wysiwyg;
Copy the code

4. Create CKEditor

Path -. / plugins/wysiwyg/admin/SRC/components/CKEditor/index, js

import React from 'react';
import PropTypes from 'prop-types';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import styled from 'styled-components';

const Wrapper = styled.div` .ck-editor__main { min-height: 200px; > div { min-height: 200px; }} `;

const configuration = {
  toolbar: [
    'heading'.'|'.'bold'.'italic'.'link'.'bulletedList'.'numberedList'.'|'.'indent'.'outdent'.'|'.'blockQuote'.'insertTable'.'mediaEmbed'.'undo'.'redo',]};const Editor = ({ onChange, name, value }) = > {
  return (
    <Wrapper>
      <CKEditor
        editor={ClassicEditor}
        config={configuration}
        data={value}
        onChange={(event, editor) = >{ const data = editor.getData(); onChange({ target: { name, value: data } }); }} / ></Wrapper>
  );
};

Editor.propTypes = {
  onChange: PropTypes.func.isRequired,
  name: PropTypes.string.isRequired,
  value: PropTypes.string,
};

export default Editor;
Copy the code

5. Overwrite the WYSIWYG and modify the front entrance of the plug-in

Replace the contents of the following files

Path -. / plugins/wysiwyg/admin/SRC/index, js

import pluginPkg from '.. /.. /package.json';
import Wysiwyg from './components/Wysiwyg';
import pluginId from './pluginId';

export default strapi => {
  const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;

  const plugin = {
    blockerComponent: null.blockerComponentProps: {},
    description: pluginDescription,
    icon: pluginPkg.strapi.icon,
    id: pluginId,
    initializer: () = > null.injectedComponents: [].isReady: true.isRequired: pluginPkg.strapi.required || false.mainComponent: null.name: pluginPkg.strapi.name,
    preventComponentRendering: false.settings: null.trads: {}}; strapi.registerField({type: 'wysiwyg'.Component: Wysiwyg });

  return strapi.registerPlugin(plugin);
};
Copy the code

6. Replace your own custom CKEditor5

  1. Will start copyingckeditor.jsandtranslationsCopy folder toplugins/wysiwyg/admin/src/components/CKEditorfolder
  2. Modify theplugins/wysiwyg/admin/src/components/CKEditor/index.js
    - import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
    + import ClassicEditor from "./ckeditor";
    Copy the code
  3. Rebuild the file to see the effect
yarn build
yarn dev
Copy the code

reference

  • Create a new plug-in to change WYSIWYG in CKEditor
  • ckeditor5-strapi-upload-plugin