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 - This page was cached on 05 Jun 2020 - 08:05.

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