[wp-hackers] Question about the architecture of the admin widgets.php

John BouAntoun jbouantoun at gmail.com
Mon Jan 4 22:59:14 UTC 2010


Thanks for the response Andy. My responses in-line

On Tue, Jan 5, 2010 at 9:45 AM, Andy Skelton <skeltoac at gmail.com> wrote:

> On Mon, Jan 4, 2010 at 5:09 PM, scribu <scribu at gmail.com> wrote:
> > If you sent a duplicate email on purpose, please don't do it again.
> Thanks.
>
> This adds nothing of value.
>
> On Mon, Jan 4, 2010 at 1:02 AM, John BouAntoun <jbouantoun at gmail.com>
> wrote:
> > So the general solution would be to use a queuable event binding
> mechanism
> > for all events in Wordpress, but failing that, the specific solution
> would
> > be to allow me to wire in a pre-display event and a pre-save event, to
> allow
> > me to do my mce control clean up and save triggering.
>
> The way TinyMCE is integrated into WordPress, you already have a
> general method for extending TinyMCE in plugins and themes. Use
> WordPress action hooks to inject your javascript at the appropriate
> times. Use filters to modify the editor's configuration.
>

I believe I made a decent attempt at this already, which has gotten me to
this point, but am open to the fact that I might be missing something. I
believe the source code will provide a more simple explanation than me
typing it out, but am concerned that the mailing list won't allow
attachments through. I've copied the snippet of the js code in here
(apologies for the verbosity). I appreciate that I might not be doing things
the cleanest way, but that's the reason I've emailed this mailing list. I've
read through much of the WP code and API documentation to get to this point
of knowledge.

// register some helper functions
        if(!is_numeric($this->number)) {
            echo "
                <script type='text/javascript'>
                /* <![CDATA[ */
                // function to fix the save event of a control
                function fixWidgetSaveEvent(widgetTitleSelector) {
                    // make sure tinymce copies it's data to the text editor
before save
                    var savebutton = jQuery('.widget-control-save',
jQuery(widgetTitleSelector).closest('form'));

                    // unbind old click event
                    savebutton.unbind('click');

                    //
                    // DIRTY! DIRTY! DIRTY. As of WP 2.9 the devs use a
live('click) event on the all save buttons which means I can't override it
                    //
                    // So we just add a bind('click') call to the button
itself and return false which runs before the button's live('click') event
and cancels it. dirty but it works so long as we return true
                    //
                    // rebind new click event
                    savebutton.bind('click', function(){
                        tinyMCE.triggerSave();
                        // call old click event functionality
                        wpWidgets.save( jQuery(this).parents('.widget'), 0,
1, 0 );
                        return false;
                        });
                }

                // actually bind another method on the click event of the
open arrow to remove/readd the mce editor to work around a ajax issue
                function fixWidgetOpenEvent(button, mceEditorID,
mceInitObject) {

                    //
                    // DIRTY! DIRTY! DIRTY. As of WP 2.9 the devs use a
live('click) event on all edit widget buttons which means I can't override
it
                    //
                    // So we just add a bind('click') call to the button's
parent which runs before the child's live('click') event. dirty but it works
so long as we return true
                    //
                    // register the pre-save function to trigger an mce save
                    button.parent().bind('click', function(){

                        var inside = jQuery('#' +
mceEditorID).parents('.widget').children('.widget-inside');
                        if(inside.is(':hidden')) {
                            //
                            // DIRTY! DIRTY! DIRTY. For some reason after a
re-sort of the sidebar there are two rich editor elements with the same
parent id even though jQuery says there is only one,
                            //
                            // So we just remove them all and readd,
everytime the panel is opened
                            //
                            var editorCount = jQuery('.mceEditor',
jQuery('#' + mceEditorID).closest('form')).length;


                            for(i = 0; i < editorCount; i++) {
                                jQuery('#' + mceEditorID +
'_parent').remove();
                            }

                            tinyMCE.init(mceInitObject.mceInit);
                            tinyMCE.get(mceEditorID).show();

                            // ajax event fix ups
                            fixWidgetSaveEvent('#' + mceEditorID);
                        }
                        return true;
                    });

                }
                /* ]]> */
                </script>
            ";
        }

        echo "
            <script type='text/javascript'>
            // initialise the editor
            tinyMCEPreInit_" . $this->number . " = {
                    base : '" . get_bloginfo('wpurl') .
"/wp-includes/js/tinymce',
                    suffix : '',
                    query : '" . $ver ."',
                    mceInit : {" .$mce_options . "},
                    load_ext : function(url,lang){var
sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');sl.markDone(url+'/themes/advanced/langs/'+lang+'.js');}
                };
            tinyMCEPreInit_" . $this->number . ".load_ext(tinyMCEPreInit_" .
$this->number . ".base, 'en');
            tinyMCE.init(tinyMCEPreInit_" . $this->number . ".mceInit);

            // workaround to make the sorting not break the tinyMCEeditor
            fixWidgetOpenEvent(jQuery('a.widget-action', jQuery('#"
.$this->get_field_id('title') . "').parents('.widget')), '" .
$this->get_field_id('aboutmehtml') . "',tinyMCEPreInit_" . $this->number .
");

            /* ]]> */
            </script>
            ";


> > Can anyone suggest a better approach to solve my issue or let me know the
> > likelyhood of either solution (general or specific) happening in the near
> > future so that I know if it's worth updating my plugin with the dirty
> hack
> > or not?
>
> Study the way WordPress modifies the behavior of TinyMCE. Then do as core
> does.
>

It's not so much about modifying the behaviour of TinyMCE, which I think
I've figured out, but am open to suggestions. The issue is that since the
widget admin screen was cleaned up in WP circa 2.8 (to support auto
multi-widgets), the widget options forms are preloaded and saved using
boiler plate code that isn't complex enough to understand how to extract the
html form a rich text editor, which is why I needed to play silly buggers
with the javascript to trigger a save on the save button's click.


> Cheers,
> Andy
> _______________________________________________
> wp-hackers mailing list
> wp-hackers at lists.automattic.com
> http://lists.automattic.com/mailman/listinfo/wp-hackers
>


More information about the wp-hackers mailing list