Announcing Wysiwyg API - major milestone

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
sun's picture

I took the time to rewrite the Wysiwyg (Editor) module into a generic API over the weekend. So the primary concerns about TinyMCE-specific code all over the module are eliminated now. Also, you might have noticed, that I have added an example integration for FCKeditor already - which of course is rather a proof of concept than a fully-fledged integration (and it works cleanly 8).

So Wysiwyg has become a real API finally.

Since Wysiwyg API contains only minor changes between 5.x, 6.x, and upcoming 7.x, I want to encourage all developers and maintainers of so called "editor integration modules" in contrib to write a similar migration function like the one that exists for users of the obsolete TinyMCE module in wysiwyg_editor.install.

Please bear in mind that with each active developer joining the project, and each new end-user of Wysiwyg API, the probability of having proper support for client-side editors in core for Drupal 7 increases. So instead of working on dead-end projects, join forces, please!

The next major steps are:

Allow to configure advanced editor settings
http://drupal.org/node/313497

Attach client-side editors to input format enabled textareas only
http://drupal.org/node/253600

...and I'm already working on a new plugin architecture, so modules like Image Assist can integrate into TinyMCE and FCKeditor (and others) concurrently, without having to implement editor-specific functions.

That said, another task for Wysiwyg API 1.x will definitely be to move and rename all functions into wysiwyg.module instead of wysiwyg_editor.module. I originally started with wysiwyg_editor, because I did not know whether support for "rich-text editors" would just be one component of a larger API, but just re-phrasing this into "support for client-side editors" along with an appropriate architecture turned out to be key.

EDIT:
A list of editor modules, which can be replaced by Wysiwyg API:

http://drupal.org/project/bbcode_wysiwyg
http://drupal.org/project/bueditor
http://drupal.org/project/editonpro
http://drupal.org/project/editarea
http://drupal.org/project/editor
http://drupal.org/project/fckeditor
http://drupal.org/project/htmlarea
http://drupal.org/project/htmlbox
http://drupal.org/project/jwysiwyg
http://drupal.org/project/markitup
http://drupal.org/project/nicedit
http://drupal.org/project/openwysiwyg
http://drupal.org/project/tinytinymce
http://drupal.org/project/tinymce_autoconf
http://drupal.org/project/tinymce
http://drupal.org/project/whizzywig
http://drupal.org/project/widgeditor
http://drupal.org/project/wymeditor
http://drupal.org/project/xstandard
http://drupal.org/project/yui_editor

Comments

sounds great

Chris Charlton's picture

Wow, this sounds great!

Chris Charlton, Author & Drupal Community Leader, Enterprise Level Consultant

I teach you how to build Drupal Themes http://tinyurl.com/theme-drupal and provide add-on software at http://xtnd.us

HTML filtering: client -vs- server sides?

markus_petrux's picture

Do any of these solutions provide a mechanism to sync HTML filtering options/capabilities between client and server?

If this has been answered elsewhere, or if it can be considered offtopic here, could you please provide a link? :-|

Clarify

sun's picture

Sorry, I am not able to grasp what you are talking about. Could you please elaborate on "sync HTML filtering options/capabilities between client and server"?

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Let's see this with TinyMCE

markus_petrux's picture

With TinyMCE you can configure the WYSIWYG editor to accept HTML elements and attributes from a whitelist (see valid_elements). But then, what the server gets needs to be processed (probably) by a filter that matches the same combination of features that are allowed for the WYSIWYG editor. Otherwise, a) users will be able to do things that do not show when content is sent, or b) you have to enable Full HTML, which might not be an option.

So, it would be nice if there was a method to keep in sync both sides: what the WYSIWYG editor allows you to do, ought to match what the filter in the server sides allows you to post.

...in the goals

sun's picture

Yes, this is in the scope of the goals of Wysiwyg API, but not yet implemented. See http://drupal.org/project/wysiwyg for a complete list along with the current status.

