Insert HTML using Writer.insert* functions in CKEditor 5 - ckeditor

I see that Writer class has methods to insert Text. However, I fail to understand as to which of those methods is the right one to insert HTML into the editor.
Explanations
My case scenario is:
A User can create certain content template and save it. Later the user should be able to insert that same content into the editor and start modifying.
I'm handling this using the following code
activeCKE.model.change( writer => {
writer.insertElement( "text to insert", activeCKE.model.document.selection.getFirstPosition() );
activeCKE.setData(activeCKE.getData()); // to refresh the contents
}
It works well with "**text**" but not with " <strong>text</strong>". The latter appears as-is.
So my question is; What is the right way to insert the HTML string programatically that has already been created using something like the Writer class?
I see there is a concept of template in ui/template, however I'm unclear as how to convert editor.getData() to that template.
Please Note: I don't want to give the user an HTML editing interface. I just want to create templates to make his life easier. Hence my question has nothing to do with 'View Source Code' based questions.

While I continued my research post asking this question, I landed onto FAQs, where I got my answer.
const viewFragment = activeCKE.data.processor.toView( "<p>HTML Text</p>" );
const modelFragment = activeCKE.data.toModel( viewFragment );
activeCKE.model.insertContent( modelFragment, activeCKE.model.document.selection );
This satisfies my use case. However, I encourage the community to post other possible variations, such as using Template class. Especially because line-breaks due to any kind of tag (br, p etc) are filtered out.
Developers interested to show the source code & allow source code manipulation in CKEditor 5, can create a plugin that shows the contents of editor.getData() in a dialog (or something they like) and then reset the contents of editor and insert the content in a fashion similar to the one demonstrated above.

Related

Setting Mailchimp campaign content html not working

I tried to update my campaign html content using mailchimp api:
/campaigns/{campaign_id}/content
You can find more information about this api here: https://developer.mailchimp.com/documentation/mailchimp/reference/campaigns/content/#
Before sending a campaign, I tried to get campaign content html, modified it and then set campaign content html using above api. I just simply use BeautifulSoup to append a new tag to content body:
content.body.append(BeautifulSoup('<p>Mailchimp is freaking shittttt</p>'))
Then, some interesting things happen, the first campaign I created, it works fine, the tag added appears in my email. But, then the sub-sequence campaigns not working anymore, the tag added not appearing.
I observed something strange on my mailchimp campaign site, even though I set campaign html content, only Plain-Text Email gets changed (HTML Source still the old version) for both working and not working campaign.
Anyone got this issue before?
I had a similar issue and I had to take a slightly different approach to solve it. According to this answer by Joel H., "MailChimp doesn't allow updating the campaign's HTML content because the campaign type is based on a template. In order to update the HTML content, the campaign has to be set to custom HTML instead of a template."
That solution didn't suit me but it led me to another solution: creating a template, creating editable content areas within that template, and then using the API to retrieve and edit the text in those content areas.
Here is an attempt at adapting my code to solve your problem. I'm using Python 3 and the mailchimp3 client.
default_footer_content = client.templates.default_content.all(template_id=TEMPLATE_ID)['sections']['SECTION_NAME']
new_footer_content = default_footer_content.replace(PLACEHOLDER, 'Mailchimp is freaking shittttt')
client.campaigns.content.update(campaign_id=CAMPAIGN_ID, data={'template': {'id': TEMPLATE_ID, 'sections': {'SECTION_NAME': new_footer_contennt}}})
Some pointers on the above code:
You can find TEMPLATE_ID with the API or simply by copying the numbers at the end of the URL when editing the template in the web interface
You define SECTION_NAME by placing 'mc:edit="SECTION NAME"' in the appropriate place in the template
I've used .replace() rather than .append() so you will need to put PLACEHOLDER or similar at the appropriate place in the template
I hope that helps, happy to modify my answer if it needs more clarification. This is my first answer on Stack Overflow so constructive criticism appreciated :)

Stop Magento/tinyMCE forcing object tag type

