Sharing JavaScript Code in Webmin

I posted a while back on my personal blog about some UI enhancement work that I’ve been doing in Webmin using the ExtJS JavaScript toolkit. Several folks had questions about whether Webmin was getting a new “official” JavaScript toolkit (it has some ancient and ugly API calls to generate a few JavaScript helpers for things like field graying and validation and such, but they aint got that AJAX religion), and, if not, how one could add a JavaScript library to Webmin to cleanly share it across modules and themes.

So, the answer to the first question is that Webmin is not getting an “official” JavaScript toolkit at this time. Webmin has as one of its core goals that it can be used by anyone anywhere with any browser. AJAX and heavy JavaScript usage makes that goal far more complicated. For example, we consider it a serious bug if a blind user using a screen reader can’t use Webmin. That said, we also recognize that AJAX is the best way to handle huge classes of user interaction problems, and with our commercial offering we have a strong interest in having the best looking, and most pleasant to use, UI in the field. So, I’ve begun to build a “semi-official” Webmin module that contains ExtJS and some helper functions and classes. The first example usage of this will be our new TheJAX Virtualmin theme, and soon after a few new modules.

For the second question, I’d just like to show how I’ve created this new ExtJS module for Webmin, and how one can use it. It only takes a few minutes to wrap something up into a module, and since most AJAX frameworks are making use of good JavaScript design practices and using their own namespaces, you can actually mix and match without too much pain.

Hidden Modules

So, Webmin has a very powerful module system, that allows you to package code for easy distribution and installation. A Webmin module is simply a directory with some files in it. Only one file is mandatory to make the directory into a “module”: module.info

So, we create a directory named extjs within the Webmin directory (/usr/libexec/webmin on my system), and make a file called module.info with the following contents:

name=ExtJS
desc=ExtJS AJAX Toolkit
depends=1.360
version=0.1
hidden=1

Here I’ve given it a name, and a short description, noted the version of Webmin it depends on, given it a version (I’m going to stat it at 0.1, though the contained ExtJS version is 2.0b), and set it to be hidden. The hidden option means that users won’t be able to see this module in the UI, but other modules can make calls to it. Later, if I decide to add configurable options to this library that I do want users to be able to see, I can make it visible and add an icon and a UI.

Now, I can start dropping in my files. I merely unzipped the ExtJS bundle, deleted the extraneous files, and dropped it into an ext directory within the module directory. That’s just to make it easy to update ExtJS components separately from the helper functions that I write in Perl in the top-level directory.

Helper Functions

So, the simplest thing to automate away is the inclusion of the script tags that load the library. So, I’ll create a header_text function in a file called extjs-lib.pl (Webmin has a convention of calling function libraries modulename-lib.pl), which looks like this:

 # extjs-lib.pl
 
do '../web-lib.pl';
&init_config();
 
my $debug=''; # Set to '-debug' to use non-stripped library
 
# header_text()
# Text to load JavaScript and CSS for use of extjs
sub header_text {
  return <EOF;
<script src="/extjs/ext/adapter/ext/ext-base.js" type="text/javascript"></script>
<script src="/extjs/ext/ext-all.js" type="text/javascript"></script>
<link href="/extjs/ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
<link href="/extjs/ext/resources/css/xtheme-$config%7B" rel="stylesheet" type="text/css" />
EOF
}
 
1;

Here we pull in the Webmin core library, pull in the configuration for this module (which I’ll cover in a couple of days when I’ve completed the configuration code for this module), and build the function to return the bits of text we need to properly load ExtJS and its stylesheets.

Using It

Believe it or not, we’ve now got a library that can be used by other Webmin modules or by themes. Webmin has a foreign_require function that will pull libraries like this in under their own namespace. So, when I need to use ExtJS, I can do this:

foreign_require("extjs", "extjs-lib.pl");
print extjs::header_text();

All done! In a few days I’ll be finished with the first full-featured version of this library, and will wrap it up for distribution, along with some proof-of-concept modules that show how to use a full-featured AJAX interface without breaking text-mode browsers and readers, among other things.

2 Responses

  1. drew February 24, 2008 / 11:59 pm

    Hey.

    I’ve checked out this post and also one here > http://www.obsceneart.com/?p=11

    I’m really interested in getting an extjs look at feel for webmin…is there a module for this that I can’t find, I’m not yet confident in making my own.

    Is there anything you can do to point me in the right direction?

    Cheers drew.

  2. Joe Cooper February 28, 2008 / 3:36 pm

    It’s not a minor undertaking…it’s still in development. Other projects just keep pushing it to the backburner…but it will be finished eventually.

Comments are closed.