Jump to content

TinyMCE Valid Elements


Adam Kiss
 Share

Recommended Posts

Just a quick note: I believe not everyone is that skilled to [or wants to] edit advanced settings of TinyMCE on 'body' field (or any new field with TinyMCE), so I think, that Ryan (or I may, but I think that my git repo is broken) should add following elements into 'valid elements' and buttons, even though they are not used in demo site:

  • h1
  • div
  • span
  • html5 elements?

Because even if you edit code in HTML editor of tinymce, those elements that are not valid will be cleared upon saving the page.

Link to comment
Share on other sites

These tags are disallowed by default because some suggest building page structure or introducing possible non semantic markup. Something like TinyMCE can very easily get out of hand if it turns into a freeform markup tool. So the current settings are really geared towards ensuring that the markup is specific to a field and not the entire page, as well as trying to minimize the damage a client could do with markup and pasting. Pasting is probably the biggest issue, and even with the allowed elements we have now, it can still be a problem.

I know there are sometimes needs for div and span tags, even within a field like this. But to take full advantage of them, you are going to have to get into the TinyMCE settings even further than just the valid elements. Granted, you might be able to input them, but you won't be able to see what they do unless you get into tweaking more TinyMCE settings. If it's for your own use, then great, but if it's for a client, then expect them to break it. :)

In my sites, I try to organize an search accessibility/SEO strategy that optimizes the title tags and h1 headline (among other things). If I give the client the h1 tag in the editor, I know they will use it (it's bigger!) but it'll mess up your ability to exert some level of control over the page semantics and hierarchy, especially as it relates to search accessibility/seo (assuming headline use in the context of the page).

Regarding HTML5 tags, I do think it would be worthwhile for us to add some of those to the default allowed elements. I also recognize that everyone has different needs, and we should make the system flexible enough to support those needs. Currently it is, but you do have to understand how the TinyMCE settings work, and they are a little cryptic! So while I do want to have default settings for best practices (like they are now), perhaps we should setup a separate thread or forum for pre-defined TinyMCE tweaks that people can paste in? Or maybe when I setup the documentation for this fieldtype, I can have a section there with predefined settings they can use... what do you think?

Link to comment
Share on other sites

Well, from this standpoint (clients), I guess it makes sense then ;)

The thing is – I'm not sure whether possibilities for e.g. the 'body' field are clear enough – I mean, there are quite a few settings regarding textarea field, but default settings make it look like the TinyMCE is the most important (or even the only one to use). Granted, it's easy to change it, I'm just thinking whether it's clear to newbies with PW what to change [maybe this isn't question of admin design, rather than documentation]

Re: h1

<h1> is the HTML element for the first-level heading of a document:

  • If the document is basically stand-alone, for example Things to See and Do in Geneva, the top-level heading is probably the same as the title.
  • If it is part of a collection, for example a section on Dogs in a collection of pages about pets, then the top level heading should assume a certain amount of context; just write <h1>Dogs</h1> while the title should work in any context: Dogs - Your Guide to Pets.

I believe it suggests, that h1 should be the most important heading on current page, rather then site /site headline/

Link to comment
Share on other sites

Granted, it's easy to change it, I'm just thinking whether it's clear to newbies with PW what to change [maybe this isn't question of admin design, rather than documentation]

It's probably best if the newbies don't change it. :) If someone knows what they are doing with markup and semantics, then I do want them to be able to figure it out though. TinyMCE settings aren't the most clear thing in the world (I don't totally understand them myself! I spend hours wading through the TinyMCE wiki and forums), and I do agree with you about documentation.

I believe it suggests, that h1 should be the most important heading on current page, rather then site /site headline/

This is the reason why it's not an allowed element in the TinyMCE field by default. Assumption is that people are using the $page->title field (or a separate headline field they've added) for their h1 rather than assuming it'll get built into the bodycopy.

Link to comment
Share on other sites

Let me know what you want to do with the TinyMCE config, and I can help you determine what needs to be put in.

If you find a better solution for a RTE than TinyMCE, let me know. I've experimented with quite a few, and as annoying as it can be, TinyMCE seems to be the most tolerable.

Also, lightweight markup languages (like Markdown) are often a good alternative. The results they produce tend to age and scale better... if you can convince your client to adopt the syntax.

Link to comment
Share on other sites

  • 1 month later...

