Jason Huck's Devblog http://devblog.jasonhuck.com Web dev stuff that doesn't fit in a tweet. Tue, 24 Jan 2012 03:06:47 +0000 en hourly 1 http://wordpress.org/?v=3.3.1 My Name Is Jason, And It’s Been Three Years Since My Last Blog Post http://devblog.jasonhuck.com/2012/01/23/my-name-is-jason-and-its-been-three-years-since-my-last-blog-post/ http://devblog.jasonhuck.com/2012/01/23/my-name-is-jason-and-its-been-three-years-since-my-last-blog-post/#comments Tue, 24 Jan 2012 03:06:47 +0000 Jason http://devblog.jasonhuck.com/?p=52 I had just posted some updates to my company’s work-in-progress site, and was doing some routine maintenance on the server the other day, including updating a few WordPress blogs, when I realized just exactly how out of date my poor little dev blog had become. My previous post is just over three years old. Hmm, I thought, so is my daughter. But surely that’s just a coincidence…?

I’ve discovered, used, tweaked, and even created plenty of blog-worthy things in the last three years. What I haven’t done, obviously, is find the time to actually blog about them. And, despite the fact that I’m posting this now, I’m not making any promises that’s going to change. You see, as the informatively titled sidebar indicates, “Mostly, I Tweet.” And, according to someone on the internet that I’m far too lazy to Google, “anything worth saying can be said in 140 characters or less.” Probably true about 80% of the time. Let’s face it.

Of course, now that this blog is sporting a nice responsive theme, maybe I’ll start posting a few things here that I can’t quite squeeze into a tweet.

Maybe.

]]>
http://devblog.jasonhuck.com/2012/01/23/my-name-is-jason-and-its-been-three-years-since-my-last-blog-post/feed/ 0
Installing Lasso on CentOS 5 http://devblog.jasonhuck.com/2009/01/08/installing-lasso-on-centos-5/ http://devblog.jasonhuck.com/2009/01/08/installing-lasso-on-centos-5/#comments Thu, 08 Jan 2009 13:31:53 +0000 Jason http://devblog.jasonhuck.com/?p=37 Officially, Lasso Professional is only supported on one flavor and version of linux: Red Hat Enterprise Linux 4. However, many Lasso users have opted to forego RHEL4, which requires a commercial support subscription, for its community supported twin, CentOS 4, despite the fact that it isn’t officially supported by LassoSoft. Because CentOS 4 is based on the same core code and designed to be 100% binary compatible with RHEL4, installing Lasso on either distribution is essentially an identical process. Marc Pope has provided an excellent set of quick start instructions for installing Lasso on CentOS 4 at LassoTech.

Unfortunately, Lasso is not supported on newer versions of either distribution, even though RHEL5 was released in March of 2007, and CentOS 5 followed in the next month. Given the length of time the 5 series has been available, along with the significant number of bug fixes and enhancements it contains over the previous releases, many users would like to run Lasso on CentOS 5. This article describes the steps I took to get Lasso Professional 8.5.5 running on a clean install of CentOS 5.2, both the most current releases, respectively, at the time of this writing.

