<p>You can define entry types that are available from within CKEditor, per the docs: <a href="https://github.com/craftcms/ckeditor?tab=readme-ov-file#longform-content-with-nested-entries" rel="nofollow noreferrer">https://github.com/craftcms/ckeditor?tab=readme-ov-file#longform-content-with-nested-entries</a></p>
<p>In your case, you could create a 'button' entry type with fields including the link, the link text, and the 'button' style. For the button style, I'd probably use a dropdown field to allow user only specific types, outputing the classes for those directly to your template, e.g:</p>
<p>option.label: 'Primary button'
option.value: 'alo-base-button alo-button-red'</p>
<p>I think that would provide a more robust solution, that's easily extended and potentially re-used in other components.</p>

CC BY-SA 4.0
2024-11-13T12:09:18.517Z
This sounds like a very good solution indeed. I will check it out.
Merc
CC BY-SA 4.0
2024-11-13T12:31:20.830Z
I tried this but as we use craft cms in a headless way with graphql this might no be ready :(. So far I have not found any solutions, although they might seem on the way
Merc
CC BY-SA 4.0
2024-11-12T11:25:54.427Z
2024-11-12T14:03:38.150Z
2024-11-12T14:03:38.150Z
Seth Warburton
<p>I am using ckeditor with some extras to render a button.
This is part of my ckeditor config in the plugins settings</p>
<pre><code>link: {
      // Automatically add target=&quot;_blank&quot; and rel=&quot;noopener noreferrer&quot; to all external links.
      addTargetToExternalLinks: true,
      decorators: [
        {
          mode: 'manual',
          label: 'Render as Button',
          classes: ['alo-button-red', 'alo-base-button'],
          attributes: {
            role: 'button',
          }
        },
        {
          mode: 'manual',
          label: 'Render as Inverted Button',
          classes: ['alo-button-white', 'alo-base-button'],
          attributes: {
            role: 'button',
          }
        }
      ]
    }
</code></pre>
<p>This works as wanted, but the editor itself shows, after saving once, some wrong markup.
Here is the link after creation with decorator &quot;render as button&quot;.</p>
<img src="https://i.sstatic.net/trL3sSFy.png" width="500" alt="Image 1">
<p>Then after saving the preview looks like this:</p>
<img src="https://i.sstatic.net/2f0JO4QM.png" width="500" alt="Image 2">
<p>So you can see it has blue text, because the editor added a link inside my link.
When showing the source I get:</p>
<img src="https://i.sstatic.net/V00oAzLt.png" width="500" alt="Image 3">
<p>Resulting in two nested <code>a</code> tags.
Luckily in my frontend I still get only one a tag.</p>
<img src="https://i.sstatic.net/EXjEfjZP.png" width="300" alt="Image 4">
<p>But when I edit some things in my wysiwyg editor it happens that those a tags get messed up resulting in a break of all the button code.</p>
<p>Does anybody know why this is happening?</p>

CC BY-SA 4.0
2024-11-04T13:33:20.157Z
In the interests of robust content modelling and future-proofing I'd advise against allowing editors to add buttons directly in a rich text editor. There are plenty of alternative approaches that will serve your needs better in the long run.
James Smith
CC BY-SA 4.0
2024-11-05T14:10:56.397Z
We have not used this approach for years now and you just trade them in for other problems. We'll give this approach a shot this time. Creating richtexts following custom buttons and then again richtexts brings problems with styling for spacing between, which is no in the control of the editor and also brings more configuration effort on the developers side. Furthermore the CP gets crowded with elements (especially when taking into account that one button now needs for fields (target, link, button style and link text).
Thanks for sharing your concerns, but we stick to the plan ;).
Merc
CC BY-SA 4.0
2024-11-12T10:27:10.940Z
Agree with James, I don't think this is the right approach. This seems like a very fragile way to do things; as you are discovering. You could add a linky-button entry type to CKeditor, or just add a block type for styled links. Both will prevent editors from accidentally messing things up, which I think is a better approach. An editor should not be able to easily break things, it's the developers job to ensure that.
Seth Warburton
CC BY-SA 4.0
2024-11-12T10:28:35.483Z
…and forcing all external links to open in new tabs is a terrible UX.
Seth Warburton
CC BY-SA 4.0
2024-11-12T11:07:37.127Z
@SethWarburton thanks for your input. Could you clarify how I would do that. How would I add a `linky-button entry`?
With the block style I would add a link and then give the option to wrap a block style around the button to make them appear differently? Is that correct?
Merc
CC BY-SA 4.0
2024-11-12T11:10:33.737Z
And about the external link, I think it is much worse UX to not even give that option at all, leaving all external links to open in the same window: https://ibb.co/K2Hdyvc

