TinyMCE: tags inside a-tag - tinymce

I use TinyMCE 4.1.10 and have a problem with tags inside <a>-tags:
I need to insert code in the following markup inside the code viewer:
<a><h3>something</h3></a>
Generally I want every tag to be possible inside the <a>-tag (besides another <a>-tag).
But TinyMCE does a ridiculous cleanup:
<p><a></a></p>
<h3><a>something</a></h3>
<p></p>
I've already made following modifications in the setup:
extended_valid_elements : "a[*]",//allow empty <a>-tag
valid_children : "+a[div|h1|h2|h3|h4|h5|h6|p|#text]",//allow some children in the <a>-tag
verify_html: false,
It doesn't make any sense at all what TinyMCE is doing here.
The TinyMCE-website is telling me it uses html5-specification by default:
The schema option enables you to switch between the HTML4 and HTML5
schema. This controls the valid elements and attributes that can be
placed in the HTML. This value can either be the default html5, html4
or html5-strict.
And in the HTML5-Specifiations you can read:
The a element may be wrapped around entire paragraphs, lists, tables,
and so forth, even entire sections, so long as there is no interactive
content within (e.g. buttons or other links).
And now I don't get anything despite HTML5 valid markup AND extra valid-children setting in TinyMCE.

Related

What do you call input class="gLFyf" vs input.gLFyF (vocabulary help needed)