Please note that I am far from a linux guru. To the extent that I have tested this setup so far, I have not seen any errors and performance has been on par with what I would expect for the given hardware and conditions, but it has, by no means, been exhaustively tested. Use this unsupported setup in a production environment at your own risk. I welcome any feedback which can improve, correct, or add to the instructions below. Good luck!

  1. Install and update CentOS 5.2 as usual.

    The details of installing the base operating system are beyond the scope of this article. Suffice it to say, if you are not comfortable installing Linux on your own, you probably do not want to install Lasso on it either. These instructions were created against clean installs of version 5.2. If you have upgraded from an earlier version of CentOS, you may find that you do not need to install some of the compatibility packages that I needed.

  2. Become the Root User

    As usual, you’ll need root privileges for many of these operations, so it’s easiest to just become the root user for the duration, rather than prefixing every command with “sudo.”

    [prompt]# su root
    

    (enter the root password when prompted)

  3. Install the latest JRE from Sun.

    Download the latest Java Runtime Edition, or JRE, from java.sun.com and create a symlink to the i386 directory from within the “latest” directory, where Lasso looks for it. At the time of this writing, the latest version was 1.6.0 Update 11. You may wish to check for a newer version rather than using the link shown below.

    [prompt]# wget http://javadl.sun.com/webapps/download/AutoDL?BundleId=26213 -O jre-6u11-linux-i586-rpm.bin
    [prompt]# chmod +x jre-6u11-linux-i586-rpm.bin
    [prompt]# ./jre-6u11-linux-i586-rpm.bin
    

    (type “yes” to accept the license agreement)

    [prompt]# ln -s /usr/java/jre1.6.0_11/lib/i386/ /usr/java/latest/lib/i386
    
  4. Install Missing/Deprecated X11 Libraries

    Find and install xorg-x11-deprecated-libs-6.8.2-1.EL.33.i386.rpm. Afterwards, yum will show it as installed, but the Lasso RPM will still complain that a required package is missing. I used the deprecated package because the regular one overrides the mesa-based package that CentOS 5 uses by default, which causes problems with the windowing system and Gnome.

    [prompt]# wget ftp://mirror.switch.ch/pool/3/mirror/centos/4.7/os/x86_64/CentOS/RPMS/xorg-x11-deprecated-libs-6.8.2-1.EL.52.i386.rpm
    [prompt]# rpm -ivh xorg-x11-deprecated-libs-6.8.2-1.EL.33.i386.rpm
    

    Note: On an otherwise identical system with the KDE desktop installed, we were able to install just libXp (via yum), which is the specific package from the deprecated X11 libs that is missing in CentOS 5′s X11 install, instead of using the deprecated libs. Apparently this has been a common problem with the new version of X11.

  5. Install Older Version of OpenSSL

    CentOS has OpenSSL 098a, but Lasso requires 097a. I did not have to uninstall the newer version to include the older one.

    [prompt]# yum install openssl097a
    
  6. Install OpenLDAP Compatibility Layer

    Lasso requires libldap-2.2.so.7, which is in an OpenLDAP Compatibility package:

    [prompt]# yum install compat-openldap.i386
    
  7. Symlink /etc/localtime To Your Time Zone

    Lasso expects /etc/localtime to be a symlink to /usr/share/zoneinfo/[your zone], but it wasn’t, by default, on the machines I set up.

    [prompt]# mv /etc/localtime /etc/localtime_bak
    [prompt]# ln -s /usr/share/zoneinfo/EST /etc/localtime
    
  8. Install LassoService and Documentation

    Install the Lasso-Service and Lasso-Documentation RPM’s, but skip the Lasso Connector RPM since we need the 2.2 connector anyway. NOTE: Use –nodeps on the LassoService RPM to keep it from complaining about the xorg-x11-libs not being installed.

    [prompt]# wget http://download.lassosoft.com/pub/Lasso85/Lasso_Pro_8.5.5_Lin.tar.gz
    [prompt]# tar -zxvf Lasso*
    [prompt]# cd Lasso\ Pro\ 8.5.5\ for\ Red\ Hat\ Enterprise\ Linux\ 4/
    [prompt]# rpm -ivh --nodeps Lasso-Service*.rpm
    [prompt]# rpm -ivh Lasso-Documentation*.rpm
    
  9. Install Lasso Connector for Apache 2.2

    Copy the connector out of Lasso’s Extensions folder into Apache’s modules folder, copy the config file into Apache’s conf directory, modify the httpd.conf file to include it, and restart Apache.

    [prompt]# cd /usr/local/Lasso\ Professional\ 8/Extensions/Lasso\ Connector\ for\ Apache\ 2.2/
    [prompt]# cp lasso8.conf /etc/httpd/conf/lasso8.conf
    [prompt]# cp Lasso8ConnectorforApache2.2.so /etc/httpd/modules/Lasso8ConnectorforApache2.2.so
    [prompt]# cd /etc/httpd/conf
    [prompt]# vi httpd.conf
    

    Press “i” to enter insert mode, then add the following lines:

        # Include Lasso config.
        Include conf/lasso8.conf
    

    Press [esc] to enter command mode, then “:w” to write (save) the file, and “:q” to quit the vi editor. Next, start or restart apache:

    [prompt]# /etc/init.d/httpd start
    

    Or, if Apache is already running:

    [prompt]# /etc/init.d/httpd restart
    
  10. Add Unicode Properties Support to PCRE

    Lasso’s [string_findregexp] and [string_replaceregexp] rely on the PCRE regular expression library. However, the version included in CentOS is missing “Unicode properties support”, which prevents you from using regular expressions which include \L, \l, \N, \P, \p, \U, \u, or \X. In order to fix this, you must download the source RPM for the PCRE library, edit the compilation options in its SPEC file, and rebuild it so that when you (re)install the RPM, it will include the missing Unicode properties support. Once that’s done, you’ll need to create a set of symlinks from where Lasso expects to find these libraries to where they actually get installed on your system.

    Note: These instructions were written by Bil Corry as part of a discussion on Lasso Talk. To use them, you will need to have the “rpmbuild” tool and a compiler such as GCC installed on your system. If you did not choose to include these components when you installed CentOS, be sure to add them via yum before proceeding.

    [prompt]# mkdir /usr/src/redhat
    [prompt]# cd /usr/src/redhat
    [prompt]# wget http://mirrors.kernel.org/centos/5.2/os/SRPMS/pcre-6.6-2.el5_1.7.src.rpm
    [prompt]# rpm -ivh pcre-6.6-2.el5_1.7.src.rpm
    [prompt]# cd /usr/src/redhat/SPECS/
    [prompt]# vi pcre.spec
    

    Press “i” to enter insert mode, find the “%configure” line and add the option for Unicode property support, so it looks like this:

    %configure --enable-utf8 --enable-unicode-properties
    

    Press [esc] to enter command mode, then “:w” to write (save) the file, and “:q” to quit the vi editor. Next, rebuild the RPM with the new configuration option in place and install it:

    [prompt]# rpmbuild -bb pcre.spec
    [prompt]# cd /usr/src/redhat/RPMS/i386/
    [prompt]# rpm -Uhv pcre*.rpm
    

    Finally, replace the PCRE libraries in /usr/local/lib with symlinks to the versions in /usr/lib:

    [prompt]# mkdir /usr/local/lib/pcre-old
    [prompt]# mv /usr/local/lib/libpcre*.* /usr/local/lib/pcre-old
    [prompt]# ln -s /usr/lib/libpcre.a /usr/local/lib/libpcre.a
    [prompt]# ln -s /usr/lib/libpcre.so /usr/local/lib/libpcre.so
    [prompt]# ln -s /usr/lib/libpcre.so.0 /usr/local/lib/libpcre.so.0
    [prompt]# ln -s /usr/lib/libpcrecpp.a /usr/local/lib/libpcrecpp.a
    [prompt]# ln -s /usr/lib/libpcrecpp.so /usr/local/lib/libpcrecpp.so
    [prompt]# ln -s /usr/lib/libpcrecpp.so.0 /usr/local/lib/libpcrecpp.so.0
    [prompt]# ln -s /usr/lib/libpcreposix.a /usr/local/lib/libpcreposix.a
    [prompt]# ln -s /usr/lib/libpcreposix.so /usr/local/lib/libpcreposix.so
    [prompt]# ln -s /usr/lib/libpcreposix.so.0 /usr/local/lib/libpcreposix.so.0
    
  11. Start Lasso

    In our testing, Lasso ran fine when started using any of the provided startup scripts, but it did not have sufficient permissions when started from Gnome’s Services control panel, resulting in ISE’s.

    [prompt]# cd /usr/local/Lasso\ Professional\ 8/Tools/
    [prompt]# sh ./startLassoService.sh
    

    Note: The problem starting from the Services control panel is apparently due to the fact that Lasso wants to run a process as root in order to spawn other processes under the lasso user. In CentOS 5.2, by default, only console users can do this (hence the need to use the startup scripts). A potential workaround is to comment out this line in /etc/sudoers, though there are likely security implications in doing so:

    Defaults requiretty
    

