• Techblog369, India
  • September 29, 2022

How to create PHP QR code and Save it to Database?

Hi In this Article I am going to show how to create QR code and save it to database also fetch QR Code in a Table Create a Page addqrcode.php in …

How to Send Multiple Files Attachment Mail using Laravel

Hi in this article i am going to show how to send multiple files attachment mail in Laravel. It’s simple example of Laravel send multiple attachment in mail. I explained simply …

Install CKEditor on Strapi, In this guide, we will see how you can create a new Field for your administration panel

Step1

Generate a plugin

cd your-projectfolder

yarn strapi generate:plugin wysiwyg

Step2

Install the needed dependencies

cd plugins/wysiwyg
yarn add @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic

Step3

# Go back to strapi root folder

it will work only yarn, not npm. watch-admin help for project rebuilding automatically

cd ../..
yarn develop --watch-admin

Step4

Creating the MediaLib

Make folder components/MediaLib/index.js under ./plugins/wysiwyg/admin/src/
The path looks like that

./plugins/wysiwyg/admin/src/components/MediaLib/index.js

Then Paste the bellow code

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;

Step5

Creating the WYSIWYG Wrapper

Path  ./plugins/wysiwyg/admin/src/components/Wysiwyg/index.js

Paste the below code in 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);
   let spacer = !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.6rem',
               fontSize: '1.3rem',
               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.4rem' } : {}}
           />
           <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;

Step6

Implementing CKEditor
Path ./plugins/wysiwyg/admin/src/components/CKEditor/index.js
Paste the below code

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}
               onReady={editor => editor.setData(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;

At this point, we have simply created a new plugin that is mounted in our project but our custom Field has not been
registered yet.

Registering a our new Field

Path — ./plugins/wysiwyg/admin/src/index.js

import pluginPkg from '../../package.json';
import Wysiwyg from './components/Wysiwyg';
import pluginId from './pluginId';
import App from './containers/App';
import Initializer from './containers/Initializer';
import lifecycles from './lifecycles';
import trads from './translations';

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

 const plugin = {
   blockerComponent: null,
   blockerComponentProps: {},
   description: pluginDescription,
   icon,
   id: pluginId,
   initializer: Initializer,
   injectedComponents: [],
   isReady: false,
   isRequired: pluginPkg.strapi.required || false,
   layout: null,
   lifecycles,
   mainComponent: null,
   name,
   preventComponentRendering: false,
   trads,
   // menu: {
   //   pluginsSectionLinks: [
   //     {
   //       destination: `/plugins/${pluginId}`,
   //       icon,
   //       label: {
   //         id: `${pluginId}.plugin.name`,
   //         defaultMessage: name,
   //       },
   //       name,
   //       permissions: [
   //         // Uncomment to set the permissions of the plugin here
   //         // {
   //         //   action: '', // the action name should be plugins::plugin-name.actionType
   //         //   subject: null,
   //         // },
   //       ],
   //     },
   //   ],
   //},
 };
 strapi.registerField({ type: 'wysiwyg', Component: Wysiwyg });
 return strapi.registerPlugin(plugin);
};

Finally, you will have to rebuild strapi so the new plugin is loaded correctly

yarn build

If you want to remove WYSIWYG from your plugin folder then just remove the below code from .plugins/wysiwyg/admin/src/index.js

// menu: {
   //   pluginsSectionLinks: [
   //     {
   //       destination: `/plugins/${pluginId}`,
   //       icon,
   //       label: {
   //         id: `${pluginId}.plugin.name`,
   //         defaultMessage: name,
   //       },
   //       name,
   //       permissions: [
   //         // Uncomment to set the permissions of the plugin here
   //         // {
   //         //   action: '', // the action name should be plugins::plugin-name.actionType
   //         //   subject: null,
   //         // },
   //       ],
   //     },
   //   ],
   //},

Author

admin@techblog369.in

Leave a Reply

Your email address will not be published.