Magento2: WYSIWYG Editor removing block level elements inside <a> tags

Created on 17 May 2016  路  20Comments  路  Source: magento/magento2

The WYSIWYG editor strips out <a> tags when they have block level elements nested inside, this is valid HTML5 so I believe it should not do this.

Steps to reproduce

  1. Create a static block and add the below code
  2. Save the static block.
  3. Refresh the page
  4. Save the static block again
<a href="#">
    <div class="test">Test</div>
</a>

Expected result

  1. I expect the code to remain the same.

    Actual result

  2. The code in rendered out to

<div class="test">Test</div>

Extra points

Cms Confirmed P2 ready for dev Reproduced on 2.1.x Reproduced on 2.2.x Reproduced on 2.3.x S2 bug report

Most helpful comment

Just FYI: Magento 2.3 will finally have an update to Tinymce 4.x, currently it's at 4.6.4, see: https://github.com/magento/magento2/blob/2.3-develop/lib/web/tiny_mce_4/tinymce.min.js

All 20 comments

Hi @BenSpace48

Thank you for reporting this. I created internal ticket MAGETWO-52972 to investigate and fix.

Hello,

is there any update on this given issue ?

So, any news on this?

@BenSpace48, thank you for your report.
We've created internal ticket(s) MAGETWO-52972 to track progress on the issue.

Here's a potential fix

In this file: lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js
Replace this:

['a', 'href target rel media hreflang type charset name rev shape coords download', phrasingContent],

With this:

['a', 'href target rel media hreflang type charset name rev shape coords download', flowContent],

Yes Good call @BenSpace48

More Info:

Yes I think it would be a good idea to override the javascript if possible if you are patching an existing project. I meant to propose this as the official fix for someone who is in a position to make it.
The reason this fixes the issue is that the 'flowContent' array includes block level tags and inline tags unlike the 'phrasingContent' array which includes only inline elements.

The first element of this array is the a the tag we want to fix, the second array entry appears to be attributes allowed on a tags, and the third array entry (the one we care about) appears to be allowed children.

I didn't do much more than test that this works in my own individual project so use at your own risk. Someone who has more time than me and can make an official fix or PR should by all means look at other ways to fix this that might be better.

@friendscottn Can you provide more info please? How does this fix it? and we should probably overwrite that file not edit it directly.

For @friendscottn's suggestion, it does work and it should be done in an overridden file in the following location (replace YourCustomName):
app/design/adminhtml/YourCustomName/Backend/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js

@BenSpace48 Do we need to fix this issue magento core file ?

@hitesh-wagento Yes, but I think the main cause is Tiny MCE seems way out of date.

Based on /lib/web/tiny_mce/tiny_mce.jsthe version is 3.4.7 which dates back to 2011 when standards were very different. The latest version is 4.7.13.

Hopefully updating this will also update the standards to HTML5.

I'm very disappointed we are here 2 years later without a single comment about it from Magento other than an internal ticket number.

Just FYI: Magento 2.3 will finally have an update to Tinymce 4.x, currently it's at 4.6.4, see: https://github.com/magento/magento2/blob/2.3-develop/lib/web/tiny_mce_4/tinymce.min.js

That's positive news, thanks @hostep

@BenSpace48, @hostep

I have tested Magento ver. 2.2.6-dev I am still facing above issue

If I will : Replace this:

['a', 'href target rel media hreflang type charset name rev shape coords download', phrasingContent],

With this:

['a', 'href target rel media hreflang type charset name rev shape coords download', flowContent],

It's solve issue but you need to use below structure :

<div>
    <a href="#">
        <div class="test">Test</div>
    </a>
</div>

If you will use :

<a href="#">
    <div class="test">Test</div>
</a>

It's show :

<p>
    <a href="#"></a>
</p>
<div class="test">
    <a href="#">Test</a>
</div>
<p></p>

As @hostep has said, with 2.3 we'll be releasing an upgrade to TinyMCE to boost us to v4. This means we could then enable allow_html_in_named_anchor (https://www.tinymce.com/docs/configure/content-filtering/#allow_html_in_named_anchor) to resolve the issue with anchor specifically.

I've updated the internal ticket with this information to hopefully aid with resolving this issue.

Thanks for your help @davemacaulay <3

Same issues on Magento 2.3 beta32

Hi @gauravagarwal1001. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:

  • [ ] 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
  • [ ] 2. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento-engcom-team give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!

  • [ ] 3. Verify that the issue is reproducible on 2.2-develop branch.

    Details- Add the comment @magento-engcom-team give me 2.2-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.2-develop branch, please add the label Reproduced on 2.2.x

  • [ ] 4. If the issue is not relevant or is not reproducible any more, feel free to close it.


Still a problem.. Magento 2.3.2