Other Notes

  • This should be run against a test suite to determine if there are any other dependencies that may still be causing problems.
  • In one test install, we saw a “file not found” error looking for “startup.LassoApp” vs. “Startup.LassoApp”, but doing a case-sensitive search on the source of the admin LassoApps didn’t produce any results, so I’m not sure where it’s coming from. On that machine, I made a copy of “Startup.LassoApp” with a lowercase “s.” I don’t know if having two otherwise identical startup scripts in place will cause any problems or not.
  • It was brought to my attention that the lasso user’s shell is set to /dev/null, but that the standard for service accounts on CentOS is /sbin/nologin. It shouldn’t make any difference, but the perfectionists among you may wish to make that change.
  • You may wish to add /usr/sbin to your user’s path, which gives you access to several handy shortcuts such as “apachectl” and “lasso8ctl”, among others, and also add your user to the /etc/sudoers file as an administrator. These two things will provide a more Mac-like experience without requiring you to log in as the root user.
  • Depending on what choices you made when installing CentOS, some packages required by Lasso that were present in my installs may be missing from yours. If you follow these instructions and Lasso does not start up properly, try starting it in console mode (cd to the Tools directory and sh ./consoleLassoService.sh) and watch for error messages about missing files. One person reported that they had to install libxslt (yum install libxslt) in order to get Lasso running, whereas our test machines already had this package installed.

