Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

HTMLarea to CKEditor - create presets and your own plugin for TYPO3

2,871 views

Published on

Why did TYPO3 switch to CKEditor, what are these so called presets. And how about using external plugins or even creating a own plugin for CKEditor to use in TYPO3 8 LTS.

In this presentation I walk through these questions and show how to configure CKEditor for TYPO3 and create your own plugin.

(slides of my presentation hold @T3DD17 in Malmö, Sweden)

Published in: Technology
  • Be the first to comment

HTMLarea to CKEditor - create presets and your own plugin for TYPO3

  1. 1. HTMLarea → CKEditor
  2. 2. Frans Saris 2 ■ developer @beech.it (in the Netherlands) ■ TYPO3 core/extension dev ■ slack/typo3.org: minifranske ■ twitter: @franssaris ■ github: fsaris - frans-beech-it - beechit
  3. 3. Why the switch to CKEditor? 3
  4. 4. Why the switch to CKEditor? ■ We don’t have to fully maintain it our self ■ Superb browser support ■ Complying with the latest web accessibility standards ■ Inline editing features ■ Advanced Content Filter 4
  5. 5. The big changes 5
  6. 6. Big changes 6 ■ Presets in YAML ■ <p> are now saved in database! ■ No <typolink> anymore ■ No automatic migration of existing configs
  7. 7. But why YAML? 7
  8. 8. Why YAML 8 ■ CKEditor uses plain javascript for configuration ■ typoscript for BE config is confusing for newcomers ■ A new structure (new start) separate “processing” and Editor-related configuration ■ Allows options to be extend but no conditions or unsetting values
  9. 9. Presets 9
  10. 10. What do these presets do? 10 ■ Define editor appearance ■ Define what tags and styles are allowed ■ Define what plugin’s to load ■ Define database processing `RTE.proc`
  11. 11. Preset: default 11 ●
  12. 12. Preset: minimal 12 ●
  13. 13. Preset: full 13 ●
  14. 14. So I want my own preset 14
  15. 15. Add your own preset 15 // Register or own text-element config $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['text-element'] = 'EXT:config_examples/Configuration/RTE/TextElement.yaml'; ext_localconf.php
  16. 16. Configure your own preset 16 # Load default processing options imports: - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" } - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" } # Minimal configuration for the editor editor: config: toolbarGroups: - { name: basicstyles, groups: [ basicstyles ] } removeButtons: - Underline - Strike EXT:config_examples/Configuration/RTE/TextElement.yaml
  17. 17. Configure your own preset 17 editor: config: # Limit the height of the editor height: 200 extraPlugins: - justify removePlugins: - image YAML
  18. 18. CKEditor js to YAML CKEDITOR.editorConfig = function( config ) { config.toolbarGroups = [ { name: 'basicstyles', groups: [ 'basicstyles' ] } ]; config.removeButtons = 'Underline,Strike'; }; http://ckeditor.com/tmp/4.5.0-beta/ckeditor/samples/toolbarconfigurator/ js editor: config: toolbarGroups: - { name: basicstyles, groups: [ basicstyles ] } removeButtons: - Underline - Strike YAML
  19. 19. Define some custom style options 19 editor: config: stylesSet: # block level styles - { name: "Orange title H2", element: "h2", styles: { color: "orange", background: "blue" } } - { name: "Orange title H3", element: "h3", styles: { color: "orange", background: "blue" } } - { name: "Quote / Citation", element: "blockquote" } - { name: "Code block", element: "code" } # Inline styles - { name: "Yellow marker", element: "span", styles: { background-color: "yellow" } } yaml
  20. 20. Paragraph format options 20 editor: config: format_tags: "p;h2;h3;pre" http://docs.ckeditor.com/#!/guide/dev_format yaml
  21. 21. Migrate existing config 21
  22. 22. PageTS -> YAML editor: config: toolbar: - [ 'Bold', 'Italic', 'Underline', '-'] - [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] - [ 'NumberedList', 'BulletedList', '-', 'Indent', 'Outdent' ] - '/' - [ 'HorizontalRule', 'Link', 'RemoveFormat', '-' ] - [ 'Copy', 'Cut', 'Paste', '-', 'Undo', 'Redo' ] extraPlugins: - justify RTE.default { showButtons ( bold, italic, underline, left, center, right, justifyfull, orderedlist, unorderedlist, indent, outdent, line, link, removeformat, copy, cut, paste, undo, redo ) toolbarOrder ( bold, italic, underline, bar, left, center, right, justifyfull, orderedlist, unorderedlist, bar, indent, outdent, linebreak, line, link, removeformat, bar, copy, cut, paste, bar, undo, redo ) } pageTS yaml
  23. 23. Advanced Content Filter 23
  24. 24. Advanced Content Filter? 24 ■ Only tags/classes/styles that are configured are kept ■ Filters content during editing and paste ■ Enabled by default ■ Makes `processing` config most of the times obsolete “RTE.proc”
  25. 25. Disable Advanced Content Filter 25 editor: config: allowedContent: true YAML
  26. 26. Using your own preset 26
  27. 27. Set default RTE preset 27 RTE.default.preset = my_config PageTSconfig
  28. 28. Set preset in TCA 28 'content' => [ 'label' => 'LLL:EXT:lang/Res...eneral.xlf:LGL.text', 'config' => [ 'type' => 'text', 'cols' => 48, 'rows' => 5, 'enableRichtext' => true, 'richtextConfiguration' => 'minimal', ], ],
  29. 29. Using PageTS to define what specific preset to use 29 RTE { config { [table].[field].preset = something [table].[field].types.[type].preset = something } }
  30. 30. RTE { config { tt_content { bodytext { preset = minimal types { textmedia.preset = default my_ce.preset = full } } } } } Using PageTS to define preset to use 30
  31. 31. Plugins 31
  32. 32. Plugins delivered by TYPO3 32 ■ Default set provided by CKEditor typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/Contrib/plugins/ ■ typo3link ■ quicktables
  33. 33. Using a CKEditor core plugin 33 editor: extraPlugins: - justify YAML
  34. 34. Using external plugins 34 editor: externalPlugins: quicktable: { resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/quicktable/plugin.js" } typo3/sysext/rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml
  35. 35. Adding plugins 35 ■ Donwload from //ckeditor.com/addons/plugins ■ Add to EXT:my_ext/Resources/Public/Javascript/Plugins/* ■ Register it in your YAML as external plugin
  36. 36. Create your own plugin 36
  37. 37. Our goal 37 ■ A custom button in the toolbar of the RTE ■ Some magic happening when we click that button
  38. 38. So what do we need 38 ■ Our own plugin.js ■ Tell TYPO3 to use our plugin ■ An icon for our button
  39. 39. example_plugin.js 39 'use strict'; (function () { CKEDITOR.plugins.add('example_plugin', { init: function (editor) { console.log('example_plugin is loaded'); } }); })(); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  40. 40. Tell TYPO3 to use our plugin 40 # Load default processing options imports: - { resource: "EXT:rte_ckeditor/Configuration/RTE/Default.yaml" } editor: # Load my plugin as external plugin externalPlugins: example_plugin: { resource: "EXT:...path.../example_plugin.js" } EXT:config_examples/Configuration/RTE/PluginExample.yaml
  41. 41. Tell TYPO3 to use our plugin 41 // Register or own plugin-example config $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['plugin-example'] = 'EXT:config_examples/Configuration/RTE/PluginExample.yaml'; EXT:config_examples/ext_localconf.php
  42. 42. Tell TYPO3 to use our plugin 42 RTE.default.preset = plugin-example PageTS
  43. 43. The result 43
  44. 44. So let’s add a button 44
  45. 45. So let’s add our button 45 'use strict'; (function () { CKEDITOR.plugins.add('example_plugin', { init: function (editor) { editor.ui.addButton( 'ExamplePlugin', { label: 'My button', toolbar: 'basicstyles' }); } }); })(); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  46. 46. Select a visible toolbar 46 'use strict'; (function () { CKEDITOR.plugins.add('example_plugin', { init: function (editor) { editor.ui.addButton( 'ExamplePlugin', { label: 'My button', toolbar: 'basicstyles' }); } }); })(); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  47. 47. Cool we have a button 47
  48. 48. Add some magic to the button 48 CKEDITOR.plugins.add('example_plugin', { init: function (editor) { editor.ui.addButton( 'ExamplePlugin', { label: 'My button', toolbar: 'basicstyles', command: 'insertTimestamp' }); editor.addCommand( 'insertTimestamp', { exec: function( editor ) {} }); } }); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  49. 49. Add some magic to the button 49 editor.addCommand( 'insertTimestamp', { exec: function( editor ) { var now = new Date(); editor.insertHtml( 'The current date and time is: <em>' + now.toString() + '</em>' ); } }); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  50. 50. The magic works 50
  51. 51. But we want an icon 51
  52. 52. Register the icon 52 CKEDITOR.plugins.add('example_plugin', { init: function (editor) { icons: 'exampleplugin', editor.ui.addButton( 'ExamplePlugin', { label: 'My button', toolbar: 'basicstyles', command: 'insertTimestamp' }); … } }); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  53. 53. Yeah 53
  54. 54. next step adding some interaction 54
  55. 55. Let’s use the TYPO3 modal 55 CKEDITOR.plugins.add('example_plugin', { init: function (editor) { editor.ui.addButton( 'ExamplePlugin', { label: 'My button', toolbar: 'basicstyles', command: 'openExampleModal' }); editor.addCommand( 'openExampleModal', { exec: openModal }); } }); EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  56. 56. Let’s use the TYPO3 modal 56 … exec: openModal }); } }); function openModal(editor) { require([ 'TYPO3/CMS/Backend/Modal' ], function (Modal) { Modal.show( 'Example plugin', 'hi' ); }); } EXT:config_examples/Resources/Public/CkEditorPlugins/example_plugin.js
  57. 57. Our modal 57
  58. 58. Get the selected text 58 function openModal(editor) { var selection = editor.getSelection(), content = 'No text selected'; if (selection && selection.getSelectedText()) { content = '<em>You selected:</em> ' + selection.getSelectedText(); } require([ 'TYPO3/CMS/Backend/Modal' ], function (Modal) { Modal.show( 'Example plugin', content ); }); }
  59. 59. Some text selected 59
  60. 60. Do something with the selected text 60 require([ 'TYPO3/CMS/Backend/Modal' ], function (Modal) { if (selection && selection.getSelectedText()) { content = '<em>Remove:</em> ' + selection.getSelectedText(); Modal.confirm( 'Example plugin', content ) } else { Modal.show( 'Example plugin', content ); } });
  61. 61. Do something with the selected text 61 Modal.confirm( 'Example plugin', content ).on('confirm.button.cancel', function () { Modal.dismiss(); }).on('confirm.button.ok', function () { var range = editor.getSelection().getRanges()[0]; range.deleteContents(); range.select(); Modal.dismiss(); });
  62. 62. And the real interaction 62
  63. 63. Loading stuff over ajax 63
  64. 64. Tell TYPO3 what route you want to use 64 editor: # Load my plugin as external plugin externalPlugins: example_plugin: resource: "EXT:...path.../example_plugin.js" route: "configexamples_some_route" EXT:config_examples/Configuration/RTE/PluginExample.yaml
  65. 65. Open an modal with iframe 65 function openModal(editor) { var url = editor.config.example_plugin.routeUrl; require([ 'TYPO3/CMS/Backend/Modal' ], function (Modal) { Modal.advanced({ type: Modal.types.iframe, title: 'Example plugin', content: url, size: Modal.sizes.large }); }); }
  66. 66. But I don’t want to switch :( 66
  67. 67. Some things to consider 67 ■ Deprecated in TYPO3 8 LTS ■ Moved to FriendsOfTYPO3/rtehtmlarea for 9 ■ https://github.com/FriendsOfTYPO3/rtehtmlarea
  68. 68. Questions? 68
  69. 69. And now? 69 ■ github.com/frans-beech-it/t3ext-config_examples ■ github.com/netresearch/t3x-rte_ckeditor_image ■ typo3worx.eu/2017/02/configure-ckeditor-in-typo3/ ■ docs.typo3.org/typo3cms/extensions/core/Changelog/8.6/Featur e-79216-AddYAMLConfigurationForCKEditorRTE.html ■ docs.ckeditor.com/#!/api/CKEDITOR.config

×