Hi, I found this post while trying to figure out if it's feasible to use TinyMCE in Processwire as a fool-proof inline rich text formatter, to say so.

For that, it seems I'd have to change TinyMCE configuration for the pertinent textarea field like this:

force_br_newlines : true,
force_p_newlines : false,
forced_root_block : ''

But Processwire don't expose those setting in its TinyMCE Advanced Configuration Options.

I suppose I'd have to mess around with the $config stuff in the admin template, but I'm just a poor copipasta php guy so I don't even know where to start. =(

Background on the issue:

I'm on a project where I want to give the "client" (it's a spare time job for a friend, so there are no stringent requirements) the ability to optionally format headlines - ie. with bold text, italics, links, superscripts, subscripts and arbitrary line breaks.

So I've put this in my template, just like in the default skyscrapers theme:

<h1><?php echo $page->get("headline|title");?></h1>

and I've set up the headline field as a text-area.

Now, I know I can have most of the functionality I want just by applying textformatters to the textarea, but I wanted to try to make it the most complete (sup and sub in markdown?) and fool-proof - markdown syntax is simple as cake but my friend is the kind of person that will never ever learn and remember that, for how brilliant he is otherwise =)

So I set up TinyMCE for the textarea and edited out all the unwanted buttons and elements (including of course <p>) in the processwire field TinyMCE options.

It works, but now, due to the _newlines config, when I press enter in the TinyMCE wysiwyg textarea I get a double carriage return that outputs nothing in the html code, and I still need to press shift-enter to actually get a line break, which is the opposite of the fool-proofness I wanted to achieve.

Link to comment
Share on other sites

Abu, PW doesn't expose the settings you mentioned just because I think they are primarily in TinyMCE for backwards compatibility with pre-semantic-markup. Years ago, rich text editors didn't deal with semantic elements. Instead, they used BR tags (not to mention inline styles) to make the editor "feel" like MS Word. But HTML markup is fundamentally different from something like MS Word and it usually does the user, and their output, a disservice to hide that fact. TinyMCE and other editors are now built more in recognition of that, but it wasn't like that just a few years ago. So this is why hitting enter (for instance) creates a new paragraph, and hitting shift-enter creates a break. Usually we don't want our client creating non-semantic breaks unless they really mean it.

That's just background info on why PW doesn't expose these settings, but they aren't applicable to your particular need which seems to be unique. I think what you are suggesting makes sense for your need and your client. While I wouldn't usually suggest editing files in a core module (because they can be overwritten in an upgrade) I think that's going to be the best way to achieve what you want. You'll have to remember to keep a copy of these files if you upgrade, so that you can apply the same change later on if the need arises. Here's how to do it: 

First edit this file:

/wire/modules/Inputfield/InputfieldTinyMCE/InputfieldTinyMCE.module

Add the elements you want to configure to the $defaults array at the top. They should now be configurable with your TinyMCE fields in PW. The only thing I'm worried about is that PW currently just configures string-based values, so something like "false" or "true" will still be a string when sent to TinyMCE (rather than a boolean). It may not matter, and TinyMCE may already be looking for this, but if it doesn't work we'll have to do a little more editing, which I can walk you through--just let me know.

Link to comment
Share on other sites

Thanks a lot Ryan :)

I actually looked at that file but I didn't realize I could just add pairs to the array... :/

Indeed as you worried things get weird passing those values via processwire's UI...

(Enter puts a paragraph break and a newline in wysiwyg, and two <br /> in the code; Shift + Enter puts a newline in wysiwyg and nothing in the code)

Whereas if I change the config default values in InputfieldTinyMCE.js things go as expected

(Enter or Shift + Enter produce a newline in wysiwyg and a <br /> in the code)

For the actual issue I've at hand it doesn't matter anyway, as I didn't think at the easiest solution, replacing Ps with BRs when I output the headline field in the template - which is a shame since there was a php example just at the bottom of the tinymce documentation page I linked... :)

I've this now in the template

<h1>
<?php 
if ($page->rootParent->headline) {
	$tinyp = $page->rootParent->headline; 
	$tinyp = preg_replace('/<p[^>]*>/', '', $tinyp); 
	$tinyp = str_replace('</p>', '<br />', $tinyp);
	echo $tinyp;
} else { 
	echo $page->rootParent->title;
};
?>
</h1>