However, the goal is to pass information about allowed markup to the client-side editor (and not the opposite), so the designated editor has to support a configuration setting like TinyMCE's valid_elements. Reason: We cannot alter the HTML filter for each post.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Thank you! :)

markus_petrux's picture

Looks really great.

Though filter_xss() doesn't allow you to filter by HTML element attributes. Will it be possible to enhance that too?

filter_xss

dwees's picture

This filter is based on a Php script someone else wrote which is far more extensive and allows for exactly what you are looking for, filtering html element attributes. I forgot who exactly wrote this more extensive script, but you could find out. It may be that we need to provide another filter module to allow for this type of filtering.

Dave

AFAICT, Nope

markus_petrux's picture

filter_xss() takes a whitelist of HTML elements, but it is not possible to whitelist HTML element attributes.

filter_xss

dwees's picture

I don't think you read my comment very closely. Filter_xss doesn't do this buuuuttt ...

this library does.

So you'd be able to whitelist attributes using this library.

Choices.

sun's picture

Yes, that's one alternative to core's built-in HTML filter. However, there is also http://drupal.org/project/htmLawed, and I'm pretty sure that there are even more in the wild.

However, Wysiwyg API will focus on core's HTML filter. When the integration is being developed, we will bear in mind that it will be capable to support other HTML filters, too.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

This is it

markus_petrux's picture

http://drupal.org/project/htmlpurifier

The other one I knew of has been posted by sun above.

No.

sun's picture

Wysiwyg API has a clear intention: Hit core.

Drupal core will not support client-side editors on textareas, which do not support editors - technically speaking: which do not support input formats. Input formats control what happens with a piece of content, respecting user permissions and administratively allowed markup in those contents.

D7 comes with improved support for this. We are working on a interim solution for D6 and D5 currently here: Attach client-side editors to input format enabled textareas only

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

markus_petrux's picture

Will it be possible to create a contrib module that provides a version of filter_xss() that is also able to whitelist HTML element attributes and that module provide a Input filter where admins can configure which attributes can be accepted per HTML element to filter content as well as to provide a fully configured valid_elements parameter for TinyMCE?

Not sure if there is anything like this already. :-|

The problem is that if HTML filters don't match between client and server, users keep sending reports like "I'm posting X, which is displayed ok in the WYSIWYG, but not when sent to the site".

How could we solve these kind of problems? What do you suggest?

You're stuck...

sun's picture

...on the obsolete way of attaching editors to textareas, which do not support the potential markup at all. By attaching editors to input formats, no editor will appear on textareas that do filter_xss_admin() only. Instead, editors are closely tied to the input format, and one of the planned improvements on the roadmap is to make the available editor buttons/plugins dependent on the allowed values of the HTML filter. Hence, we can not only limit the toolbar buttons of an editor, but also limit allowed HTML markup the user is able to type in - that is, as long as the editor supports it.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

markus_petrux's picture

Something needs to provide an input filter (not input format) to support features like valid_elements / extended_valid_elements in TinyMCE, I guess.

So ...where would I be able to configure which HTML element attributes I would like to allow (both sides) ? ...transparently, only by setting up editor options attached to input formats? ...but then, who provides the input filter equivalent to filter_xss() ? ...this is what I can't see. Sorry, if I missed something.

Allowed markup

sun's picture

Well. There is not yet an integration between the "HTML Filter" and a Wysiwyg editor profile. When we get to this point, we will have two possible ways for integration:

  1. Allow the user to select an editor, editor buttons, and plugins. Each added thing/object is able to alter the values of allowed markup in the "HTML filter", so it is ensured that any required markup will not be stripped.
  2. Make available editors, editor buttons, and plugins dependent on the values of the "HTML filter". Stuff that requires markup, which is not allowed by the HTML filter, will not be available.