So, that’s it! Hopefully not too scary. If you try this, let me know how it goes. Once again, any suggestions for how to improve these instructions is welcome.

]]>
http://devblog.jasonhuck.com/2009/01/08/installing-lasso-on-centos-5/feed/ 33
An Asset Management System for Lasso Powered Sites http://devblog.jasonhuck.com/2008/09/23/an-asset-management-system-for-lasso-powered-sites/ http://devblog.jasonhuck.com/2008/09/23/an-asset-management-system-for-lasso-powered-sites/#comments Wed, 24 Sep 2008 01:45:42 +0000 Jason http://devblog.jasonhuck.com/?p=18 At the 2008 Lasso Developer Conference in Chicago, I presented a paper entitled Server Side Techniques for Client Side Optimization, in which I reviewed the original 13 Rules For Making Web Sites Fast from Yahoo!’s Exceptional Performance Team. These rules quickly became the seminal document on the topic of client side optimization and have since been expanded to include (at the time of this writing) 37 rules across 7 categories. They also became the basis for the performance tests used by the YSlow add-on for Firebug, which is a great tool for evaluating the performance of your site.

The second half of my presentation described an asset management system for Lasso which manages the JavaScript and CSS files used throughout the site, automating many of the aforementioned best practices by handling the concatenation, minification (via YUI Compressor), compression, caching, and integration of JavaScript and CSS files. The system is designed to be adaptable to any Lasso framework or codebase without substantially impacting existing workflows, and can easily be partially or completely disabled for debugging purposes.

Even though some of the convenience features of the system are relatively fresh code, and suffer from at least one minor bug (discovered while helping Tami Williams integrate the system into the LassoFuseBox framework), the core components of this system have now been deployed several times over in production sites and work beautifully together. The following graph displays the average savings in response time, bytes transferred, and total number of requests from one of my code samples:

Video of my presentation (as well as the others) should be available in the near future. In the meantime, now that the conference is over, I am making my paper, code samples, and slides available for download:

Documentation for the individual tags that make up the system is available at tagSwap.net. Be sure to check there for any future updates and/or bug fixes.

The slides can be viewed (and downloaded) via SlideShare:

]]>
http://devblog.jasonhuck.com/2008/09/23/an-asset-management-system-for-lasso-powered-sites/feed/ 0
Will Google Chrome shake up the browser market? http://devblog.jasonhuck.com/2008/09/02/will-google-chrome-shake-up-the-browser-market/ http://devblog.jasonhuck.com/2008/09/02/will-google-chrome-shake-up-the-browser-market/#comments Wed, 03 Sep 2008 03:09:41 +0000 Jason http://devblog.jasonhuck.com/?p=15 Practically out of nowhere yesterday, it was leaked that Google was working on their very own web browser called “Chrome”, and already today a beta is available for Windows, with Mac and (hopefully) Linux versions to follow. I won’t go into the details of Google’s motivations for developing Chrome, or the specific ways in which it differs from other browsers. If you’re looking for that information, by far the most entertaining way to get it is to read the comic that introduced it. Suffice to say, at first glance it appears to be a very solid, forward-thinking effort, innovative moreso in its underlying engineering than any particular UI enhancement.

But, what sort of impact will this shiny new browser have on the market? That’s an interesting question. This release is generating a lot of buzz largely because it comes from Google. The average surfer probably doesn’t realize that new web browsers are released on a fairly regular basis, with little to no fanfare. Web browsers are everywhere you look. They’re embedded in mobile devices and gaming consoles. They power help systems for desktop applications. They might be clones of existing browsers built on the same core rendering engines, or completely unique from the ground up. They might be general purpose browsers or targeted at specific niche markets like social networking. In one form or another, new browsers appear almost every month, but usually, no one notices.