which seems to fit my needs just well (no <p> inside <h1>, and no inconsistencies in tinyMCE wysiwyg)

Thanks for the explanation anyway, it's very useful to know that many tinyMCE configs can be exposed so easily in processwire field config UI, makes me quite confident about any editor tweaking one could need for a project.

Guess you're quite busy so you don't need to bother digging in the details of passing boolean values instead of strings, I'll pop up for info if the need arise.

Link to comment
Share on other sites

Thanks for following up about this – glad that you were able to find a solution that works well. Definitely just let me know anytime you need any help getting PW's TinyMCE module to support any of those other values.

Link to comment
Share on other sites

  • 2 weeks later...

Hi all and mostly Ryan, :)

Actually.. Instead of ABU I am the guy who need an advice related to the TinyMCE configuration in PW.

I wouldn't like to waste your time if it is more complicated and time consuming answer.

Using the default PW settings the TinyMCE editor wraps "p" tag on each none block element.

If in the field is placed a table, inside each of the "td" are generated "p" tags too. I have set margin and padding to zero for "table p" and this solved the problem visually but the "p"s are still there. I have spend... hours playing with forced_root_block, indentation, removeformat_selector, valid_children, ...

Is there an tricky TinyMCE setting that will prevent that? Also.. the output formatting doesn't worked for me too. I know both are not so important but.. if someone could give a hint - it will be great.

Thanks.

Alex

Link to comment
Share on other sites

Alex, TinyMCE seems to be inconsistent about when it applies the <p> tag inside tables. I think its behavior may vary from browser to browser, though have not confirmed that. I'm using Firefox 4 and Chrome 12. On the sites that I use it on, it's only on rare occasions that a <p> tag shows up inside table cells. Because it's so rare, I just remove them manually when it happens in the HTML code view of TinyMCE.  

If you are finding it's doing it all the time, first check that you don't have any TextFormatters turned on in your field. When using TinyMCE, you generally don't want any other text formatting to take place since TinyMCE is writing out HTML.

If you can't solve this with TinyMCE settings, you may want to do something more brute force. Edit this file:

/wire/modules/Inputfield/InputfieldTinyMCE/InputfieldTinyMCE.module

Then locate this function:

<?php
       public function setAttribute($key, $value) {
               if($key != 'value') return parent::setAttribute($key, $value);

               /*

               // remove empty tags
               $value = preg_replace('{<([a-z0-9]+)>\s*( |<br />)*\s*</\\1>}i', '', $value); 

               // replace fake bulleted lists
               $value = preg_replace('{<br />\s*[-*]\s*}m', '<br />', $value); 

               // fix breaks to be paragraphs
               $value = str_replace(array('<br /> <br />', '<br /><br />'), '</p><p>', $value); 

               // fix paragraphs that start with a break 
               $value = str_replace('<p><br />', '<p>', $value) ;

               // remove arbitrary and incorrect bulleted lists
               $value = preg_replace('{\s*•\s*}', ' ', $value); 

               // fix those darn   tags
               $value = str_replace(' ', ' ', $value); 
               */

               return parent::setAttribute($key, $value);
       }

That function is what sets the value in ProcessWire, so you can modify the output from TinyMCE before it gets saved if you want to. Note all the commented stuff in orange. Those are all various solutions I've had to use to solve a specific problem on a specific site at one time or another. They are commented out because they really only apply in specific cases. But it sounds like you have a specific case like this. So what I would do is add something like this before or after that commented stuff already in the function:

$value = str_replace("<td><p>", "<td>", $value); 
$value = str_replace("</p></td>", "</td>", $value); 

That would make it remove <p> tags that open and close with the <td> tags. This may not be an ideal solution, but it would get the job done.

If you want to account for possible whitespace between the opening or closing table cell and paragraph tags, here is another solution to try (though writing in browser, not tested):

if(preg_match('/<td>\s*<p>/', $value)) {
   $value = preg_replace('{(<td>\s*<p>|</p>\s*<(/)td>)}', '<$2td>', $value);
}
Link to comment
Share on other sites

That function is what sets the value in ProcessWire, so you can modify the output from TinyMCE before it gets saved ...

That was the golden key.

Solved the <p> and many other string related issues with regex in setAttribute() method. Have used the regex with white spaces! Thanks, appreciate it.

Will reply here if I find a better TinyMCE settings related to output formatting.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...