ckeditor5
ckeditor5 copied to clipboard
Possible to make editor.getData() returns content with inline styles?
Hi,
Thanks for the new CKEditor (to me it's new).
Here is my question:
When inserting tables, we get content by editor.getData() like:
<figure class="table"><table><tbody><tr><td>....... <table></figure>
In my case, what I actually want is:
<table style="border: 1px solid #ccc...">....</table>
The reason is that the content will be used again in another WYSIWYG editor and finally sent as email and we expect who received the email would see a decently styled email.
Any help would be appreciated.
If you'd like to see this feature implemented, add 👍 to this post.
Hello, @nakupanda! Basically, it's possible to achieve the result you mentioned, but it requires changing all downcast converters.
I'll confirm your issue as a feature request. We might create API for this purpose and the feature could be called "inlining styles". Anyway, we can't declare any ETA for this one right now.
@Mgsy Great! Thank you for looking at this.
For now I'm switching back to CKEditor 4 for my purpose.
Hi @Mgsy ,I think this feautre is very important.May I know when this feature will be supported? Thanks.
Hi @Mgsy ,I think this feautre is very important.May I know when this feature will be supported? Thanks.
Hi @mengjoel, we understand that this feature might be important for you. However, unfortunately, due to other priorities, we don't have ETA for it.
Feel free to add 👍 to the first post, it will allow us to track a popularity of this request.
The same goes for images. This is especially important if they are to be used in email templates.
May I know when this feature will be supported? Thanks.
I like the case mentioned in #8004 by @justlester:
Hi! I am using the CKEditor 5 for creating email content.
When I get output data from the editor, the image output in HTML have class styles of "image-style-right":<figure class="image image_resized image-style-align-right" style="width:484px;"> <img src="https://c.cksource.com/a/1/img/docs/sample-image-bilingual-personality-disorder.jpg"> <figcaption>One language, one person.</figcaption> </figure>What I need is:
<figure style="width:484px; float:right;margin: 16px 0 16px 24px;"> <img style="width:100%" src="https://c.cksource.com/a/1/img/docs/sample-image-bilingual-personality-disorder.jpg"> <figcaption style="text-align:center; padding: .6em;font-size: .75em;">One language, one person.</figcaption> </figure>Without the styles, I can't display the image properly. I read the documentation but I'm not sure what APIs I will be using.
What it shows is that it's not only about the <figure> itself but also about all the elements inside that might've been styled by a selector consisting of figure.image.
IMO, the same applies to all styles that might've been applied to the content. That includes styles for p, h1, blockquote, etc. The editor does not come with styles for these elements, but the page on which it is integrated usually does. And when trying to reflect the same styles in an email or a different medium (we had the same problem with export to PDF), it's best if these styles are inlined.
Therefore, I think we should consider a mechanism capable of inlining an entire set of styles. It'd be best if it simply combined output HTML + stylesheets.
I too use the ckeditor5 to generate HTML for sending as email content. Without the styling inline the recipient doesn't get what we see on screen.
I temporarily got around this issue with juice:
- First, I've removed
ck-contentprefix from Content Styles and stored it for later use:
const styles = `<styles>
:root {
--ck-color-mention-background: hsla(341, 100%, 30%, 0.1);
--ck-color-mention-text: hsl(341, 100%, 30%);
--ck-highlight-marker-blue: hsl(201, 97%, 72%);
--ck-highlight-marker-green: hsl(120, 93%, 68%);
--ck-highlight-marker-pink: hsl(345, 96%, 73%);
--ck-highlight-marker-yellow: hsl(60, 97%, 73%);
--ck-highlight-pen-green: hsl(112, 100%, 27%);
--ck-highlight-pen-red: hsl(0, 85%, 49%);
--ck-image-style-spacing: 1.5em;
--ck-todo-list-checkmark-size: 16px;
}
/* ckeditor5-highlight/theme/highlight.css */
.marker-yellow {
background-color: var(--ck-highlight-marker-yellow);
}
/* and so on.. */
</styles>`;
- Installed juice:
yarn add juice; - and lastly, converted what was typed into inline styles:
import InlineEditor from '@ckeditor/ckeditor5-editor-inline/src/inlineeditor';
import CKEditor from '@ckeditor/ckeditor5-react';
import juice from 'juice';
<CKEditor
editor={InlineEditor}
data=""
onChange={(event, editor) => {
const data = editor.getData();
console.log(juice.inlineContent(data, styles));
}}
/>
Worked weel when using CKEDITOR plugins and sending inlined datas as email body.
ps: base64 images doesn't works with major email clients, so I've disabled inline images as this are not one of my requirements ps2: I will be glad to see an official solution
en.. and i very hope support this feature.
We have a need to use the contents of the editor as the body of emails. Most Email clients ignore any non-in-line CSS so we are very interested in an option to output all in-line styles. Thank you!
I was panicking that juice was not working in my nuxt project, the installation failed, but when i reinstall the node_modules i was able to install juice.js 7.00 version currently
I was able to create a temporary solution with Vue2 based from @ogabrielsantos's answer. I created a custom component with the following plugins:
- @ckeditor/ckeditor5-vue2
- juice (needed to convert styles to inline styles)
- postcss-css-variables (needed to convert css variables to static values)
Vue.component('ckeditor5-textarea',{
template: /*html*/`
<ckeditor :editor="editorBuild" :config="config" v-model="innerEditorValue" @ready="onEditorReady" @input="onEditorChange"></ckeditor>
`,
components: {
ckeditor: CKEditorSource.Vue2CKEditor.component
},
props: {
value: {
type: String,
default: ''
},
config: {
type: Object,
default: ()=>({
toolbar: {
items: [
'undo',
'redo',
'|',
'removeFormat',
'bold',
'italic',
'underline',
'link',
'numberedList',
'bulletedList',
],
},
})
}
},
data(){
return {
editorBuild: CKEditorSource.Editor,
lastValue: '',
innerEditorValue: '',
editorStyles: '',
}
},
mounted() {
//get ckeditor styles, convert css variables to static using postcss-css-variables
//and save to editorStyles for later use
var stylesObj = Array.from(document.getElementsByTagName('style')).find(x=>x.hasAttribute("data-cke"));
this.editorStyles = CKEditorSource.EditorUtils.postcss([CKEditorSource.EditorUtils.cssvariables()]).process((stylesObj ? stylesObj.innerHTML : '')).css;
},
watch: {
value(newVal,oldVal){
//prevents undo stack from clearing unless new value is being passed to v-model
if(newVal !== oldVal && newVal !== this.lastValue){
this.innerEditorValue = (newVal || '');
}
}
},
methods: {
onEditorReady(editor){
//set editor value after created
this.innerEditorValue = this.value || '';
this.$emit('ready',editor);
},
onEditorChange(value){
//with the editorStyles, convert using juice
//and emit back the value with the inline style
var htmlWithInlineStyles = CKEditorSource.EditorUtils.juice.inlineContent(`<div class="ck-content">${value}</div>`,this.editorStyles);
var div = document.createElement('div');
div.innerHTML = htmlWithInlineStyles;
var currentData = div.firstChild ? div.firstChild.innerHTML : '';
//set the lastValue
var d = this.lastValue = currentData;
this.$emit('input',d);
},
},
});
for me installing Juice with ckeditor 5 version 28.0.0 cause the ckeditor to not display on the page after building the js file. why couldnt it be built simplier, like emailStyleFormat: true or false (if false use the bootstrap classes, else used the styling for Outlook). All I want is to see the colors (font colors, background colors, table borders and highlight colors) to be supported with Outlook emails.
what's the easiest method (how to downcast in using legacy styling instead)
Any status update on this request? Seems like a potential blocker to using CKEditor5 if the purpose is to create emails. Has any work arounds been established to support this email build use case in 5?
This feature is very important! Please help us get this thing faster, breaking changes between ck4 and ck5 should be prioritize...
** After further checking it seems most classes are required with .ck.ck-content and when showing them on other screens/emails style must be added... This is a problem to solve as soon as possible...
I think this feature is very important. At least for web we can solve this issue with adding full css to our document. What about mobile application? Because rich text content can be rendered also for mobile devices.
Hi, it's 2022 and this is still a feature that is not in the editor? I'm frankly astonished that this is not included as default prop to react component / setting in the CKEditor. You even advertise the editor as being suitable for email content.
What's going on? 3 years later?
This is blocking issue for us to start using CKEditor5 to compose email templates. I don't see the point of composing html with css classes that are only defined in the scope of CKEditor5, and are not included in the final html result.
Or you include the css classes definitions as part of the html result inside <style> or you include all of those as inline styles as <table style="...">
If not the html composed it's only properly visible inside the CKEditor5 box, but not outside of it..
I want to add my comment that this is a really important feature. I just finished implementing email templates using ckeditor5 before realizing that styles don't translate over into email clients. Inlining the styles is extremely important for content portability beyond just the email use case. Hopefully we will hear an update on this request soon...
hi, this is my temporary solution 😁
- get content styles.
- get editor content value.
- use juice convert styles to inline styles.
import juice from 'juice';
const CkeditorUtil = {
getEditorStyles() {
const cssTexts = [], rootCssTexts = [];
for (const styleSheets of document.styleSheets) {
if (styleSheets.ownerNode.hasAttribute('data-cke')) {
for (const cssRule of styleSheets['cssRules']) {
if (cssRule.cssText.indexOf('.ck-content') !== -1) {
cssTexts.push(cssRule.cssText);
} else if (cssRule.cssText.indexOf(':root') !== -1) {
rootCssTexts.push(cssRule.cssText);
}
}
}
}
return cssTexts.length ? [...rootCssTexts, ...cssTexts].join(' ').trim() : '';
},
getContentWithLineStyles(editorContent) {
return juice.inlineContent(`<div class="ck-content">${editorContent}<div>`, CkeditorUtil.getEditorStyles());
}
};
export default CkeditorUtil;
// convert
CkeditorUtil.getContentWithLineStyles(editorContent);
if you needed to convert css variables to static values, You can refer to this code.
This feature is really important. I don't understand how it got such a negative response. Also, this problem has been going on for a long time. Up to 3 years long.
Is there any update for this feature??
As for the temp fix using juice to dynamically inject inline styles suggested by @ogabrielsantos, I see there might be an issue regarding the format of injected inline styles.
- CKE5 internally shrinks inline styles and outputs them compressed:
styles="font-weight:10px;color:black". - Unlike
juicethat injects in a standard CSS way with white-spaces between CSS properties:styles="font-weight: 10px; color: black".
Is there someone who synchronized inline handling between CKE5 and juice approaches, or any reliable way to achieve it without RegExp? Otherwise, it would trigger redundant value update (CKE5 content data). Especially if React or similar has been used, onChange would change the output value each time with juice, then CKE5 compresses the injected styles back.
This feature would really be great. Looking forward to it being implemented.
Bump! We've been waiting for this feature for ages. The CKEditor community really needs this!
+1
Been waiting so long for this, please make this happen soon.
Estuve revisando y aun no esta esa funcion, realmente es importante, consideo que lo hacen para que se pague la licencia premium para exportar en pdf y en word :(
Looking forward to it being implemented.