Maybe I am missing something, but ckeditor does not include that (see also: https://ckeditor.com/ckeditor-5/demo/feature-rich/)

(Edit: I solved this by adding a decorator for external links. I still think this should be a default feature though)
Merc
CC BY-SA 4.0
2024-11-14T13:42:17.700Z
It's not a default because it's terrible UX. You're not providing options, you are removing them. All users already have an option to open links in a new tab, if they want to do that. Taking away that choice is insensitive to user needs, i.e. poor UX.
Seth Warburton
<richtext><link><wysiwyg><ckeditor5>
ckeditor: custom a tag is doubled
# ckeditor: custom a tag is doubled

(Asked by: username_0 on 2024-11-03)

I am using ckeditor with some extras to render a button.
This is part of my ckeditor config in the plugins settings
link: {
      // Automatically add target="_blank" and rel="noopener noreferrer" to all external links.
      addTargetToExternalLinks: true,
      decorators: [
        {
          mode: 'manual',
          label: 'Render as Button',
          classes: ['alo-button-red', 'alo-base-button'],
          attributes: {
            role: 'button',
          }
        },
        {
          mode: 'manual',
          label: 'Render as Inverted Button',
          classes: ['alo-button-white', 'alo-base-button'],
          attributes: {
            role: 'button',
          }
        }
      ]
    }

This works as wanted, but the editor itself shows, after saving once, some wrong markup.
Here is the link after creation with decorator "render as button".

Then after saving the preview looks like this:

So you can see it has blue text, because the editor added a link inside my link.
When showing the source I get:

Resulting in two nested a tags.
Luckily in my frontend I still get only one a tag.

But when I edit some things in my wysiwyg editor it happens that those a tags get messed up resulting in a break of all the button code.
Does anybody know why this is happening?

**Tags:** richtext, link, wysiwyg, ckeditor5
> **Comments:**
> **username_1**: In the interests of robust content modelling and future-proofing I'd advise against allowing editors to add buttons directly in a rich text editor. There are plenty of alternative approaches that will serve your needs better in the long run.  
> **username_0**: We have not used this approach for years now and you just trade them in for other problems. We'll give this approach a shot this time. Creating richtexts following custom buttons and then again richtexts brings problems with styling for spacing between, which is no in the control of the editor and also brings more configuration effort on the developers side. Furthermore the CP gets crowded with elements (especially when taking into account that one button now needs for fields (target, link, button style and link text). Thanks for sharing your concerns, but we stick to the plan ;).  
> **username_2**: Agree with James, I don't think this is the right approach. This seems like a very fragile way to do things; as you are discovering. You could add a linky-button entry type to CKeditor, or just add a block type for styled links. Both will prevent editors from accidentally messing things up, which I think is a better approach. An editor should not be able to easily break things, it's the developers job to ensure that.  
> **username_2**: …and forcing all external links to open in new tabs is a terrible UX.  
> **username_0**: @SethWarburton thanks for your input. Could you clarify how I would do that. How would I add a `linky-button entry`? With the block style I would add a link and then give the option to wrap a block style around the button to make them appear differently? Is that correct?  
> **username_0**: And about the external link, I think it is much worse UX to not even give that option at all, leaving all external links to open in the same window: https://ibb.co/K2Hdyvc  Maybe I am missing something, but ckeditor does not include that (see also: https://ckeditor.com/ckeditor-5/demo/feature-rich/)  (Edit: I solved this by adding a decorator for external links. I still think this should be a default feature though)  
> **username_2**: It's not a default because it's terrible UX. You're not providing options, you are removing them. All users already have an option to open links in a new tab, if they want to do that. Taking away that choice is insensitive to user needs, i.e. poor UX.  

---

## 1 answers

### Answer by username_2 on 2024-11-12. Score: 0

You can define entry types that are available from within CKEditor, per the docs: <https://github.com/craftcms/ckeditor?tab=readme-ov-file#longform-content-with-nested-entries>

In your case, you could create a 'button' entry type with fields including the link, the link text, and the 'button' style. For the button style, I'd probably use a dropdown field to allow user only specific types, outputing the classes for those directly to your template, e.g:

option.label: 'Primary button'
option.value: 'alo-base-button alo-button-red'

I think that would provide a more robust solution, that's easily extended and potentially re-used in other components.

> **Comments:**
> **username_0**: This sounds like a very good solution indeed. I will check it out.  
> **username_0**: I tried this but as we use craft cms in a headless way with graphql this might no be ready :(. So far I have not found any solutions, although they might seem on the way  

---