Compare the two options. And hear Heine scream. ;) Certainly, only the latter would protect novice users from opening a can of worms without having a clue.
However, fact is, that we have full access to all configured input formats along with their input filters. We could even do it both ways, but I'm rather reluctant to implement the first option. Of course, all of this would have to be configured on the input format/filter configuration pages.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Agree 2 is what I was thinking about too

markus_petrux's picture

To achieve this, the wysiwyg api would have to provide a method that a filter could use to inform allowed HTML elements, attributes, classes, or whatever.

Aside from that, I was thinking in creating a clone of filter_xss() that could also get a whitelist of HTML element attributes, and provide a hook or something similar to allow external filtering of attribute values, which could be used to validate classes, etc.

I think htmlLawed and htmlpurifier are too heavy, specially compared to filter_xss(). So I'm thinking in something that could live in the middle.

Is that a reasonable approach?

...

sun's picture

I'm not really sure what you are talking about. I do not need a new filter_xss() function to compile a list of allowed HTML tags from HTML filter or whatever filter.

What counts is mapping. The filter tells us, what markup is allowed. Hence, all editor buttons and plugins need to indicate what markup they require.

Diff this, and the result is a list of available/possible/allowed editor functions that can be assigned to a Wysiwyg profile.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

markus_petrux's picture

The knowledge of which HTML elements, attributes or whatever is defined within the input filter context, but different input filters will store this information is different ways. So...how the wysiwyg api will get these settings so it can pass them on to (say) TinyMCE?

I think this is one of the most important things that need to be solved because otherwise a) the wysiwyg editor will allow users write things that will get filtered on the server (causing confusion) or b) you have to restrict wysiwyg usage to roles that have Full HTML filter access.

I'm not sure how to describe my case, maybe explaining my particular situation helps.

Please, see this site:
http://blogs.gamefilia.com/blogs (every blog has its own custom design)

It's a spanish community related to videogames. Each user has its own blog. They are teens mostly, and they will hach us if they have an opportunity (sigh), so I cannot give them Full HTML. On the other hand, when TinyMCE allows them to do something that cannot be reproduced when the post is sent, they knock my door, or maybe they go somewhere else to create their blog.

That's a site running Drupal 5 with TinyMCE module, but I had to bypass the way it configures TinyMCE for several reasons, one of them is that users have their own configurable blog designs, and I had to tweak TinyMCE CSS for every user. Another reason is that I need to sync the HTML filter on the server with the features enabled in TinyMCE. I'm not happy though, because it is all somehow hack-ish.

Now, I'm working on a project migrating a spanish online games magazine (currently using a propietary CMS/Framework), but the new site will be Drupal 6 based. Here, I also need to provide TinyMCE for a lot of users. I still need to get control of HTML filtering, and this is the most critical part of WYSIWYG implementation. That's why I'm asking for this here. I'm not sure which is the best approach.

I think this time I'll write a clone of filter_xss() where I could also use whitelists for HTML attributes, etc. (maybe in the form of a contrib module) and I'm wondering how this custom filter could tell the wysiwyg api module how to configure TinyMCE's valid_elements parameter.

Sidenote: HTMLpurifier and htmlLawed are too big, and carry on a lot more features than are not really needed. I just need to get control of which HTML elements and attributes are allowed on the server side, availble on the WYSIWYG editor and that both match so we can stay as secure as using regular filter_xss(), but also provide a consistent WYSIWYG editor for users.

Hook after invoking wysiwyg_editor_get_config() ¿?

markus_petrux's picture

Maybe it would be interesting to invoke a hook to allow external modulesalter editor settings after wysiwyg_editor_get_config() is called?

That way an external module implementing an input filter could inform the editor of which HTML elements/attributes are allowed in the client side. ie. the input filter could set the valid_elements option of the TinyMCE editor.

Step by step

sun's picture

I will keep both of your latest posts in mind, when starting with the input filter integration. The current work focuses on other aspects of the API, see http://groups.drupal.org/node/6492/summary

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Thank you!

