How to use editor in plugins?

Discussions and requests related to new CMSimple features, plugins, templates etc. and how to develop.
Please don't ask for support at this forums!
Post Reply
svasti
Posts: 1660
Joined: Wed Dec 17, 2008 5:08 pm

How to use editor in plugins?

Post by svasti » Thu Jan 05, 2012 5:32 pm

HI the experts,

I somehow can't get tinymce into calendar the way I want to... And Christophs Wiki explanation is not fully understandable by me :( . What I need to know is, how to call the editor together with a specialized tinyMCE.init-configuration.

Code: Select all

init_editor(array('description'),'minimal');
is kind of useless, as calendar needs a very specific configuration (actually even two) together with a special skin. Any hints?

svasti

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: How to use editor in plugins?

Post by cmb » Thu Jan 05, 2012 6:41 pm

Hello Frank,
svasti wrote: And Christophs Wiki explanation is not fully understandable by me
I suppose I wouldn't fully understand it either, if I hadn't written it myself ;) Perhaps you can help to improve it, after you managed to make use of the interface for the calendar plugin.
svasti wrote:as calendar needs a very specific configuration (actually even two) together with a special skin.
In this case you have basically two possibilities: (a) require the user to install a file init_calendar.js to plugins/tinymce/inits or (b) use editor_replace() with an explicit call to init_editor(). I'll begin with explaining (b), to show it's drawbacks:

Solution (b)

editor_replace() takes as 2nd parameter a $config string. The format of this string will vary between different editors. So it's generally pretty useless to call editor_replace() with a second parameter (it makes sense only if the 2nd parameter would be omitted, but this possibility is not implemented yet; that was an oversight :oops:) , but instead you should call tinymce_replace(). But that means, that the call only works for the tinyMCE, what requires the user to install this very editor. (Well, I'm ignoring the fact that there are currently no alternatives ;)).

The format of the $config string for tinyMCE is a JSON configuration object without the surrounding { }, i.e. basically the content of one of the init_*.js files, but with all %PLACEHOLDER%s replaced. You can hardcode this config string or assemble it dynamically. But if you want to use the configured filebrowser you have to it's initialization manually: tinymce_filebrowser().

A short summary:

Code: Select all

include_once($pth['folder']['plugins'].'tinymce/init.php');
include_tinymce();
tinymce_filebrowser();
$config = '...';
tinymce_replace('CALENDAREDITOR-ID');
 
Solution (a)

You can copy one of the init_*.js as say init_calendar.js and make the necessary adjustments. Just keep the %PLACEHOLDER%s where appropriate. Then it's enough to call init_editor(array('CALENDAREDITOR_CLASS'), 'calendar'). But if the user has configured another editor as default, this will be called, and probably will fall back to the user's configuration, as init_calendar.js will be missing. So you're required to deliver init_calendar.js for other editors as well. If you want to support only tinymce, you can call it directly:

Code: Select all

include_once($pth['folder']['plugins'].'tinymce/init.php');
init_tinymce(array('CALENDAREDITOR_CLASS'), 'calendar');
 
I hope these explanations somewhat clarify things.

Christoph
Christoph M. Becker – Plugins for CMSimple_XH

svasti
Posts: 1660
Joined: Wed Dec 17, 2008 5:08 pm

Re: How to use editor in plugins?

Post by svasti » Thu Jan 05, 2012 7:59 pm

Hi Christoph,

I see, or rather, I see that the Simple part of CMSimple ends here. Solution (a) seems to be managable, although I still have to figure out how to make tinyMCE to do what I want.
Solution (b) is way more complicated, I would need some time to find out what to do with the the placeholders, and calling the textareas by ID is kind of unpractical in my case, so I'd rather avoid that.
cmb wrote:I hope these explanations somewhat clarify things.
what about a CMSimple-academy? Just 1 week of learning the whole stuff? We all come and visit you :lol:
svasti

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: How to use editor in plugins?

Post by cmb » Thu Jan 05, 2012 8:34 pm

Hi Frank,

indeed, that's not too easy (particularly solution (b)). But consider the situation before CMSimple_XH 1.5. You had to do the configuration of the editor all by yourself, what would be basically the same as solution (b). Well, with FCKeditor it was easier, as it was possible to copy and modify the existing config file, what's analogous to solution (a). So IMO the new editor interface is not too complicated, if a plugin author needs a special configuration, and it's very simple to use, if the default configuration suffices:

Code: Select all

init_editor(array('CLASSNAME'));
We (primarily Martin, Holger and me) had quite some discussion, how the interface should be, to make it easy to use from plugins without restricting plugin authors and editor integrators with special demands. It's simply not possible to specify an interface which supports all the bells and whistles of tinyMCE and CKeditor, that could be implemented by editors as Whizzywig, openWYSIWYG, CodeMirror et al. So this is the compromise we came up with ...
svasti wrote:and calling the textareas by ID is kind of unpractical in my case
Well, even that could be done without too much additional work. You might have a look at plugins/tinymce/init.js tinyMCE_instantiateByClasses(). That's basically what does the trick. And it even works, if the textareas have no IDs at all -- they're given a unique ID dynamically!
svasti wrote:what about a CMSimple-academy?
I guess, I have to learn very much for myself first. I'm still struggling somewhat with implementing editors as plugins -- that's even more baffling, particularly when it comes to coupling editors and filebrowsers.