So iv been reading about peoples problems with tiny MCE "messing up" code. I understand it isn't, but I have a very minor problem that is become a major problem.
Im trying to add a simple object tag to one of my CMS pages. I need the object type to be "text/html" but whenever I save the page it converts this to "application/x-shockwave-flash"
I don't want to turn off the tinyMCE cleanup option as by the sounds of things this is a really bad thing to do.
So is there a way to stop it changing just the type attribute?
I have tried adding the code to a CMS widget and adding the widget to the page but this get the same altered result.
This thread (Object tag is not working) seems similar, but simply changing the type isn't working for me as it is automatically changing back to flash upon save.
The url i am trying to load looks like this...
(http://www.domain.com/animations/embed/one/o-t-t-d?player_width=100%&player_height=100%) I have been told that this will return flash if it is available or html if not.
Im assuming that because i'm saving the page on a PC with flash available its recognising and changing the type.
Any help appreciated.
You can edit the file js/mage/adminhtml/wysiwyg/tiny_mce/setup.js to make this happen.
Look for the settings array (around line 100). Add 'extended_valid_elements' there, like this;
var settings = {
...
extended_valid_elements: 'object[type]',
...
};
This way, TinyMCE will know the type attribute is valid and won't change it.

Passing Markdown Content to Ruby Function With Jekyll/Liquid

I am trying to write a jekyll plugin that will take a normal markdown file and provide some extra functionality on top of it. In particular, I need to do some (not actually) fancy things with tables. I know you can write straight HTML into a markdown file, but there is a requirement that the content folks don't want to / can't edit HTML.
As an extra wrench in the works, the mobile layout has a UX requirement that I essentially have to render the table as a group of divs as opposed to a table.
My initial thought was to pass the {{page.content}} variable to a ruby function extending Liquid::Tag. From there I was planning on parsing the markdown file and either:
1. If normal non-table markdown, use as normal
2. If table markdown, look for custom identifier in markdown, do what needs to be done (e.g. add class, etc)
If I do something like this:
def render(context)
content = Liquid::Template.parse(#markup).render context
end
It renders the context as a normal markdown file. However, I want to break up the context variable and work with the pieces before rendering. I've tried a few different approaches that I've gotten from the jekyll docs and Stack Overflow and gotten nowhere.
Does anyone have any experience with this? I am heading down the right path? For what it's worth, Ruby/Jekyll/Liquid is fairly new to me, so if you think I may have missed something fairly basic and obvious then please let me know.
A markdown table tool for editors !
markdownify your table in http://www.tablesgenerator.com/markdown_tables
paste the markdown result in http://prose.io/
done
I don't know other way to simplify editor's work on Jekyll, but I'll be very interested in earing from your project. Good luck.

CKEditor and HTML in Xpages

I am understanding this better but still not there yet.
I have a notes document with a rich text field. I want to edit it in Xpages, so that the user can enter text for an email that an agent will generate. The idea is that the user should be able to enter styled text, hopefully including pasted graphics, and this is saved to the rich text field in such a way that a later agent can copy that field to the body of an email.
On the form I have checked the field "Store contents as HTML and MIME.
In the Xpage I have bound the CKEditor directly to the field (can bind it to a scope variable if necessary).
The code in my agent is as follows:
Set rtItmFrm = emlDoc.getFirstItem("Body")
Set rtItmTo = New NotesRichTextItem(mail,"Body")
Set rtItmTo = rtItmFrm.Copyitemtodocument(mail,"Body")
Any further suggestions on reading up on MIME/CKEditor etc would also be much appreciated.
Bryan
=========================================================================
I just discovered how to modify the CKEditor in Xpages (the Rich Text Control). I have the full menu and one or two more things turned out. However, I am really puzzled by how it treats HTML. I would like to put a template for a nice HTML email (like a newsletter). Anything even a little complicated it munges and the output is messed up.
I read enough online to understand that it is not supposed to be a HTML editor, but I am really having trouble getting the results I want. I would love to put some basic skeleton HTML in there, but everything but the simplest code doesn't work.
Is there anyway to import HTML and it not get messed up using this editor?
as Per and Stephan said, Have a look at ACF filtering that is 'server side' (This is not related to CKEditor itself, but it is related to XPages).
If you have a look at the inputRichText control you will see 2 properties.
htmlFilter
htmlFilterIn
These properties determine how to filter Html on the way in to your data, and also on the way out.
This can be used to strip styling out, and also to prevent dangerous tags like some bad code here etc.
By Default the htmlFilter is set ACF (Active Content Filtering) if you look at the default rules, you will see it strips things like 'margin' out.
see /properties/acf-config.xml-sample
There is a filter called 'identity' which means don't filter anything, however beware if you use this you are not protected from and maliciously entered html.
You should look into defining your own set of rules for your ACF filter, this way you can choose which elements to remove. There is a section in Mastering XPages book about this.
If you still have any trouble, then there are some settings in CKEditor config which also control ACF (totally separate to XPages server side)
I don't think CKE changes the HTML, it is the writing back to a RT field.
Try and bind your RichText Editor to a scoped variable instead of a RichText field. This way you have access to the raw HTML and can use that to generate a MIME email. You might want to have a look at Mustache for mail merge.
Use this article series as starter how to prepare CK editor to make this possible.
And as Per mentioned: check the filtering.

AJAX Tabcontainer inside formview not inserting values

I have a TabContainer inside a data bound FormView (to present the information by category ex: Client Bio data, health history, financial details...). The Update and Insert of the formView doesn't work (posting NULL values to the database) - I guess the FormView cannot find the TextBoxes inside the tab container's tab panels.
Some of the forums say that it's because of the TabContainer's implementation (by design) of "INamingContainer", and a hack is to take control of the TabContainer's
source code (ajax ctl toolkit's source code) and remove the "INamingContainer" interface from it... Too complicated to my taste .. I'm kinda lost.
Well is there a straight forward and better way to fix this? I'm dazzled to see that the toolkit has failed to implement this basic functionnality as for most developper ordering info (tab control) with formview is a common need.
Thanks in advance,
Jeewai
Answering my own thread... I got some great inside from the asp.net forum and decided to post the solution here: Reproducing the explanation that helped me out:
Hope that will clear out some questions to other users who may encounter the same issue.
Best,
JY
Blockquote
Hi JY,
The short answer is that when a Bind statement is compiled, there are some limitations on extracting values for an insert/update. If the controls within the FormView are then within another Naming Container (TabContainer and TabPanel are both naming containers), then the compiler can't resolve how to extract the value from the TextBox. I have a more detailed discussion of this on my blog at http://www.aarongoldenthal.com/post/2009/03/15/ASPNET-Databinding-Bind()-Method-Dissected.aspx.
To get around this, you'll need to extract the values manually, something like:
protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
// Get references to the controls
TextBox LastNameTextBox= FormView1.FindControl("TabContainer1").FindControl("TabPanel1").FindControl("LastNameTextBox") as TextBox;
// Set update parameters in datasource
ObjectDataSource1.UpdateParameters["LastName"].DefaultValue = LastNameTextBox.Text;
}
Since FindControl only searches the current naming container, you'll need to dig through each naming container (FormView, TabContainer, and TabPanel) to get to the TextBox.
Hope that helps.
Aaron
Blockquote

Resources