Now along comes Google Chrome, and suddenly people are paying attention. With Google’s name behind it, and given the ubiquity of Google Apps — for which Chrome seems tailor made — it stands a good chance of gaining enough market share to put it on the map alongside “the big four”: Internet Explorer, Firefox, Safari, and Opera. If that happens, Yahoo! will no doubt extend A-Grade browser support for it, and developers around the globe will add it to their QA routines. It certainly could be worse. With Webkit’s Web Inspector and Google’s own Process Manager built-in, it’s not lacking for development tools. In fact, right now, it’s far more appealing to developers, power users, and other early adopters than to the average end user. If you’re not the kind of person who routinely keeps at least a dozen tabs open in your browser, half of them running actual web applications vs. simpler, static sites, most of the (nonetheless impressive) architectural benefits of Chrome will be completely lost on you.

So, the initial switchers are probably going to be the same group of people who are already using a browser that didn’t ship with their OS. Explorer users will continue to click on the blue “e” to get to the internet, whether out of blind ignorance, fear of change, lack of motivation, or worse, because their IT department won’t allow them to use anything else. In the meantime, Firefox, Safari, and Opera will be forced to take the hits.

Safari, being the default browser on OS X, will weather well on the Mac, though Chrome likely won’t help its acceptance on Windows, and Firefox, currently the most popular “alternative” browser, has an extensive, mature plugin library that engenders loyalty. Hardest hit may be Opera, a fast, powerful, but underappreciated innovator that’s consistently a distant fourth, and didn’t even rate a cursory nod in the Chrome comic, despite the fact that Opera already had its tabs on top (a feature touted by Chrome), and Chrome’s start page is obviously copied directly from Opera’s “Speed Dial” feature.

On the other hand, Chrome is yet another victory for WebKit, the latest in a string of products to incorporate the HTML rendering engine behind Safari. In addition to Safari on Mac, Windows, and iPhone, WebKit powers the Adobe AIR runtime, as well as the browser in Android, Google’s upcoming mobile platform. It seems WebKit is becoming the de facto rendering engine of choice, not a bad thing given its speed and strong standards support. And since Chrome supports Google Gears (how could it not?), we’ll likely see Gears available for other WebKit browsers in the near future, providing support for the major browsers (except Opera) on every platform.

So far, reaction from the developer community, including other browser vendors, has been positive, but whether Chrome attains popularity with end users or becomes primarily a reference/specialty platform for developers remains to be seen.

]]>
http://devblog.jasonhuck.com/2008/09/02/will-google-chrome-shake-up-the-browser-market/feed/ 3
Lasso Developer Conference 2008 http://devblog.jasonhuck.com/2008/07/02/lasso-developer-conference-2008/ http://devblog.jasonhuck.com/2008/07/02/lasso-developer-conference-2008/#comments Wed, 02 Jul 2008 22:44:10 +0000 Jason http://devblog.jasonhuck.com/2008/07/02/lasso-developer-conference-2008/ Over the past few weeks, I’ve been preparing for this year’s Lasso Developer Conference in Chicago. It’s my second time speaking at the event, and although it’s not until September, a written paper and demo materials which will accompany the presentation were due July 1st are due July 14th (thanks to LassoSoft for the gracious extension). I’m really looking forward to the event. It’s truly a great chance to meet and interact with members of the Lasso community as well as the LassoSoft team.

The title of my talk is “Server Side Techniques for Client Side Optimization”, and it explores ways to streamline the delivery of modern web apps by reducing HTTP requests, combining, minifying, and compressing assets with tools such as the YUI Compressor, using asset subdomains, and more, all wrapped up in a self-contained system that won’t force you to change your existing workflow. And, although I agree somewhat with criticisms that it’s “teaching to the test”, it’ll also help you score an A(100) in YSlow. :P

]]>
http://devblog.jasonhuck.com/2008/07/02/lasso-developer-conference-2008/feed/ 0
Expanded Google Analytics Plugin http://devblog.jasonhuck.com/2008/07/02/expanded-google-analytics-plugin/ http://devblog.jasonhuck.com/2008/07/02/expanded-google-analytics-plugin/#comments Wed, 02 Jul 2008 22:15:33 +0000 Jason http://devblog.jasonhuck.com/2008/07/02/expanded-google-analytics-plugin/ Despite numerous requests, I have either been too busy or too lazy, or both, to update my gaTracker plugin to support the new ga.js script from Google Analytics. Hence, I am very interested in trying out dvdsmpsn’s jGoogleAnalytics plugin, which not only converts my original plugin to work with ga.js, but also adds a slew of additional features for more fine-grained control over the tracking. It appears to be a pretty solid effort, and does pretty much everything I had planned to do with mine. I’ll report back once I’ve had a chance to put it through its paces.

]]>
http://devblog.jasonhuck.com/2008/07/02/expanded-google-analytics-plugin/feed/ 0
jQuery File Tree http://devblog.jasonhuck.com/2008/07/02/jquery-file-tree/ http://devblog.jasonhuck.com/2008/07/02/jquery-file-tree/#comments Wed, 02 Jul 2008 21:59:53 +0000 Jason http://devblog.jasonhuck.com/2008/07/02/jquery-file-tree/ Cory S.N. LaViska over at A Beautiful Site has created a very nice jQuery plugin for displaying file trees called, naturally, jQuery File Tree. The great thing about it is its simplicity. It doesn’t have an overabundance of bells and whistles, but it’s super easy to integrate with a simple API (it even includes Lasso support), has plenty of hooks to add your own custom functionality, and generates nice clean markup. Check it out!

]]>
http://devblog.jasonhuck.com/2008/07/02/jquery-file-tree/feed/ 1
jQuery Combo Select Redux http://devblog.jasonhuck.com/2008/04/25/jquery-combo-select-redux/ http://devblog.jasonhuck.com/2008/04/25/jquery-combo-select-redux/#comments Sat, 26 Apr 2008 03:47:49 +0000 Jason http://devblog.jasonhuck.com/2008/04/25/jquery-combo-select-redux/ As a followup to my previous post on creating comboselect boxes in jQuery, I have automated the process of transforming a normal multiselect input element into a comboselect with the (aptly named) comboselect plugin.