markus_petrux's picture

I'll be checking there and try to help as time permits.

If I was to write a filter_xss() clone (maybe in the form of a contrib module) with the above mentioned capabilities (allow setting up a whitelist of HTML attributes as well as a whitelist of HTML elements), then I would love to be able to integrate it with wysiwyg api. :)

filter_xss() alternative for TinyMCE in the works

markus_petrux's picture

@sun: please, check this:

http://groups.drupal.org/node/15979

I need a method to tell Wysiwyg API the valid_elements parameter than will be configured within the filter settings panel.

Thank you! :)

Thank you for working on

SamRose's picture

Thank you for working on this.

One question I have about this API, andit's stated goal to allow other modules to interact with WYSIWYG

To what extent is this possible, currently. Looking at http://drupal.org/node/152046 and other examples give me some ideas. But, I think I am fantasizing that this could be a way to do things like affect where a WYSIWYG editor will show up per field, (potentially) let new modules add new functionality to WYSIWYG editor, etc

Is this within the scope of this API?

Sam Rose
Social Synergy
Open Source Ecology
P2P Foundation

...

sun's picture

...fantasizing that this could be a way to do things like affect where a WYSIWYG editor will show up per field...

As mentioned above, the appearance of client-side editors is controlled via input formats ultimately. To give you the most comprehensive idea: For example, consider a textarea that is input format-enabled and contains PHP code. If an editor would be loaded for this textarea, the PHP code would be destroyed without being able to be recovered, since many editors implement (at least) basic HTML markup validation.

(potentially) let new modules add new functionality to WYSIWYG editor

Yes, the ultimate, long-term goal is that modules like Inline, Image Assist, Linktocontent, Paging, etc. only need to implement JavaScript code to integrate with Wysiwyg API, but not for integrating with every single editor. This is what I often call the mystic "generic stub plugin", which solely builds a bridge between the editor GUI and the output/UI from Drupal modules. And btw: this is where my original draft, sun's vision for handling embedded/inline content and Wysiwyg in Drupal I wrote more than a year ago, comes into play.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Looks like a great start

Owen Barton's picture

Looks like a great start :)

One snafu that has come up for me previously is the conflict between the following very common requirements:

  1. Use a WYSIWYG editor (that inserts <p> and <br /> tags)
  2. Provide for advanced users who want to edit HTML and want reasonably formatted HTML (not a single line, which you need if you want 3)
  3. Provide for users with Javascript disabled who need to be able to type basic text without adding <p> tags for each paragraph

With TinyMCE at least you can hit either (1) and (2) OR (1) and (3), however it is impossible to hit all 3. With the smartlinebreakconverter project, or by manually switching input formats you can kinda hit all 3, except that it still breaks if a user edits a page without TinyMCE and they edits the page with it disabled (they have <p> tags everywhere) or vice versa (TinyMCE strings all paragraphs together).

It's not an easy problem to solve. The only way I can think that nicely hits all 3 is to store all content with <p> and <br /> tags removed and add a Javascript hook that adds them in before loading the WYSIWYG editor and also removes then when the editor exits (on page save). It shouldn't be too hard to write reliable round trip code for this single transform.

Obviously it may not be desirable to add this directly to the API, but if we could ensure that we have Javascript hooks for the above then this would be a great :)

Sites that want to use wiki-like markup languages together with (simple) optional WYSIWYG editors have similar requirements.

Both ways are possible

sun's picture
  • smartlinebreakconverter sounds sane; might be an option for Drupal core, if it's stable enough.
  • I'm working on a new Wysiwyg Plugin API currently, which allows to add editor plugins via Drupal modules without having to implement editor-specific functions. Awesome stuff actually. See http://groups.drupal.org/node/6492/summary for the current status and roadmap.

Daniel F. Kudwien
unleashed mind

Daniel F. Kudwien
netzstrategen

Image

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: