27

I wanted to configure the toolbar in CKEDITOR 5. I took a look at the documentation.

https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/builds/guides/integration/configuration.html

Yet, the only script related to my question is:

Array.from( editor.ui.componentFactory.names );

It is way too difficult for a frontend programmer to understand. Where do I put this script? How do I output the results? Is there a detailed tutorial?

Matter fact, it would be nice if CKEDITOR simply put the available items in the documentation. That will save a hell lot of troubles.

Thanks!

stonyau
  • 2,132
  • 1
  • 20
  • 18

9 Answers9

27

You can put this code right in the body of code samples which you can find e.g. in CKEditor 5 Build's Basic API guide. For example:

ClassicEditor
    .create( document.querySelector( '#editor' ) )
    .then( editor => {
        console.log( Array.from( editor.ui.componentFactory.names() ) );
    } )
    .catch( error => {
        console.error( error );
    } );

As @Szymon Cofalik mentioned in his answer – there's no single list of buttons which are available in all builds. CKEditor 5 builds may differ not only visually – they may also contain different plugins and hence different buttons. So, using that code snippet is the safest and future-proof solution.

Blizzardengle
  • 992
  • 1
  • 17
  • 30
Reinmar
  • 21,729
  • 4
  • 67
  • 78
  • Thank you so much! Now I have another question: I can't find a button/feature to show source html code in the textarea. Is there a function like this in CKEDITOR5? – stonyau Nov 24 '17 at 15:13
  • 1
    Check out https://github.com/ckeditor/ckeditor5/issues/592. This topic explains why the source view feature doesn't make sense (in the form you know it from other editors). – Reinmar Nov 25 '17 at 17:10
  • There is a semi-colon that should be removed from that line that has two semi-colons in it. – Magmatic Mar 07 '18 at 19:26
  • I'm using CK5 with VueJS. I'm assigning 'ClassicEditor' to data property 'editor'. Yet, when I attempt to log the available names from it, 'ui' is undefined. How to access the available names when my editor is used in Vue? – Jay Nov 28 '19 at 13:49
  • 2
    I understand about the different builds, and about the documentation. But each 'build' has its own buttons, right? So why we gotta stumble across this "snippet" buried in the docs & figure out how to implement it (they provide the command, but no info about where to put it or how)? They could have put all the buttons in THAT build in the toolbar by default. Easier for the user/developer than hunting around their docs. – McAuley Oct 09 '20 at 05:35
16

you can use console.log( Array.from( editor.ui.componentFactory.names() ) ); which will give you:

["undo", "redo", "bold", "italic", "blockQuote", "ckfinder", "imageTextAlternative", "imageUpload", "heading", "imageStyle:full", "imageStyle:side", "link", "numberedList", "bulletedList", "mediaEmbed", "insertTable", "tableColumn", "tableRow", "mergeTableCells"]

Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58
8

Example code you can use to list available toolbar

var editor = ClassicEditor
    .create(document.querySelector('#editor'), {
        toolbar: ['headings', 'bold', 'italic', 'link', 'bulletedList', 'numberedList'],
        heading: {
            options: [
                {modelElement: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph'},
                {modelElement: 'heading1', viewElement: 'h1', title: 'Heading 1', class: 'ck-heading_heading1'},
                {modelElement: 'heading2', viewElement: 'h2', title: 'Heading 2', class: 'ck-heading_heading2'},
                {modelElement: 'heading', viewElement: 'h3', title: 'Heading 3', class: 'ck-heading_heading3'}
            ]
        }
    })
    .then(function (editor) {
        console.log(Array.from(editor.ui.componentFactory.names()));
    });
Izhari Ishak Aksa
  • 858
  • 10
  • 13
  • 3
    This used to work but seems to have stopped working recently. I'm getting an error when I add an options array to the heading object. – shanzilla May 04 '18 at 19:02
6

For anyone coming here wondering how to make use of the Array.from(editor.ui.componentFactory.names()) solution (as described in the other answers) in Angular (e.g. Angular 8), here is a description. If you try to do it in ngOnInit or ngAfterViewInit, it is too early and you will get something like Cannot read property 'ui' of null. You need to listen for the ready event from the ckeditor and query the names at that point as follows.

In your component template code, give the editor an id and listen for the ready event:

<ckeditor
    #editor
    [editor]="Editor"
    [config]="config"
    (ready)="onEditorReady($event)">
</ckeditor>

Then in your component typescript code, add a @ViewChild annotation and implement onEditorReady as follows:

@ViewChild('editor', {static: false})
editorComponent: CKEditorComponent;

onEditorReady(event: any): void {
    const toolbarItems = Array.from(this.editorComponent.editorInstance.ui.componentFactory.names());
    console.log('Available toolbar items: ' + toolbarItems.join(', '));
}

You will then see something like this in the console:

Available toolbar items: undo, redo, bold, italic, blockQuote, ckfinder, imageTextAlternative, imageUpload, heading, imageStyle:full, imageStyle:side, indent, outdent, link, numberedList, bulletedList, mediaEmbed, insertTable, tableColumn, tableRow, mergeTableCells

user2846469
  • 2,072
  • 3
  • 18
  • 32
4

It is difficult to keep plugin names in one place in documentation because:

  • There are multiple builds which differs,
  • New plugins are developed and added.

If you want to check what toolbar items are available in the build you are currently using, open developer's console in the browser you are using and execute the quoted line of code

Array.from( editor.ui.componentFactory.names );

Of course, editor has to be the editor instance.

I hope this answers your question.

EDIT: Creating editor is described in the documentation too. But you have to assign editor instance to editor variable.

For example:

ClassicEditor
    .create( document.querySelector( '#editor' ) )
    .then( editor => {
        window.editor = editor;
        // Or alternatively you could paste that line here and look at console.
    } );
Szymon Cofalik
  • 1,142
  • 8
  • 9
3

Adding to @DestinyB answer - perhaps a simpler solution for Vue - just listen for @ready="onReady" on the ckeditor component, and in the onReady method:

onReady(event) {
   console.log(Array.from(event.ui.componentFactory.names()));
},
Anoiny
  • 376
  • 4
  • 6
2

Adding to @user2846469 Response, It can be achieved in vue.js simply by the sample below;

import ClassicEditorfrom '@ckeditor/ckeditor5-build-classic';

export default {
data() {
return {
    editor: ClassicEditor,
    editorData: '',
    editorConfig: {}
 },
 mounted() {
            console.log(this.editor.builtinPlugins.map( plugin => plugin.pluginName ));
        }
 }
}
 
1

In React

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';




export default class AddArticle extends Component {




    
    render() {

        return <CKEditor config={EditorConfig} editor={ClassicEditor} onReady={(event) => {
   console.log(Array.from(event.ui.componentFactory.names()))}} /> 
    }
}



Bambier
  • 586
  • 10
  • 16
0

This is what I get for ClassicEditor [ "selectAll", "undo", "redo", "bold", "italic", "blockQuote", "uploadImage", "imageUpload", "heading", "imageTextAlternative", "toggleImageCaption", "imageStyle:inline", "imageStyle:alignLeft", "imageStyle:alignRight", "imageStyle:alignCenter", "imageStyle:alignBlockLeft", "imageStyle:alignBlockRight", "imageStyle:block", "imageStyle:side", "imageStyle:wrapText", "imageStyle:breakText", "indent", "outdent", "link", "numberedList", "bulletedList", "mediaEmbed", "insertTable", "tableColumn", "tableRow", "mergeTableCells" ]

kheya
  • 7,546
  • 20
  • 77
  • 109