With the plugin, you start with a normal select input, and transform it using a few simple options. You can decide which sides get resorted after a change (none, left, right, or both), and also specify the labels for the buttons which control movement from left to right and vice versa. You can also move items from side to side by double clicking them. The default sort option is “both”, and the default button labels are “>” and “<”. The plugin passes the list of selected items back to the original form input, so the form submission works the same regardless of whether the plugin is used.

Sample usage is as simple as:

$('#somelist').comboselect();

Or, with options:

$('#somelist').comboselect({
	sort: 'right',
	addbtn: ' Add ',
	rembtn: ' Remove '
});

To see the plugin in action, check out this simple demo page:
http://devblog.jasonhuck.com/assets/comboselect_plugin/

You can download the comboselect plugin here:
http://plugins.jquery.com/project/comboselect

The download contains the source of the demo, including a sample CSS file and the Selso plugin, which is required for sorting.

]]>
http://devblog.jasonhuck.com/2008/04/25/jquery-combo-select-redux/feed/ 38
Using Namespaces To Load Lasso Tags Into Memory http://devblog.jasonhuck.com/2008/04/10/using-namespaces-to-load-lasso-tags-into-memory/ http://devblog.jasonhuck.com/2008/04/10/using-namespaces-to-load-lasso-tags-into-memory/#comments Thu, 10 Apr 2008 04:07:46 +0000 Jason http://devblog.jasonhuck.com/2008/04/10/using-namespaces-to-load-lasso-tags-into-memory/ This article describes different ways to load custom tags into memory in Lasso, and presents an alternative method of managing tag libraries.

LassoStartup and LassoLibraries

Lasso provides a number of different ways to make custom tags (and types) available for use in your scripts. Tag definitions can be pasted directly into scripts, or included from external files. Alternatively, tag files can be placed in one of two special folders within the Lasso application folder, LassoStartup and LassoLibraries, for automatic loading.

Placing tags within these special folders provides two distinct advantages. First, Lasso handles the loading of the tags for you, so it’s not necessary to manually include any extra files or code in your scripts; the tags are simply always available for use. If placed in LassoStartup, they’re loaded as part of the initialization process when the Lasso Service starts. If placed in LassoLibraries (and arranged in a certain way), they’re loaded on-demand, the first time they are used in a script.

Secondly, once loaded, tags placed in these special folders remain resident in memory until the Lasso Service is restarted. This eliminates the overhead of reading a file from disk, parsing the tag definition, constructing an internal prototype, and adding it to the tag registry, a process that must otherwise be repeated for each tag every time a script which uses that tag runs. For a single tag, all of those actions happen in a few milliseconds, but with larger libraries, those milliseconds can add up to noticeable delays.

Despite the advantages, it’s not always convenient or even possible to place tags in these special folders. For instance, if your project is hosted in a shared hosting environment, you may not have access to the Lasso application folder. If you use a version control system such as Subversion, you’d have to maintain separate working copies in order to keep two directories in different locations in sync. Although LassoLibraries provides a mechanism for unloading tags programmatically, reloading custom tags defined in LassoStartup requires a restart of the Lasso Site and/or the entire Lasso Service. Generally speaking, it’s just more convenient to be able to keep all the files related to a single project within a single folder.

