From d54899e72b450fc3d7cfe08d79ac0d6872874726 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Tue, 19 Apr 2022 11:38:55 +0200 Subject: [PATCH] add editors doc --- docs/template.md | 2 +- docs/tree/page.md | 8 +- docs/utils/editors/editorjs.md | 130 +++++++++++++++++++++++ docs/utils/editors/grapesjs.md | 132 +++++++++++++++++++++++ docs/utils/editors/tinymce.md | 186 +++++++++++++++++++++++++++++++++ mkdocs.yml | 5 + 6 files changed, 460 insertions(+), 3 deletions(-) create mode 100644 docs/utils/editors/editorjs.md create mode 100644 docs/utils/editors/grapesjs.md create mode 100644 docs/utils/editors/tinymce.md diff --git a/docs/template.md b/docs/template.md index 971e980..4f212ba 100644 --- a/docs/template.md +++ b/docs/template.md @@ -72,7 +72,7 @@ When the navigation has several domains, you can specify the domain: ### Filters -When a content could contains tags (eg: '{{url://my_route}}`), use `murph_url`. This the example below: +When a content could contains tags (eg: '{{url://my_route}}`), use `murph_url`. See the example below: | Code | Output | | ---- | ------ | diff --git a/docs/tree/page.md b/docs/tree/page.md index 70f7070..f8c5b69 100644 --- a/docs/tree/page.md +++ b/docs/tree/page.md @@ -100,11 +100,15 @@ public function getMyBlock(): Block ### EditorJsTextareaBlockType -`App\Core\Form\Site\Page\EditorJsTextareaBlockType` will render a EditorJs widget. +`App\Core\Form\Site\Page\EditorJsTextareaBlockType` will render a [EditorJs widget](/utils/editors/editorjs/). ### GrapesJsBlockType -`App\Core\Form\Site\Page\GrapesJsBlockType` will render a GrapesJS editor. +`App\Core\Form\Site\Page\GrapesJsBlockType` will render a [GrapesJS editor](/utils/editors/grapesjs/). + +### TinymceTextareaBlockType + +`App\Core\Form\Site\Page\TinymceTextareaBlockType` will render a [Tinymce editor](/utils/editors/tinymce/). ### ImageBlockType diff --git a/docs/utils/editors/editorjs.md b/docs/utils/editors/editorjs.md new file mode 100644 index 0000000..76db082 --- /dev/null +++ b/docs/utils/editors/editorjs.md @@ -0,0 +1,130 @@ +# Editor.js + +Workspace in classic editors is made of a single contenteditable element, used to create different HTML markups. Editor.js workspace consists of separate Blocks: paragraphs, headings, images, lists, quotes, etc. Each of them is an independent contenteditable element (or more complex structure) provided by Plugin and united by Editor's Core. + +Editor.js is fully integrated in Murph as form types. + +## Classic form + +``` +// src/Form/ExampleType.php +namespace App\Form\ExampleType; + +use App\Core\Form\Type\EditorJsTextareaType; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; + +class ExampleType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myField', + EditorJsTextareaType::class + ); + + // ... + } + + // ... +} +``` + +Modified data should return stringified JSON array if empty: + +``` +public function getMyField(): string +{ + if (empty($this->myField)) { + $this->myField = '[]'; + } + + return $this->myField; +} +``` + +## Page form + +``` +// src/Entity/Page/YourPage.php +namespace App\Entity\Page; + +use App\Core\Entity\Site\Page\Block; +use App\Core\Form\Site\Page\EditorJsTextareaBlockType; + +/** + * @ORM\Entity + */ +class YourPage extends Page +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myBlock', + EditorJsTextareaBlockType::class, + [ + 'label' => 'My block', + 'row_attr' => [ + ], + 'options' => [ + // options given to the sub form + ], + ] + ); + + // ... + } + + public function setMyBlock(Block $block) + { + return $this->setBlock($block); + } + + public function getMyBlock(): Block + { + $block = $this->getBlock('myBlock'); + + if (!$block->getValue()) { + $block->setValue('[]'); + } + + return $block; + } + + // ... +} +``` + +## Rendering + +Editor.js will generate a JSON which contains blocks. + +Supported blocks: + +* paragraph +* header +* quote +* delimiter +* warning +* list +* nestedList +* checkList +* table +* code +* raw +* image +* link + +To render HTML, the basic way is: `{{ value|editorjs_to_html }}` +If you want to render specific blocks: `{{ value|editorjs_to_html(['paragraph', 'header', ...])) }}` + +Block have default templates stored in `vendor/murph/murph-core/src/core/Resources/views/editorjs`. +They can be simply overridden in `config/packages/app.yaml`: + +``` +core: + editor_js: + blocks: + paragraph: 'path/to/paragraph.html.twig' + header: 'path/to/header.html.twig' +``` diff --git a/docs/utils/editors/grapesjs.md b/docs/utils/editors/grapesjs.md new file mode 100644 index 0000000..2a108b1 --- /dev/null +++ b/docs/utils/editors/grapesjs.md @@ -0,0 +1,132 @@ +# GrapesJS + +GrapesJS is a web builder which combines different tools and features with the goal to help users to build HTML templates without any knowledge of coding. It's a very good solution to replace the common WYSIWYG editor like TinyMCE. + +GrapesJS is fully integrated in Murph as form types. + +## Classic form + +``` +// src/Form/ExampleType.php +namespace App\Form\ExampleType; + +use App\Core\Form\Type\GrapesJsType; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; + +class ExampleType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myField', + GrapesJsType::class + ); + + // ... + } + + // ... +} +``` + +## Page form + +``` +// src/Entity/Page/YourPage.php +namespace App\Entity\Page; + +use App\Core\Entity\Site\Page\Block; +use App\Core\Form\Site\Page\GrapesJsBlockType; + +/** + * @ORM\Entity + */ +class YourPage extends Page +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myBlock', + GrapesJsBlockType::class, + [ + 'label' => 'My block', + 'row_attr' => [ + ], + 'options' => [ + // options given to the sub form + ], + ] + ); + + // ... + } + + public function setMyBlock(Block $block) + { + return $this->setBlock($block); + } + + public function getMyBlock(): Block + { + return $this->getBlock('myBlock'); + } + + // ... +} +``` + +## Options + +There are 3 modes: + +* Bootstrap 4 (default): `bootstrap4` +* Preset webpage: `presetWebpage` +* Preset newsletter: `presetNewsletter` + +To specify a mode, you must define the attribute `data-grapesjs`: + +``` +// src/Form/ExampleType.php + +$builder->add( + 'myField', + GrapesJsType::class, + [ + // ... + + 'attr' => [ + 'data-grapesjs' => 'bootstrap4', + ], + ] +); + +// src/Entity/Page/YourPage.php + +$builder->add( + 'myBlock', + GrapesJsBlockType::class, + [ + // ... + + 'options' => [ + 'attr' => [ + 'data-grapesjs' => 'bootstrap4', + ], + ], + ] +); +``` + +## Rendering + +GrapesJS will generate a JSON which contains HTML and CSS. + +* To extract HTML: `{% set html = value|grapesjs_html %}` +* To extract CSS: `{% set css = value|grapesjs_css %}` + +Depending of the mode, you will need to import in the app sass file: + +* Bootstrap 4: `@import "~bootstrap/scss/bootstrap.scss";` +* Preset webpage: `@import "~grapesjs-preset-webpage/dist/grapesjs-preset-webpage.min.css";` +* Preset newsletter: `@import "~grapesjs-preset-newsletter/dist/grapesjs-preset-newsletter.css";` diff --git a/docs/utils/editors/tinymce.md b/docs/utils/editors/tinymce.md new file mode 100644 index 0000000..bf11e83 --- /dev/null +++ b/docs/utils/editors/tinymce.md @@ -0,0 +1,186 @@ +# TinyMCE + +TinyMCE gives you total control over your rich text editing. It's fully integrated in Murph as form types. + +## Classic form + +``` +// src/Form/ExampleType.php +namespace App\Form\ExampleType; + +use App\Core\Form\Type\TinymceTextareaType; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; + +class ExampleType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myField', + TinymceTextareaType::class + ); + + // ... + } + + // ... +} +``` + +## Page form + +``` +// src/Entity/Page/YourPage.php +namespace App\Entity\Page; + +use App\Core\Entity\Site\Page\Block; +use App\Core\Form\Site\Page\TinymceTextareaBlockType; + +/** + * @ORM\Entity + */ +class YourPage extends Page +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add( + 'myBlock', + TinymceTextareaBlockType::class, + [ + 'label' => 'My block', + 'row_attr' => [ + ], + 'options' => [ + // options given to the sub form + ], + ] + ); + + // ... + } + + public function setMyBlock(Block $block) + { + return $this->setBlock($block); + } + + public function getMyBlock(): Block + { + return $this->getBlock('myBlock'); + } + + // ... +} +``` + +## Options + +There are 2 predefined modes: + +* Default: `default` +* Light: `light` + +To specify a mode, you must define the attribute `data-tinymce`: + +``` +// src/Form/ExampleType.php + +$builder->add( + 'myField', + TinymceTextareaType::class, + [ + // ... + + 'attr' => [ + 'data-tinymce' => 'light', + ], + ] +); + +// src/Entity/Page/YourPage.php + +$builder->add( + 'myBlock', + TinymceTextareaBlockType::class, + [ + // ... + + 'options' => [ + 'attr' => [ + 'data-tinymce' => 'light', + ], + ], + ] +); +``` + +To custom the editor, see the example below: + +``` +// assets/js/admin.js + +import '../../vendor/murph/murph-core/src/core/Resources/assets/js/admin.js' + +window.tinymce.language = 'fr_FR' + +window.tinymce.murph.modes.myCustomMode = { + plugins: '...', + menubar: '...', + toolbar: '...' + quickbars_selection_toolbar: '...' + contextmenu: '...' + templates: [ + { + title: 'Container', + description: 'Add a bootstrap container', + content: '
' + } + // ... + ], + content_style: '...' +} + +// src/Form/ExampleType.php + +$builder->add( + 'myField', + TinymceTextareaType::class, + [ + // ... + + 'attr' => [ + 'data-tinymce' => 'myCustomMode', + ], + ] +); + +// src/Entity/Page/YourPage.php + +$builder->add( + 'myBlock', + TinymceTextareaBlockType::class, + [ + // ... + + 'options' => [ + 'attr' => [ + 'data-tinymce' => 'myCustomMode', + ], + ], + ] +); +``` + +## Rendering + +GrapesJS will generate a JSON which contains HTML and CSS. + +* To extract HTML: `{% set html = value|grapesjs_html %}` +* To extract CSS: `{% set css = value|grapesjs_css %}` + +Depending of the mode, you will need to import in the app sass file: + +* Bootstrap 4: `@import "~bootstrap/scss/bootstrap.scss";` +* Preset webpage: `@import "~grapesjs-preset-webpage/dist/grapesjs-preset-webpage.min.css";` +* Preset newsletter: `@import "~grapesjs-preset-newsletter/dist/grapesjs-preset-newsletter.css";` diff --git a/mkdocs.yml b/mkdocs.yml index 9a3d7f5..51f58d0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -17,6 +17,11 @@ nav: - Controller: controller.md - Template: - Template: template.md + - Utils: + - Editors: + - TinyMCE: utils/editors/tinymce.md + - GrapesJS: utils/editors/grapesjs.md + - Editor.js: utils/editors/editorjs.md - Entities: - 'Entity Manager': entities/em.md - 'Repository Query': entities/query.md