PackagingJQueryPlugins

Awaiting boiling down into a feature proposal
(08:27:15) CDot: MichaelDaum: I was thinking; is there some way we can streamline the packaging of jquery plugins?
(08:27:51) MichaelDaum: yes there definitely is still room for optimization
(08:27:54) CDot: I'm slightly concerned that when I package a plugin using JQueryPlugin, then that might conflict with the same plugin packaged by another Foswiki extension
(08:28:15) CDot: e.g. I'm packaging jEditable in EditRowPlugin, but I can see that being used elsewhere
(08:28:48) CDot: the problem seems (to me) to be that jquery don't dictate any packaging standards themselves
(08:29:07) CDot: so third party plugins can be a right mess
(08:29:26) CDot: e.g. stylesheets mixed in with code etc
(08:29:32) MichaelDaum: then our own previous answer always was: make jEdittable a contrib/plugin of its own ... is that still a sensible approach?
(08:29:41) CDot: that's what I'm wondering
(08:30:12) MichaelDaum: are you picturing a kind of mini-jquery module?
(08:30:38) CDot: not sure yet; just wanted to discuss it, see what ideas we come up with
(08:30:44) MichaelDaum: not a full fledged foswiki plugin but a thing that still is able to participate in JQREQUIRE
(08:30:53) CDot: how about a "bucket" on Extensions web
(08:31:05) CDot: yes, that sounds credible
(08:31:23) MichaelDaum: gawd I nearly typed AddOn
(08:31:23) CDot: could we dictate a packaging standard for jquery plugins?
(08:31:57) CDot: i.e. a Foswiki dir structure that has the files in the right places?
(08:32:22) MichaelDaum: thats hard because plugins come with their own idea how to orga css and js ... not compatible
(08:32:44) CDot: I know - but I don't mind "mapping" the JQ plugins. You have to do that anyway
(08:32:58) MichaelDaum: thats why I added this perl stub thingy to capture all kinds of info required to make it work
(08:33:03) CDot: but what I'd like to do is standardise - so that I only have to package jEditable *once*
(08:33:16) CDot: and I can then upload it as a (versioned) zip
(08:33:27) CDot: and anyone else can use it
(08:34:05) MichaelDaum: we almost have the standards to make it work ... all it needs is better automation
(08:34:12) CDot: that perl "stub" is like a MANIFEST
(08:34:17) CDot: ish
(08:35:04) CDot: but I have to call registerPlugin, which is a problem. Or is it?
(08:35:33) CDot: if I could put in the MANIFEST of my extension something like:
(08:35:45) CDot: !jqueryplugin jeditable
(08:35:57) CDot: !jqueryplugin tinymce
(08:36:28) CDot: nah, that's not right
(08:37:08) MichaelDaum: we once had autodetection of (perl) plugins crawling a defined directory structure... we abandoned that for performance reasons
(08:37:23) CDot: oh, yeah, I agree autodetecton stinks
(08:37:34) CDot: I'm happy with a MANIFEST or DEPENDENCIES approach
(08:37:42) MichaelDaum: a kind of "look mummy I just found out the same thing yet again"
(08:37:48) CDot: the main problem I have is packaging for re-use
(08:38:13) CDot: I'd like to only have to package each plugin *once* and thn have it available for everyone
(08:38:26) MichaelDaum: okay so right now this means: make it a JQEditTablePlugin ... question is why
(08:38:38) CDot: as you did with JQueryPlugin, but without having it in the same package, IYSWIM
(08:38:58) CDot: yes, but making it a Foswiki plugin feels too.... heavy
(08:39:24) MichaelDaum: let me see ..
(08:39:35) CDot: really, this package doesn't need *any* perl - or aybe just one (simple) file
(08:41:13) MichaelDaum: sure, could be coded without perl...a perl hash just felt ... natural as thats what the module's info ends up anyway
(08:41:34) MichaelDaum: me reading JQueryPlugin/Plugins::init()
(08:41:37) CDot: sure, I don't have a problem with that
(08:42:03) MichaelDaum: it crawls the {JQueryPlugin}{Plugins} hash and does the registration automatically
(08:42:10) CDot: I see we have pub/System/JQueryPlugin/plugins ....  and also /themes and /images (and I guess /icons?)
(08:42:35) MichaelDaum: see lib/Foswiki/Plugins/JQueryPlugin/Plugins.pm
(08:42:44) ***CDot reads that code
(08:43:03) MichaelDaum: thats where the sub modules are registered kind of lightweighted ...
(08:43:25) MichaelDaum: kind of replicates the foswiki perl plugins behaviour w/o some overhead not required for javascript
(08:44:47) CDot: ok, so we have the requirement for a =configure= entry, which is fine I guess
(08:44:48) MichaelDaum: so how about we kick in there
(08:45:08) MichaelDaum: for lightweighted js addons
(08:45:15) CDot: let's see; what would a "simple plugin zip" look like?
(08:46:17) CDot: it it would need a .pm 
(08:46:35) CDot: e.g. lib/Foswiki/Plugins/JQueryPlugin/AUTOCOMPLETE.pm
(08:47:06) MichaelDaum: or a lib/Foswiki/Contrib/SomeoneElsesCoolStuff/foobar.pm
(08:47:43) CDot: yes, ok, that works
(08:47:59) ***CDot is looking at UI.pm and is horrified by the sub init
(08:48:15) CDot: gotta be able to do that more cleanly.....
(08:49:01) CDot: but I guess that isn't a "right now" requirement
(08:49:37) MichaelDaum: well that's a js library needing more care loading it into a page
(08:49:51) CDot: I know; that's why I looked at it ;-)
(08:50:17) MichaelDaum: thing worring me is that each jquery plugin author does her own i18n
(08:50:42) MichaelDaum: like ui is only internationalizing datepicker
(08:50:57) CDot: one thing for sure; we should *not* be trying to rewrite other people's jquery plugins
(08:51:00) MichaelDaum: or jquery.validate some of its error messages
(08:51:04) CDot: just packaging them
(08:51:22) CDot: jquery.validate is bad news. The more I poke it, the more bits fall off :-(
(08:51:39) MichaelDaum: damn right. even then it is xtra hard to get to know they released a bugfix ... most event have a bloddy rss feed on their homepage
(08:52:02) CDot: y. All the more reason to have our own "stable" repository
(08:52:18) MichaelDaum: had no problems with jquery.validate. whats going on that falls off?
(08:52:23) CDot: what about dependencies? e.g. jquery 1.4.2 won't work with jquery-ui 1.8.7
(08:52:47) MichaelDaum: thats the problem causing the most headaches
(08:52:50) MichaelDaum: dependency hell
(08:58:42) CDot: ok, so you favour ignoring dependecies?
(08:59:27) CDot: MichaelDaum: your hash has a =version= field in it
(08:59:29) MichaelDaum: thats this chrome plugin
(08:59:47) MichaelDaum: ^gmc
(09:00:12) MichaelDaum: CDot, yes it is the 1:1 version number of the 3rd party software
(09:00:17) CDot: so a plugin *should* be able to check dependencies itself, in the init method
(09:00:32) CDot: can it abort the init if there is a dependency failure?
(09:01:01) CDot: e.g. "throw "OUCH" if jquery->{version} < "1.4.3"
(09:01:11) MichaelDaum: isnt that handled by DEPENDENCIES ... as this is more of a package dependency
(09:01:23) CDot: we want to avoid having to have a DEPENDENCIES
(09:01:45) CDot: remember, these are "micro packages"
(09:02:09) ***CDot is thinking this work might suggest a direction for packaging web applications as well
(09:02:14) MichaelDaum: I think there's no problem to add a throw ... and a catch inside the init() registration loop to skip it when an exception was found
(09:02:50) CDot: I don' mind if the exception takes down the whole foswiki - this should be a "check once" thing, really
(09:03:07) MichaelDaum: or pollute warnings.log
(09:03:07) CDot: so no need for a try..catch
(09:04:49) MichaelDaum: one last thign: what the users sees is "the page doesnt work" and he needs some hints to find out whats going on... at least a "you are lumping together a bunch of jquery modules that really dont work out together"

-- CrawfordCurrie - 18 Feb 2011

Out of interest, what's involved in packaging up a JQuery plugin? Maybe this can be done using doc. In the interests of experiment, I tried this. I ended up with a very simple JEditableAddOn. Here's a (draft) tutorial:
First create the extension framework:
$ cd to the root of a subversion checkout
$ core/create_new_extension.pl JEditableAddOn

This should give you:
JEditableAddOn/
  data/
    System/
      JEditableAddOn.txt
  lib/
    Foswiki/
      Contrib/
        JEditableAddOn.pm
        JEditableAddOn/
          build.pl
          DEPENDENCIES
          MANIFEST

Create JEditableAddOn/pub/System/JEditableAddOn, and put the source (uncompressed) javascript there (you can call it _src.js or =.uncompressed.js, your choice. I prefer _src) </verbatim> pub/ System/ JEditableAddOn / jquery.jeditable_src.js </verbatim> Add this file to the generated JEditable/lib/Foswiki/Contrib/JEditableAddOn/MANIFEST.

Edit JEditable/lib/Foswiki/Contrib/JEditableAddOn/DEPENDENCIES and add
Foswiki::Plugins::JQueryPlugin,>4.01,perl,Required

Now, edit JEditable/lib/Foswiki/Contrib/JEditableAddOn.pm. You are best to clear this file out and start again.

package Foswiki::Contrib::JEditableAddOn;

use strict;
use warnings;
use Foswiki::Plugins::JQueryPlugin ();
use Foswiki::Plugins::JQueryPlugin::Plugin ();

use version 0.77; our $VERSION = version->declare('v1.7.1'); # keep these in sync with jquery.jeditable.js
our $RELEASE = '1.7.1'; 
our $SHORTDESCRIPTION = 'The JQuery "JEditable" plugin, packaged for use in Foswiki';

{
    # This is the JQuery plugin stub. You could put this in a separate file, but there
    # is no advantage to this, as JQueryPlugin doesn't have any other way to find it.
    package Foswiki::Contrib::JEditableAddOn::JEDITABLE;
    our @ISA = qw( Foswiki::Plugins::JQueryPlugin::Plugin );

    sub new {
   my $class = shift;
   my $session = shift || $Foswiki::Plugins::SESSION;
   my $version = $Foswiki::Contrib::JEditableAddOn::RELEASE;
   
   my $this = $class->SUPER::new( 
       $session,
       name          => 'JEditable',
       version       => $version,
       author        => 'Mika Tuupola',
       homepage      => 'http://www.appelsiini.net/projects/jeditable',
       puburl        => '%PUBURLPATH%/%SYSTEMWEB%/JEditableAddOn',
       documentation => "$Foswiki::cfg{SystemWebName}.JEditableAddOn",
       javascript    => [ "jquery.jeditable.js" ]);

   return $this;
    }
}

=begin TML

Call this from any other extension to include this plugin. For example,
<verbatim>
require Foswiki::Contrib::JEditableAddOn ();
Foswiki::Contrib::JEditableAddOn::init();
</verbatim>

=cut

sub init {
    unless (Foswiki::Plugins::JQueryPlugin::registerPlugin(
      'JEditable',
      'Foswiki::Contrib::JEditableAddOn::JEDITABLE')) {
   die 'Failed to register JEditable plugin';
    }
    unless ( Foswiki::Plugins::JQueryPlugin::createPlugin( "JEditable" )) {
   die 'Failed to create JEditable plugin';
    }
    return 1;
}

1;

So it's pretty simple to add a jquery plugin this way. However, note the init function. This function has to be called from another extension. JQREQUIRE will not work with this add-on, because the JQueryPlugin has no mechanism to accept plugins that have sources anywhere other than in the Foswiki/Plugins/JQueryPlugin directory - which should never be written to by another extension (separation of concerns).

If you want to be able to use JQREQURE, you have to create this as a plugin and define initPlugin in place of init. But this will always register the plugin. In my case, I don't want to always register it - I only ever use it from other extensions.

-- CrawfordCurrie - 21 Feb 2011
Topic revision: r3 - 15 Nov 2012, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy