Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Hello,
I'm would like to write/ port an editor integration (jquery based editor) but don't know how the interface works. Is a documentation available which describes how the functions work an what the code do (which format is needed for plugins? have to converted before return data? ...)?
Best regards
Comments
Comment #1
TwoDWe haven't gotten around to making an official documentation of this yet. There's been little interest earlier and we've simply focused on other things. I wrote a little about this not long ago in another issue, but that could be a bit hard to find so I'll write about it here as well. Maybe this could be the start of such a documentation addition to wysiwyg.api.php and wyswyg.api.js where our plugin hooks are documented?
There are two ways to create an editor implementation. Or rather, there are two ways to make Wysiwyg core recognize and use it. In both cases you need one editorname.inc (PHP) file and at least one editorname.js (JavaScript) file, for the serverside and clientside implementations. We'll get to the actual contents of the file in a moment. The .inc file's purpose is to provide meta data about the editor library like what JavaScript files it uses, what buttons/plugins/extension it provides, what the currently installed version is and if there are any version specific overrides and some other stuff. The .js file does the heavy lifting when it comes to actually instancing and using the editor on a field, it also takes care of cleaning up anything added by the editor when it is destroyed.
The first way to get the editor implementation recognized is simple, just put the .inc file at wysiwyg/editors/editorname.inc and the JS file in wysiwyg/editors/js/editorname.js.
Wysiwyg loads all .inc files in the editors folder and will be instructed to add the .js file when it's time to use the editor.
The second way is to provide an equivalent of the editors folder, but in a different module. This is done by implementing hook_wysiwyg_include_directory($type). You'll probably notice that this is the same hook used for providing cross-editor "Drupal plugins", but now we're interested in returning 'editors' (or whatever you name the module's subfolder) when $type is 'editors'. There's a short sample implementation in wyswyg.api.php. This simply tells Wysiwyg to also look for .inc file in sites/[all|sitename]/modules/MYMODULE/RETURNED-STRING when listing what editors are available on admin/settings/wysiwyg, or when being told to load a certain editor library. Let's say it finds myeditor.inc in there. Then it'll call a hook implentation to get more info about 'myeditor': MYMODULE_myeditor_editor().
We'll use the TinyMCE implementation as a reference here:
The settings callback function for some editors can look very intimidating but it's not really that complex. It basically gets an array with all the values from the profile config form at admin/settings/wysiwyg/profile/#/edit as the $config argument. These are 'translated' to keys and values the editor can understand and set on the $settings array, but not all of them are currently useful for all editors (I'm working on customizing that form for each editor). The $settings array is returned and later passed via drupal_add_js() to become
Drupal.settings.wysiwyg.config.editorname.format#
(where # corresponds to the format id the profile is associated with) on the client.There's a special setting called 'buttons', which of course is where all the buttons you selected from under "Buttons and Plugins" are listed, keyed by the plugin providing them. This one usually takes a bit of effort to translate as it's also used to figure out what plugins need to be active. Some plugins may not even have buttons, so we just call them extensions.
The JavaScript implementation is currently a bit tricky and I'm running out of time here so this will be really brief.
There are a couple of methods that each editor implementation must define.
The first one is "attach" (set as
Drupal.wysiwyg.editor.attach.editorname
). It gets the $settings array passed to it (now as a JavaScript array) whenever an editor is to be attached to a field. It also gets some field-specific data in the param argument, to say if the editor should be active at all, what the id of the field is, and what the selected input format is (this is only called for an editor when a profile of its type is associated with the selected format, so there's no danger of attaching the editor at the wrong time). The context is an element containing the original textarea (and now the editor instance too), useful for passing as the context argument to jQuery()/$().The second one is "detach", which is obviously the reverse of the first method. Destroy the editor instance - don't forget to sync the contents back to the original field first, if the editor doesn't do this on its own - then clean up any event handlers that editor has set on the form or elsewhere. A "leave it as you found it" approach is used here. ;) You never really know why the editor was detached. The form could have been submitted, the editor might just have been deactivated or is about to be replaced by another editor.
The third one's a special method which may not be needed by all editors. It's
Drupal.wysiwyg.editor.init.editorname
and it's called during page load, before the onload events have fired. TinyMCE needs to run at this point to set some global library data and load external plugin files, otherwise they won't be available if a TinyMCE instance is active by default.Next comes
Drupal.wysiwyg.editor.instance.editorname
, which is currently a great source of confusion. It's meant to be a collection of methods which act directly on an attached editor instance, called only when an instance of the editor in question is attached. You'll see that we sometimes call methods set here directly, though I think that's wrong since Wysiwyg core only uses this object as a template for creating actual instance objects inDrupal.wysiwyg.instances[field-id]
before the editor is attached. Note: Not actual TinyMCE/CKEditor/FCKeditor instances, "instances" of our implementation of an editor instance. Get it? ;)Anyway, there's really only one method you currently need to care about on the instance object: "insert". This is called when it's time to, well, insert a HTML snippet in the editor. Both cross-editor plugins and other modules can call this method, so it's a bit har to know what to expect as input. If the editor has an "insert html" API function, this is the time to call it. Note: "this" inside that method will refer to
Drupal.wyswyg.instances[field-id]
as it would be called like:Drupal.wyswyg.instances[field-id].insert('<h1>Hello World!</h1>')
.The other methods in the instance object are editor-specific and not needed by all editors. The open/closeDialog methods were meant to provide a way for cross-editor plugins to "blend in" a bit more and use the editor's own dialog templates etc, but it turned out to be a mess to implement this way. D7 has dialog support anyway and we'll probably backport a similar solution to D6 if we don't just cut it all out. (AFAIK, only img_assist relies/relied on it, and it just works/worked with TinyMCE much for this reason.)
Inside the insert method on the instance, you'll have access to all the parameters from the attach function as properties of the "this" reference.
this.field
gives the id of the current field for instance. This is also true for any other method on the instance object given they were called viaDrupal.wysiwyg.instances[field-id].method()
and not directly viaDrupal.wysiwyg.editor.instance.editorname.method()
.I hope that helps some. To determine what all the arguments in the PHP callbacks contain, I can recommend using the Drupal for Firebug module and its firep() function. (Similar to Devel's dsm() or print_r() but you see the output in a Firebug tab.)
Comment #2
sunWe want to move most of this into wysiwyg.api.php :)
Comment #3
JohnnyX CreditAttribution: JohnnyX commentedOk, thanks. I will take a look and do a first try to integrate cleditor. My first steps with drupal modules :)
Comment #4
JohnnyX CreditAttribution: JohnnyX commentedPlease delete...
Comment #5
JohnnyX CreditAttribution: JohnnyX commentedProblem 1:
"The installed version 1.2.5 of clEditor is not supported."
I don't know why isn't supported.
versions
wysiwyg_cleditor_version()
It returns 1.2.5! Tested with a simple echo $version[1]; break; But doesn't work... If I add return '1.2.5'; to first line of function it works...
Problem2:
Editor will not appear after attached.
.cleditor() should simply show an editor with toolbar. Maybe a bug with Drupal 7 (jquery) or wysiwyg module?
Comment #6
TwoDYour regular expression might be catching an extra character after the version string, such a s a newline. Try with just
if (preg_match('|@preserve CLEditor WYSIWYG HTML Editor v([0-9\.]*)|', $line, $version)) {
. Or perhapsif (preg_match('|@preserve CLEditor WYSIWYG HTML Editor v([0-9]+(?:\.[0-9]+)*)|', $line, $version)) {
to find that string followed by at least one number then optionally followed by multiples of a dot followed by at least one number?I'm not sure why the editor wouldn't attach, the code looks ok. Are you getting any errors? Have you tried using Firebug to insert a breakpoint on the .cleditor() row and stepped from there?
Comment #7
JohnnyX CreditAttribution: JohnnyX commentedTwoD:
You're right, thanks! Maybe a extra charakter after version string. Fixed and works :)
But attach editor is strange... I can't find any wysiwyg or cleditor string in source code?! No path or file found.
Comment #8
TwoDCould you post/attach the entire files?
Comment #9
sunComment #10
Kate101 CreditAttribution: Kate101 commentedHello,
I'm seeing the same issue as described by JohnnyX (above) when I'm trying to integrate a new editor:
Problem2:
Editor will not appear after attached.
Drupal.wysiwyg.editor.attach.cleditor = function(context, params, settings) {
$('#' + params.field).cleditor();
};
Did you ever manage to resolve this? I've tried debugging but am seeing no errors thrown.
Thank you!
Comment #11
TwoD@Kate101, is the script file containing that snippet being included in the document by Wysiwyg when a format with that editor is available?
Have you set a breakpoint in the attach method to see if it gets called?
Could you post the entire integration files (prefereably the entire module implementing the Wysiwyg hooks) you are using? It's a bit difficult to guess what's wrong without having any code to look at.