Christoph
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: How to use editor in plugins?

Post by Holger » Thu Jan 05, 2012 11:36 pm

Hi folks,

the last weeks I had to upgrade some old SE-Installations to 1.5.
At the end the biggest problem was the new editor (I've posted my problems elsewhere).
So I made a really quick & dirty solution for the old FCKeditor in XH 1.5 and all my problems are gone (for now).
I've talked about that with Christoph and we've discussed if it would be a good idea to provide that code.

So upon this discussion I had now a closer look again:
IMO it's not a problem to integrate / connect a filebrowser to (F)CKeditor with the todays codebase.
But I stumbled about this:
cmb wrote:Well, even that could be done without too much additional work. You might have a look at plugins/tinymce/init.js tinyMCE_instantiateByClasses(). That's basically what does the trick. And it even works, if the textareas have no IDs at all -- they're given a unique ID dynamically!
AFAIK that's not possible by default with CK / FCKeditor and we have to code something like tinyMCE_instantiateByClasses() for CKeditor.

But I really not see an advantage to initialize the editor by classes (and I'm happy that the default id "text" is still in the core :) ).

@svasti:
svasti wrote:and calling the textareas by ID is kind of unpractical in my case, so I'd rather avoid that
Why? You need in both cases a <textarea> and, if you need more than one editor at the page, unique selectors.
IMO you'll end up in a code like the core:

Code: Select all

'<textarea name="some_name" class="some_class ....">' . htmlspecialchars($some_content). '</textarea>'; 
or

Code: Select all

'<textarea name="some_name" id="some_id" ....">' . htmlspecialchars($some_content). '</textarea>';  
(the core uses both, ID and CLASS, in the textarea)

So could someone explain me the advantage of using classes instead id's?
I would prefer (or in other words, I see no other way for CK :cry: ) this way:

Code: Select all

function init_editor($ids = array(), $config = false) 
$config can always be provided as a .js-file by the plugin IMO. So if a plugin has to use special configs, like calendar, it only has to check if there is one existing for the configured editor.

But it's no problem to use IDs for CK and classes for Tiny as long as every plugin uses the same code for the textarea like the core (ID and CLASS!):

Code: Select all

'<textarea id="some_id" name="some_name" class="some_class ....">' . htmlspecialchars($some_content). '</textarea>';  
To include a (default-configured) editor to a plugin is then just copy & paste the code from adm.php and rename the name, class, id and $content variable.


At the end a question to Christoph / Martin:

what's the secret behind function editor_replace($elementID = false, $config = '')?
I can't understand in which case this function is usefull.

IMO we only need include_editor() as a separate function and init_editor(...).


KR

Holger

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: How to use editor in plugins?

Post by Holger » Thu Jan 05, 2012 11:48 pm

And just another thing to suggest:

if a plugin just needs another skin or another toolbar, maybe it's a good idea when $config only overwrites the default editor-configuration.
So init_editor() will always create a working editor and $config only contains those settings, the plugin wants to overwrite.
That should be much easier for plugin developers than providing a full working configuration for a lot of different editors...

Maybe that's possible. What do you think?

Holger

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: How to use editor in plugins?

Post by cmb » Fri Jan 06, 2012 11:46 am

Hi Holger,
Holger wrote:I've talked about that with Christoph and we've discussed if it would be a good idea to provide that code.
The pros (well known and tested editor) and the cons (fails under IE9; takes time to implement) have to be weighed. I'm still not sure about it.
Holger wrote:But I really not see an advantage to initialize the editor by classes (and I'm happy that the default id "text" is still in the core ).
Initializing by classes might be a simple solution for calendar. AFAIK an editor instance is available for each event. So it's quite easy to give all of them the same class, and call 1 function to initialize them all. And that's the advantage of being able to initialize by class (a similar situation probably holds for Trabant). This way the burdon of implementing it is shifted from the plugin author to the editor integrator. Under the assumption, that there'll be more plugins that uses editors than editor integrations, it's an advantage. And the editor integrator might take the code from tinymce_initializeByClasses() and modify it according to his needs.

OTOH: if a plugin author needs more than 1 editor instance, it's not hard for him to postfix the IDs with consecutive numbers, and write a wrapper that initializes all these instances within a loop.

What's best for all? :?

Some "historical" information to consider: as Martin came up with the idea to call init_editor with an array of classes, it was very easy to handle this for tinyMCE by setting "editor_selector" in the init file. But that required the call to tinyMCE.init(). Unfortunately it's not possible to call tinyMCE.init() more than once with different settings (at least not by ready() handlers). This was recognized while Gert developed the current version of Realblog_XH. It was not possible to have separate configs for the editors of the teaser resp. the full blog entry. To make this possible, we had to use tinymce.Editor().render(), what requires the textarea's ID. So I came up with the *_initializeByClasses() function (besides some further changes to avoid clashes, if the initialization is called more than once).
Holger wrote:what's the secret behind function editor_replace($elementID = false, $config = '')?
This is the most flexible way to instantiate an editor. If the user (i.e. plugin author) wants to have his own, very special filebrowser, he could have it. That's not possible with init_editor(), as this will always call EDITOR_filebrowser(). Well, it's possible not to use %FILEBROWSER% in the init, but to provide an own filebrowser callback. But in this case editor_replace() might be the more direct way. And yes, as I've already written, it might not be reasonable to call editor_replace(), but instead %EDITOR%_replace().
Holger wrote:So init_editor() will always create a working editor and $config only contains those settings, the plugin wants to overwrite.
I don't know, if this could be implemented with reasonable effort for different editors. For tinyMCE that would probably mean, that two config objects have to be merged by JS before instantiating the editor. Well, not too big a deal, but what about possible conflicts. E.g. the default config uses the "simple" theme, but the plugin config relies on the "advanced theme". OTOH: the plugin author can alway make a copy of one of the init_*.js files and adjust it to his needs.

IMO it's hard to specify such a general interface for editors, if it's neither clear, which editors will be made available, nor which features are required by plugins. And perhaps it's reasonable to change the editor interface. But it might be good, to hear more opinions on this topic.

Christoph

PS: It would have been better, if this discussion were held in the beta or RC stage of CMSimple_XH 1.5.
Christoph M. Becker – Plugins for CMSimple_XH

Martin
Posts: 346
Joined: Thu Oct 23, 2008 11:57 am
Contact:

Re: How to use editor in plugins?

Post by Martin » Fri Jan 06, 2012 11:58 am

Hi Holger,

the function editor_replace() was ment to offer an easy solution to have one or more editor instances with specific configurations. Maybe someone needs an editor in the frontend or needs a basic editor for some kind of teaser text and a full blown version to edit some other content.

Code: Select all

function editor_test(){
    $html = '<form>
        <textarea id="my_id_1" name="my_teaser">Guten Tag!</textarea>
        <textarea id="my_id_2" name="my_content">I need a fullblown editor</textarea>
     </form>';

    include_editor();
    $html .= editor_replace('my_id_1');
    $html .= editor_replace('my_id_2', 'theme : "advanced",
                                                       theme_advanced_toolbar_location : "top"');

    return $html;
} 
That's pretty simple and maybe it's even what you had in mind with your suggestion. But, as Christoph wrote, if you want to support different editors things get complicated as you need different "config strings". But still, you do not have to spread your editor configuration files to the plugins/<editors>/inits-folder.

Martin

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: How to use editor in plugins?

Post by cmb » Fri Jan 06, 2012 12:04 pm

Hi Martin,
Martin wrote:But still, you do not have to spread your editor configuration files to the plugins/<editors>/inits-folder.
Perhaps init_editor()'s specification should be slightly extended to allow a full path for $config. This way the plugin could keep the config in it's own folder.

Christoph
Christoph M. Becker – Plugins for CMSimple_XH

Martin
Posts: 346
Joined: Thu Oct 23, 2008 11:57 am
Contact:

Re: How to use editor in plugins?

Post by Martin » Fri Jan 06, 2012 12:24 pm

Hi Christoph,
Christoph wrote:Perhaps init_editor()'s specification should be slightly extended to allow a full path for $config. This way the plugin could keep the config in it's own folder.
That's a good idea!
Christoph wrote:Unfortunately it's not possible to call tinyMCE.init() more than once with different settings (at least not by ready() handlers). This was recognized while Gert developed the current version of Realblog_XH. It was not possible to have separate configs for the editors of the teaser resp. the full blog entry. To make this possible, we had to use tinymce.Editor().render(), what requires the textarea's ID. So I came up with the *_initializeByClasses() function (besides some further changes to avoid clashes, if the initialization is called more than once).
Sorry, that I missed that discussion. And I haven't had a look at *_initializeByClasses(), but - at least with TinyMce - this works as well:

Code: Select all

function editor_test_2()
{
       $html = '<form>
        <textarea id="my_teaser" name="my_teaser" class="my_teaser_class">Guten Tag!</textarea>
        <textarea id="my_content" name="my_content" class="my_content_class">I need a fullblown editor</textarea>
     </form>';

    init_editor(array('my_teaser_class'), 'minimal');
    init_editor(array('my_content_class'), 'full');
  
  return $html;
}  
:?:

Edit: Sorry :oops: - now I see that this second solution was not possible without the new js-function tinyMCE_instantiateByClasses() ...

Martin

Post Reply