Checking if this work-around solves it...
https://github.com/pavelleonidov/magento2-tinymce4

composer require pavelleonidov/module-tinymce4
php bin/magento setup:upgrade && php bin/magento setup:di:compile

It does not.
composer remove pavelleonidov/module-tinymce4

Additionally, is there a way to configure tinymce to not reformat the html and not to put p tags in all over the show?

I tried this.

Edit lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js
Line 204 add ```forced_root_block : '',

apply_source_formatting : false,
verify_html : false,
allow_conditional_comments: true,
allow_html_in_named_anchor: true,

But I think disabling the p tags by using forced_root_block might have an adverse effect of preventing some features/styling of sections of text.

php bin/magento setup:upgrade && php bin/magento setup:di:compile && php bin/magento setup:static-content:deploy -f && chown -R www-data:www-data . && bin/magento c:c

But it did not help to resolve it.

https://stackoverflow.com/questions/39083971/configure-tinymce-4-to-allow-inline-element-or-anchor-tag-a-to-be-the-top-leve

TinyMCE version in use 4.6.4
TinyMCE 5 is out any thoughts on using that?
Or maybe a different editor such as Quilljs, CKEditor, Trumbowyg, summernote, Editor.js?

Even more odd,

<p>
<a href="#">
    <div class="test">Test</div>
</a>
</p>

Turns into this when you click Show / Hide Editor twice.

<p><a href="#"> </a></p>
<div class="test"><a href="#">Test</a></div>
<a href="#"> </a>
<p></p>

I then tried changing the a tag's phrasingContent to flowContent did not appear to have any improvement maybe because I did not revert what I did above?

By editing lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js
And changing to
['a', 'href target rel media hreflang type charset name rev shape coords download', flowContent],

https://magento.stackexchange.com/questions/270923/magento2-wysiwyg-tinymce-editor-every-time-removing-a-tags-in-cms-blocks

The reason this fixes the issue is that the flowContent array includes block level tags and inline tags unlike the phrasingContent array which includes only inline elements.

But another comment on there says they solved it with editing Tinymce4Adapter.js and changing valid_elements and valid_children settings to

$settings['valid_elements'] = '*[*]';
$settings['valid_children'] = '+body[style],+div[a],+p[strong|a|#text],+a[div]'

https://stackoverflow.com/questions/14597219/how-to-configure-tinymce-to-allow-block-level-elements-inside-anchor-a-tag

Anyone else had luck fixing this?
Making everything valid, does not seem like a fix to me.

I had this issue because I'm trying to put the WeltPixel Pearl theme Social Icons in the footer of a site.

https://pearl.weltpixel.com/v5/weltpixel-social-icons

<a href="#" class="social-icons si-facebook">
    <i class="icon-facebook"></i>
    <i class="icon-facebook"></i>
</a>

Gets completely removed.

Maybe related/regression of this but should be fixed...
https://core.trac.wordpress.org/ticket/28940

If I put content in the i tag it is changed to an em tag, spans are changed to p as well.
Also media url tags in images sand quotes seem to get wiped/broken after saving and re-toggling the editor.

https://magento.stackexchange.com/questions/293980/double-quotes-change-into-quot-in-tiny-mce-editor-in-magento-2-x
<li><a href="{{store url=&quot;about-us/&quot;}}">About Us</a></li>

If I put single quote it appears to work but for some reason the default content had double quotes and it all got mucked up :(

<li><a href="{{store url='about-us'}}">About Us</a></li>

Workaround to use Magento Markup Tags and load a phtml template seems stupid...
https://docs.magento.com/m2/ce/user_guide/marketing/markup-tags.html

Ah, WeltPixel exposes Widget for their icons thankfully.
<p><a href="https://www.facebook.com/company">{{widget type="WeltPixel\DesignElements\Block\Widget\Icon" icon="icon-facebook" icon_size="38px" custom_class=""}}</a></p>

But this is still not quite what I wanted as does not have the custom classes correctly.

Please fix this so we can just paste the html and it will work without breaking it and removing new lines/formatting.

  • Updating : Magento 2.4, TinyCME 4.0
    Fixing lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js.
    Function : getSettings, variable settings, add new config value : 'valid_elements': '*[*]'

`getSettings: function () {
var settings,
eventBus = this.eventBus;

        settings = {
            selector: '#' + this.getId(),
            theme: 'modern',
            skin: 'magento',
            'entity_encoding': 'raw',
            'convert_urls': false,
            'content_css': this.config.tinymce4['content_css'],
            'relative_urls': true,
            'valid_elements': '*[*]',
            'valid_children': '+body[style]',

...
`
Then it works.

You are a legend @trunglv. That worked perfectly and got rid of that annoying bug that removes elements. Legend!!!

Was this page helpful?
0 / 5 - 0 ratings