In Chrome DevTools, the element tab shows the constructed DOM and I can click on elements in the DOM which also highlights the element on the page. Image of both versions shown in DevTools
If the DOM shows:
<input class="gLFyf">
Then the page highlight will show:
input.gLFyF
I realise these are two ways of writing the same thing, I also realise the former is HTML style and the latter follows CSS conventions. However, I lack the vocabulary to properly refer to either.
What do I call each format?
Eg. would it make sense to refer to <input class="gLFyf"> as HTML syntax and input.gLFyF as CSS syntax? Is there a more widely accepted way to differentiate and name them?
gLFyf is the name of the class which is an attribute that can be referred to in the stylesheet to match styles with elements of that class on the page.
A class leads with a period (.) - whereas an ID would lead with a hash (#).
So .gLFyf is a class.
And #gLFyf would be an ID.
It is a class, whether viewing HTML markup or the DOM inspector. They both refer to the same thing as you already state.
This may be of some use/reference.

How to configure TinyMCE to allow block-level elements inside inline element?

I have an HTML where inline element span which hold block element example div. I have pasted below HTML source in the source view of TinyMCE and press Ok
<span>plain text<div>test div</div></span>​
Further, I have click on the source view and HTML it changes to the below HTML where span automatically gets closed and new span added to the HTML,
<p><span><span>plain text</span></span></p>
<div>test div</div>
<p>​</p>
I know, we can't have block element inside the inline element(i.e. HTML global rule), but I am not in position to make changes in the current system.
Update: I have tried to solution mention here but not worked well: https://stackoverflow.com/a/14603631/4420468
There is a config option to control this behavior.
valid_children
The valid_children enables you to control what child elements can exists within specified parent elements.
see docs for further information

TinyMCE: How can I change the formats ("Paragraph", "Heading 1", etc.)

By default TinyMCE (4) has a "Paragraph ▼" dropdown, and if you click on it you get a list of formatting options ("Paragraph", "Heading 1", etc.).
I'd like to be able to do two things. First, I want to change the options and their names (eg. to "Normal" and "Heading"), and I found the block_formats option which does exactly that:
block_formats: 'Normal=p;Heading=h1'
However, I'm stuck on thing #2: adding classes to the generated elements. Instead of plain <h1> elements, when someone picks "Heading" I want to generate a <h1 class="heading">.
I thought maybe this would work:
block_formats: 'Normal=p;Heading=h1.heading'
... but it doesn't, and I haven't been able to find any other option that would let me do this. Then again, the TinyMCE documentation isn't always the easiest place to find answers, which is why I came here.
Does anyone know how I configure TinyMCE to have a "Paragraph ▼" dropdown with customized names AND custom classes on the generated elements?
I never did find a way to do this, so what I wound up doing instead was remove the block format drop-down entirely and replace it with the (custom) format dropdown. In other words I:
removed the formatselect from the toolbar1 config (removing the un-configurable normal formatting dropdown)
added the custom format dropdown (styleselect) to the toolbar1 config
defined a style_formats config entry with my custom styles
The style_formats config looked like this:
style_formats: [
{
title: 'Header',
inline: 'span',
classes: 'someClass',
styles: {someStyle: '5px'}
},
], // next style would go here
There were only two downsides of this approach. First, the dropdown now says "Formats", and I don't seem to be able to configure that anywhere. However I do have a single formatting dropdown, with only the options I want, and those options add the desired classes to the formatted text, so the dropdown's name isn't a big deal.
The second issue was that TinyMCE uses an <iframe>, which prevents it from using our stylesheet. I could have written a stylesheet for TinyMCE and then appended it to the <iframe> (or used some TinyMCE mechanism, if there is one) ... but I'm lazy so I just used style: entries for each custom format to define the style.

CKEditor strips <i> Tag

I'm trying to find a solution to avoid CKEditor, but also the older FCKeditor strips out any
<i> tag from previously inserted content to the db.
Case:
I insert html content to the db, some content contain the <i> elements.
I do this with the CKEditor.
Everything works perfect and the content shows up on the webpage.
But when i want to edit the previously inserted content, the <i> elements are missing.
In my specific case i use:
<i class="fa-icon-fullscreen fa-icon-xxlarge main-color"></i>
Of course if i disable the editor, the content shows up just fine in the textarea.
When the protectedSource solution is used, i tags are no longer stripped, but img tags stop showing up in the WYSIWIG mode of CKEditor (I'm using 4.3.1). The solution that worked better for me is to disable removing empty i tags using CKEDITOR.dtd.$removeEmpty
For example, I added the following to the config.js
// allow i tags to be empty (for font awesome)
CKEDITOR.dtd.$removeEmpty['i'] = false;
Note: This should be placed outside the CKEDITOR.editorConfig = function( config ) function.
I found the solution for this specific problem i ran into with the <i> tag
The original answer i got from drupal forum
The fix or tweak (you name it) for it is to set the following into the ckeditors config.js:
// ALLOW <i></i>
config.protectedSource.push(/<i[^>]*><\/i>/g);
Thanks to Spasticdonkey for pointing me to the link.
Here is what works for me
add the 3 lines of code below in the same order in the drupal ckeditor profile setting
admin/config/content/ckeditor/edit/Full
ADVANCED OPTIONS >> Custom JavaScript configuration
config.allowedContent = true;
config.extraAllowedContent = 'p(*)[*]{*};div(*)[*]{*};li(*)[*]{*};ul(*)[*]{*}';
CKEDITOR.dtd.$removeEmpty.i = 0;
First line is pretty much turning off the advanced filtering
Second line is allowing ALL class (), any style {} and any attribute [*] for the p,div, li and ul.
The last line is for the empty tag...this line works with images...I have found that if you use
config.protectedSource.push(/]*></i>/g);
it strips out the tag while editing.
for 4.3 version ckeditor
in config.js (after config section) paste
CKEDITOR.dtd.$removeEmpty['b'] = false;
and write widget with code
CKEDITOR.plugins.add( 'bwcaret', {
requires: ['widget'/*, 'richcombo'*/],
icons: 'bwcaret',
init: function( editor ) {
editor.widgets.add( 'bwcaret', {
button: 'Create a caret',
template: '<b class="caret"></b>',
allowedContent: 'b(!caret)',
requiredContent: 'b(!caret)',
upcast: function( element ) {
return element.name == 'b' && element.hasClass( 'caret' );
},
});
}
});
There are two possible problems:
Read about Advanced Content Filter. CKEditor is removing elements which are not allowed, but you can extend filter's rules.
However, if the problem is that CKEditor removes empty <i> elements, then you need to find other way of using it. CKEditor is not a WYSIWYG website builder. It is a document editor, so the loaded content must have a meaning. Empty inline element does not have any meaning, therefore it is removed, because otherwise editor would not know what to do with it.
One of the possible solutions in the (near) future, will be to use Widgets system, to handle those empty elements. But for now I advice you to check the CKEDITOR.htmlDataProcessor and short guide how to use it.
i found a permanent solution for it.actually what happened ckeditor removing only blank tag.whatever the tag is, may b <i> tag or <span> tag
if you are using any icon like font-awesome,maeterlize icon etc ...
you can stop it by using below code in your config.js file
CKEDITOR.dtd.$removeEmpty.span = false;
CKEDITOR.dtd.$removeEmpty.i = false;
if you are using more blank tag then you need to add the tag name after $removeEmpty
CKEditor 4 removes emtpy tags, so here you can do trick without changing any config settings.
Replace
<i class="fa-icon-fullscreen fa-icon-xxlarge main-color"></i>
With
<i class="fa-icon-fullscreen fa-icon-xxlarge main-color"> </i>
Now <i></i> tag have content i.e. so CKEditor will not remove that tag.

Prevent EPiServer from wrapping content in <p> tags

I'm working on a site in EPiServer, and whenever I create a page property with the type set to "XHTML string" (which uses the WYSIWYG content editor in Edit mode), it wraps all content in <p> tags.
Is there any way to prevent this from happening? I can't remove the paragraph margins universally through my CSS (e.g. p {margin: 0 !important;}) since I do need the margins for actual paragraphs of text. I've even tried going to the HTML source view in the editor and manually deleting the <p> tags that it generates, but it immediately adds them back in when I save!
It doesn't happen when the property type is either a long or short string, but that's not always an option since the content might contain images, dynamic controls, etc.
This is becoming a real nuisance since it's very hard to achieve the layout I need when basically every element on the page has extra margins applied to it.
As Johan is saying, they are there for a reason - see more info here. That being said, it's not impossible to remove them. It can be done in one of two ways (taken from world.episerver.com:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
myEditor.InitOptions["force_p_newlines"] = "false";
}
or
<script type="text/javascript">
tinyMCE.init({
force_p_newlines: false
});
</script>
You can add your own custom TinyMCE-config that removes P-elements or strip them out using regular expressions either when saving the page or when rendering the property/page.
I think it's a bad idea though. P-elements are what the editors generate the most and in most cases their content is also semantically correct. Better to wrap your property in a div with a class and adjust margins using CSS like you mention.
If you're using a version of EPiServer with TinyMCE editors, you can insert <br /> elements instead of <p> elements if you type shift-enter instead of enter. This should eliminate your margin problems.
More info at the link below:
http://www.tinymce.com/wiki.php/TinyMCE_FAQ#TinyMCE_produce_P_elements_on_enter.2Freturn_instead_of_BR_elements.3F
EDIT: My comment below answers his question better.
I discovered that while I can't remove the <p> tags from the source view (because it adds them back in automatically), if I replace them with <div> tags, it'll leave things alone. It does mean that I've got an extra <div> wrapping some elements that I don't really need, but at least a <div> doesn't add margins like a <p> does, so...good enough!