Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding classes to links in CKeditor

I have some specific requirements around adding classes to links in ckeditor5 - I have read the docs and tried numerous approaches but I'm still struggling to achieve what I want here. My requirements are:

  1. All links added (whether using the link UI, or via paste) must have a class assigned. That class should be set to defaultClass if no class is assigned or the class assigned is not in the list of valid classes

  2. Link classes must be in the list of valid link classes

I have built a dropdown containing a list of the valid classes and added it to the link interfaceLink class dropdown

Here is the code I have so far:

    const { editor } = this

    const linkClasses = editor.config.get('link.options.classes')
    const defaultLinkClass = editor.config.get('link.options.defaultClass')

    editor.model.schema.extend('$text', { allowAttributes: 'linkClass' })

    editor.conversion.for('downcast').attributeToElement({
      model: 'linkClass',
      view: (attributeValue, writer) => writer.createAttributeElement('a', { class: attributeValue }, { priority: 5 }),
      converterPriority: 'low'
    })

    editor.conversion.for('upcast').attributeToAttribute({
      view: {
        name: 'a',
        key: 'class'
      },
      model: 'linkClass',
      converterPriority: 'low'
    })
like image 649
Paul Odeon Avatar asked Sep 12 '19 12:09

Paul Odeon


2 Answers

The key to the solution is in the upcast converter - I eventually stumbled on to: https://stackoverflow.com/a/55019124/803804

This led me to realise you can pass a callback into the attributeToAttribute converter https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_conversion_upcasthelpers-UpcastHelpers.html#function-attributeToAttribute

Really simple in the end:

editor.conversion.for('upcast').attributeToAttribute({
  view: {
    name: 'a',
    key: 'class'
  },
  model: {
    key: 'linkClass',
    value: viewElement => {
      if(this.classes.includes(viewElement.getAttribute('class'))) {
        return viewElement.getAttribute('class')
      } else {
        return this.defaultClass
      }
    }
  },
  converterPriority: 'low'
})
like image 58
Paul Odeon Avatar answered Sep 19 '22 12:09

Paul Odeon


Use callback function in decorators and inside the callback, use setTimeout function to check the valid class list in the urls.

Check the jsFiddle. Refer CKEditor5 manual decorators in Links for more and please confirm the Link plugin installed @ckeditor/ckeditor5-link

Hope this will help.

Thank You

like image 44
Nishal K.R Avatar answered Sep 17 '22 12:09

Nishal K.R