Pushing Tags Into The Global Namespace

The ideal setup, then, is one where the developer can both specify the location of tag libraries, and have them loaded into memory. Fortunately, the same mechanism that allows files in LassoLibraries to be loaded into memory on-demand can be used on other paths as well.

You may have noticed that Lasso’s tag names use a categorization system to organize sets of tags into groups. For example, the tags which deal with string manipulation are all prefixed by string_. These groups are called namespaces (namespaces in general | namespaces in Lasso) and they have a number of interesting uses. What’s important to understand in this context, however, is that Lasso’s namespaces are hierarchical, and all descend from a top-level namespace known as the global namespace. Tags defined within the global namespace remain resident in memory, and thanks to the [namespace_using] tag, we can push tag definitions into the global namespace programmatically.

For example, once the following code snippet runs, the [foo] tag will be available for use on any page until Lasso is restarted. Without the namespace tags, [foo] will only exist on the page in which it was defined.

[
	namespace_using(namespace_global);
		define_tag('foo');
			return('bar');
		/define_tag;
	/namespace_using;
]

A Flexible Loader For Managing Tag Libraries

The [tags_load] custom tag uses this technique to “watch” the given folder and make sure all the tags within it are loaded into memory. Basic usage is simply:

[tags_load('/path/to/mytags/')]

Optionally, you can specify what type of files to load by extension (the default is .inc), and a condition for whether or not to refresh all tags:

[
	tags_load(
		'/path/to/mytags/',
		-ext='.lasso',
		-refresh=(var_defined('reloadmytags') && $reloadmytags === true)
	);
]

When the tag loader is called, it will list every file in the given path which matches the given extension. It does not currently recurse into subdirectories, and will ignore files that begin with a period.

It will then iterate through that list, checking to see if a tag by that name already exists. For instance, if the file is “foo_bar.inc”, it will check for a tag called [foo_bar]. If none is found (or the refresh condition has been met), it will include the file using the [library] tag within a [protect] block. Any errors that occur when loading an individual file will be trapped and logged to Lasso’s built-in error database, and the tag loader will move on to the next file. Log entries made by the tag loader are prefixed with “[Tagloader]” like so:

[Tagloader] Error loading [foo_bar]: No permission.

The total number of successfully loaded tags for each path is stored in a global variable. On subsequent calls for that path, if the number of files to load matches the number of tags already loaded (and the refresh condition is not met), the rest of the routine is skipped. Thus, even if the tag loader is called on every page load, it’s usually only doing work if a new tag is added to the path, or a refresh is requested. When it’s finished, the results are logged to the error database:

[Tagloader] 113 of 115 tags loaded successfully.

In its current incarnation, it’s important that each file loaded with the tag loader contain a tag with the same name as the file. Otherwise, that file will be reloaded every time, regardless of whether it’s necessary. So, for instance, if you have all of the tags in the foo_ namespace in a single file called foo_library.inc, you’ll want to include a placeholder tag to register the library with the tag loader. I typically just define a simple tag which returns “Loaded” and place it at the end of the file (so that it only loads if there are no other errors):

[
	define_tag('foo_bar');
		...
	/define_tag;

	...

	define_tag('foo_library');
		return('Loaded');
	/define_tag;
]

The tag loader could be extended with more options for greater flexibility, but the current feature set has met my needs well for quite some time. Some ideas include:

  • Optionally accepting an array instead of a string for the path, so that multiple locations can be loaded via a single tag call.
  • Recursing subdirectories so that tags can be broken down into nested folders.
  • Replacing the -ext param with -match and/or -deny params which would accept arrays of conditions to match against filenames.
  • An additional -usenamespace param which could override or append to the default global namespace.

Hopefully a future version of Lasso will support custom paths to LassoLibraries and/or other methods of moving things in and out of memory. The namespace library which ships with Lasso is, itself, written in LassoScript, and could easily be modified to support custom paths. However, that would require maintaining a custom-compiled version of Startup.LassoApp everywhere you want to deploy your code — not a very portable solution. In the meantime, I think this is a satisfactory workaround.

