TYPO3 11.5 - CKEditor keeps replacing specific tags on loaded HTML with non-breaking spaces - ckeditor

In my TYPO3 project (v11.5.20 via composer), I want the included RTE CKEditor to be able to work with - not necessarily display though - boxicons, which are formatted as simple HTML tags like this: <i class="bxs bx-bank"></i>. I made sure that the processing options of the RTE are allowing this tag, which I can confirm as both the frontend page and the network data delivered on loading the editing frame for a content element are properly including the tag.
When editing the content element though, once I switch to the source code view of CKEditor, the i tag has been replaced with a , for reasons I cannot figure out. I've read about CKEditor's Advanced Content Filter and how it processes HTML input apart from TYPO3's HTMLParser, and that it could be disabled by setting the editor.config.allowedContent option in your custom RTE preset to true, but this has no effect for me somehow. My preset looks like this, which is basically the default preset of CKEditor with some minor changes:
imports:
# - { resource: "EXT:lraffb_intern/Configuration/RTE/Processing.yaml" }
- { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" }
- { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" }
- { resource: "EXT:rte_ckeditor_image/Configuration/RTE/Plugin.yaml" }
editor:
config:
allowedContent: true
format_tags: "p;h1;h2;h3;h4;h5;pre"
toolbarGroups:
- { name: styles, groups: [ styles, format ] }
- { name: basicstyles, groups: [ basicstyles ] }
- { name: paragraph, groups: [ list, indent, blocks, align ] }
- { name: links, groups: [ links ] }
- { name: clipboard, groups: [ clipboard, cleanup, undo ] }
- { name: editing, groups: [ spellchecker ] }
- { name: insert, groups: [ insert ] }
- { name: tools, groups: [ table, specialchar, insertcharacters ] }
- { name: document, groups: [ mode ] }
justifyClasses:
- text-left
- text-center
- text-right
- text-justify
extraPlugins:
- justify
- autolink
- editorplaceholder
removeButtons:
- Anchor
- Underline
- Strike
- Styles
(Note that I've resorted to legacy RTE processing via TSConfig since some options in the custom Processing.yaml did not work reliably somehow. The TSConfig code is quite verbose so I'll provide only when required.)
Does someone know what could cause this and how to fix it?

⚠ There are several hurdles to overcome here, but everything is feasible in some form. It should be remembered that this configuration is relatively tricky, mainly because security-related issues are involved here, of course. An input of content goes through several stages of verification:
The CKEditor only allows certain content and must receive appropriate instructions.
TYPO3 also needs permission to store certain content in the database.
Content is additionally processed with a sanitizer during output in the frontend.
You can solve this as follows (tested with TYPO3 v10/v11 with CKEditor v4):
First you should always use span instead of the HTML tag i, because this would be syntactically more correct and you have less problems with the configuration.
Also, the CKEDitor converts italic to em by default.
Another common mistake when configuring the CKEditor is to use allowedContent: true.
This basically creates a security hole in the editor and makes the concept of secure input useless.
Instead, you should always explicitly allow a specific HTML tag or attribute.
You can do this with the following statement in your YAML configuration:
editor:
config:
extraAllowedContent:
# Allow class-attribute
- span(*)[class]
# Allow all attributes
#- span(*)[*]
Further note that without the help of a JavaScript plugin for the CKEditor, empty tags are generally removed, so you would have to add a space.
You can of course solve this directly with a CKEditor plugin, and give the CKEditor the following instruction:
CKEDITOR.dtd.$removeEmpty.span = 0;
If you don't or can't use JavaScript, an icon would always have to be entered with a space:
<span class="bxs bx-bank"> </span>
Depending on your configuration you might have to allow saving CSS classes in the span tag.
You do this either in PageTSconfig:
RTE.default.proc {
# Allow additional attributes in SPAN-tags on the way from RTE to DB
HTMLparser_db.tags.span.allowedAttribs := addToList(class)
}
...or in the YAML configuration of the CKEditor (Processing):
processing:
## CONTENT TO DATABASE
HTMLparser_db:
tags:
span:
allowedAttribs:
- class
Finally I can recommend a nice TYPO3 extension that does all that (and more) for you, and offers you various icon sets (including Boxicons) for use in TYPO3:
https://github.com/quellenform/t3x-iconpack
https://github.com/quellenform/t3x-iconpack-boxicons

Related

CKEditor 5 - Using HTML inside mentions

I have been using mentions in CKEditor 5 to tag certain system variables. A typical tag looks like as:
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
#ApprovedCosts
</span>
When I try to render the following (the idea is to show the variable value when the user clicks preview, while he continues editing):
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
<p>Nice rendered <b>html</b></p>
</span>
CKEditor goes bonkers.
My requirement is to show a nicely formatted variable name inside the tag. I know I can control via CSS, but there could be a situation where I might end-up rendering a small table (if variable points to a data set), etc.
Help will be appreciated.
Cheers.
Generally speaking, CKEditor 5 documentations refrain from going with your basic plain HTML approach, as seen in the comments:
This plugin customizes the way mentions are handled in the editor model and data.
Instead of a classic <span class="mention"></span>,
Within their mentions documentation (by the way, highly suggested to take a look at - it's very well documented with lots of useful examples in case you're stuck!), they're defining a ClassicEditor (to be precise, they want to mimic a chat platform in which you can tag a user and will receive a list of users in return).
ClassicEditor
.create( document.querySelector( '.chat__editor' ), {
extraPlugins: [ Essentials, Paragraph, Mention, MentionLinks, Bold, Italic, Underline, Strikethrough, Link ],
toolbar: {
items: [
'bold', 'italic', 'underline', 'strikethrough', '|', 'link', '|', 'undo', 'redo'
]
},
mention: {
feeds: [
{
marker: '#',
feed: [
{ id: '#cflores', avatar: 'm_1', name: 'Charles Flores' },
[...]
],
itemRenderer: customItemRenderer
[...]
After the mention object is created, they're calling the customItemRenderer function. This infrastructure could nearly identical be copied. For your part the function MentionLinks is important, as you can customize how mentions are handled, i.e. let's take a look at their example:
function MentionLinks( editor ) {
editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'a',
key: 'data-mention',
classes: 'mention',
attributes: {
href: true
}
},
model: {
key: 'mention',
value: viewItem => editor.plugins.get( 'Mention' ).toMentionAttribute( viewItem )
},
converterPriority: 'high'
} );
Basically, you can customize all the properties within the MentionLinks function. CKEditor 5 did a good job documenting the mention plugin very hierarchically:
The documentation can be found here.
On a slight off-topic note I noticed your code passage <p>Nice rendered <b>html</b><p> contains little formality issues, i.e. you need to close the <p> tag by assigning a close tag </p>:
<p>Nice rendered <b>html</b></p>
Though I'm pretty sure that's not the error as you're talking about HTML in general and not only this code passage.
I think your main issue is your tags. Your paragraph tags (<p>) don't have a closing tag, only two opening tags. It should be <p>***your text here***</p>. If this doesn't fix the issue, please leave a comment.

TYPO3: CKEditor strips data-attributes in <span>-Tags

I want to use a data-attribute in a span-Tag. The CKEditor removes this attribute.
If I add it in a p-Tag it will not removed and this is OK.
processing:
allowAttributes: [data-count]
is added in the YAML-file.
I've tried this and other combinations, nothing works.
config
extraAllowedContent: '*(*)[data-*]'
What do I have to do, to keep the data-attribute in a span-Tag?
I have done this for iframe tag with attribbuts, no allowAttributes used for this:
processing:
allowTags:
- iframe
editor:
config:
extraAllowedContent:
- iframe[*]
for you this should do the trick:
editor:
config:
extraAllowedContent:
- span[*]

CKEditor 5 links: Set default target for links or edit target

In CKEditor 5 I don't see field for target attribute in link dialog.
How to add such field? Or set target=_blank as default.
Thanks
Since version 11.1.0 of a Link Plugin, there is added link decorator feature. This feature provides an easy way to define rules when and how to add some extra attributes to links.
There might be manual or automatic decorators.
First provides a UI switch which might be toggled by the user. When the user edits a link and toggles it, then preconfigured attributes will be added to the link e.g. target="_blank".
Second one, are applied automatically when content is obtained from the Editor. Here you need to provide a callback function which based on link's URL decides if a given set of attributes should be applied.
There is also a preconfigured decorator, which might be turn on with simple config.link.addTargetToExternalLinks=true. It will add target="blank" and rel="noopener noreferrer" to all links started with: http://, https:// or //.
You can achieve it by adding this code in CKEditor Initialization Script:
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ...
link: {
decorators: {
openInNewTab: {
mode: 'manual',
label: 'Open in a new tab',
defaultValue: true, // This option will be selected by default.
attributes: {
target: '_blank',
rel: 'noopener noreferrer'
}
}
}
}
} )
.then( ... )
.catch( ... );
Here is the Documentation Link . It will be working fine.

Classes for Apostrophe Rich Text Widget

I've run into an issue passing classes to the Apostrophe Rich Text Widget. I've updated the sanitizeHtml document, and I'm able to pass one custom class, but as soon as I try to add multiple classes in the widget stops working (at least the style selector does).
{{ apos.singleton(data.page, 'servicesSubtitle', 'apostrophe-rich-text', {
toolbar: [ 'Styles' ],
styles: [
{
name: 'Services Subtitle',
element: 'h3',
attributes: {
class: 'sub-title primary-color'
}
}
],
class
controls: {
movable: false,
removable: false
}
}) }}
This works if I only have:
attributes: {
class: 'sub-title'
}
but doesn't when trying to pass two classes. I'm assuming there's something wonky with passing a space to that parameter, since it always grabs the first chunk of text, but I could be totally wrong about that. I figure I'm missing something really obvious, but cant figure it out or find any docs about it.
Any help would be appreciated!
This is a known CKEditor bug that the Apostrophe team hasn't quite pinned down. Multiple classes WILL work in certain cases (change the order, try different phrases)
This is a crummy answer. We'd love a contribution!

Ckeditor bullets and numberedlists are not displaying in result

I have applied ckeditor on a textarea . it display bold and italic txext as it is but does not display numbered lists and bulletlist in results when i fetch from database. Instaead it encapsulte whole text in ol/ul tags.
A secretary, personal assistant, or administrative assistant is a person whose work consists of supporting management, including executives, using a variety of project management,
communication, or organizational skills. These functions may be entirely carried out to assist one other employee or may be for the benefit of
more than one. In other situations a secretary is an officer of a society or organization
who deals with correspondence, admits new members, and organizes official meetings and events
Jquery code to apply ckeditor:
$(document).ready(function(){
//Applying ckeditor on provider msg textarea.
CKEDITOR.replace( 'responsibilities',
{
uiColor: '#6C518F',
toolbar: [
{ name: 'basicstyles', items : [ 'Bold','Italic','TextColor',"BGColor", 'NumberedList','BulletedList' ] },
{ name: 'tools', items : [ 'Maximize','-' ] }
],
removePlugins : 'elementspath'
});
})
It's caused most likely by:
Either some backend filtering which strips lists.
Or styling of your webpage, which sets list-style-type to none.
If none of these is true, please clarify your question.
I also faced same issue while using ckeditor in Angular. When we fetch the data from the editor it shows with ul/li tag. Actually it is applying the bulleted list to the editor but it is not visible to us. So we just need to increase the padding so that it can be visible to us.
.ck-editor__editable_inline {
padding: 0 30px !important;
}
Removing list-style-type to none resolved my issues.

Resources