[tags_load] can be downloaded at tagSwap.net

]]>
http://devblog.jasonhuck.com/2008/04/10/using-namespaces-to-load-lasso-tags-into-memory/feed/ 1
Combo Select Boxes In jQuery http://devblog.jasonhuck.com/2008/03/08/combo-select-boxes-in-jquery/ http://devblog.jasonhuck.com/2008/03/08/combo-select-boxes-in-jquery/#comments Sat, 08 Mar 2008 15:03:55 +0000 Jason http://devblog.jasonhuck.com/2008/03/08/combo-select-boxes-in-jquery/ Although the standard <select> input for HTML forms supports a “multiple” attribute which allows users to select multiple options by control- or command- clicking, it’s easily one of the most confusing concepts for users to grasp. It’s also fairly clumsy, especially when the list of options is long. It’s difficult for users to see which options they have already selected, and if their previous selections scroll out of site, they get nervous that those choices will be lost when they make additional selections.

A more friendly and intuitive solution is to allow the user to create a new list of selected items by moving them from the original list into the new list. This keeps their (usually much smaller) list of selected items in constant view, and removes those items from the original list, making it shorter and easier to scan for any additional items they might wish to add.

I’ve been using these “combo select boxes” for many years, but a recent project provided me with the opportunity to recreate them with better markup, and using jQuery to control the behavior.

The Markup

I wanted to keep the markup as light and simple as possible, so I stuck with basic form elements. Classes are used as the “hooks” for the javascript so that you can manage multiple lists in a single page.

  • There are two <select> inputs, classed “left” and “right” — users will move items from the left (original) list to the right (new) list.
  • There are two <input> elements of type “button”, classed “add” and “remove”, to control the movement of items between the lists.
  • The buttons are wrapped in a <fieldset> so that they can be positioned as a group via CSS.
  • The grouped buttons and the two lists are wrapped in an additional <fieldset>, with an associated <label> element, so that the entire control can be treated as a single element when integrated with the rest of your form.
  • The one slightly unusual bit of markup here is the addition of an ID on each <option> element. This helps us keep the lists sorted as items are moved between them (explained below).
<label for="letters">Letters</label>
<fieldset id="letters">
	<select id="lettersleft" name="lettersleft" class="left" multiple="multiple">
		<option id="opt1" value="1">AAA</option>
		<option id="opt2" value="2">BBB</option>
		<option id="opt3" value="3">CCC</option>
		<option id="opt4" value="4">DDD</option>
		<option id="opt5" value="5">EEE</option>
		...etc...
		<option id="opt26" value="26">ZZZ</option>
	</select>
	<fieldset>
		<input type="button" class="add" value=" > " />
		<input type="button" class="remove" value=" < " />
	</fieldset>
	<select id="lettersright" name="lettersright" class="right" multiple="multiple">
	</select>
</fieldset>

Adding Behavior

jQuery’s built-in DOM manipulation methods made short work of the basic functionality. I used .parent() to traverse back up the tree to the master <fieldset>, and .find() to target the left and right lists respectively. Moving <option> elements between the two lists is a snap with .append():

$('input.add').click(function(){
	var left = $(this).parent().parent().find('select.left option:selected');
	var right = $(this).parent().parent().find('select.right');
	right.append(left);
	sortBoxes();
});

$('input.remove').click(function(){
	var left = $(this).parent().parent().find('select.left');
	var right = $(this).parent().parent().find('select.right option:selected');
	left.append(right);
	sortBoxes();
});

You’ll notice the call to a sortBoxes() function. The usability of this type of control is greatly enhanced if the lists are sorted as each change is made. For that, I used Guillaume Andrieu’s Selso plugin <http://plugins.jquery.com/project/selso>. A cool feature of this plugin is that it can simultaneously sort multiple lists with the given criteria, since it sorts individual elements within their respective parents. So, all I had to do is select all of the <option> elements from the left and right lists, and tell the plugin how I wanted them sorted. I also deselected any selected elements:

function sortBoxes(){
	$('select.left, select.right').find('option').selso({
		type: 'alpha',
		extract: function(o){ return $(o).text(); }
	});

	// clear all highlighted items
	$('select.left, select.right').find('option:selected').removeAttr('selected');
}

And that’s it! As usual with jQuery, not a lot of custom code required. I considered wrapping this up into a plugin, but I think I’ll wait until I’ve used it in a few more places to see what options would be the most useful. You can try out a demo here: <http://devblog.jasonhuck.com/assets/comboselect/>.

]]>
http://devblog.jasonhuck.com/2008/03/08/combo-select-boxes-in-jquery/feed/ 17