<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Modest Construct &#187; work</title>
	<atom:link href="http://heliologue.com/tag/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://heliologue.com</link>
	<description>Let joy be unconfined. Let there be dancing in the streets, drinking in the saloons, and necking in the parlor.</description>
	<lastBuildDate>Sun, 29 Apr 2012 15:33:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The City of Brotherly Love</title>
		<link>http://heliologue.com/2009/03/22/the-city-of-brotherly-love/</link>
		<comments>http://heliologue.com/2009/03/22/the-city-of-brotherly-love/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 04:52:17 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://heliologue.com/?p=3702</guid>
		<description><![CDATA[I find myself in downtown Philadelphia, staring at the window of the Cathedral-Basilica of Sts. Peter &#38; Paul. I am a long way from my hometown, a smallish suburb of Chicago, feeling at odds with Philadelphia&#8217;s large stature—the sixth most populous city in the entire United States—and my own touristy insignificance. I took a picture [...]]]></description>
			<content:encoded><![CDATA[<p>I find myself in downtown Philadelphia, staring at the window of the <a href="http://en.wikipedia.org/wiki/Cathedral-Basilica_of_SS._Peter_&#038;_Paul">Cathedral-Basilica of Sts. Peter &amp; Paul</a>.  I am a long way from my hometown, a smallish suburb of Chicago, feeling at odds with Philadelphia&#8217;s large stature—the sixth most populous city in the entire United States—and my own touristy insignificance.</p>
<p>I took a picture of the Liberty Bell earlier, but it was a mere formality:  the bell, in real life, was smaller, duller, and much less impressive than I realized.  Congress Hall, too, was neat but tidily boring.  I thought of the Nick Cage vehicle filmed in next-door Independence Hall and can&#8217;t help but think it&#8217;s all been trivialized to the point where it&#8217;s impossible to care.  </p>
<p><span id="more-3702"></span></p>
<h3>History, for a block</h3>
<p>I&#8217;m here for Sungard HE&#8217;s annual <a href="http://sungardsummit.com/">Summit</a>, an international get-together for users of Sungard&#8217;s ERP system, Banner.  Last year, I <a href="http://heliologue.com/2008/04/13/anaheim-and-other-larks/">blogged from Anaheim</a>, and there were about 8,000 attendees;  this year, there&#8217;s perhaps 5,500, a significant decrease.  One could argue that it&#8217;s due to restricted travel budgets from the current economic crisis;  I, cynically, will point out that nobody gives a shit about the Liberty Bell compared to, say, Disneyland.  </p>
<p>If you ask me, of course, Disneyland is a blight upon the pristine Californian landscape, but I <em>hope</em> we can all agree on the historical import of Philadelphia.  It did, for instance, house the entire federal government for 10 years (1790-1800);  it was the <em>most</em> populous city in the nation at that time, which didn&#8217;t help when Yellow Fever killed a third of its inhabitants.  Though one of several critical locations in the history of the country, however, Philadelphia takes a decidedly low-key approach to publicizing it.</p>
<p>When I went to Springfield in the fall of &#8217;08, I couldn&#8217;t throw a rock without hitting a brown landmark sign;  half the city&#8217;s restaurants or tourist attractions invoke Lincoln or the government.  In other words, the city really milked the Springfield/Lincoln connection for all it was worth;  Philadelphia, on the other hand, while it doesn&#8217;t fail to mention its historicity, cordons off the Liberty Bell and Congress/Independence Halls appropriately, but has them sitting in the middle of urban sprawl.  <span class="pullquote">One moment, I&#8217;m passing the 6th pawn shop in as many blocks on the Market St.; the next, I&#8217;m suddenly standing before a 200+ year old brick edifice that housed some of the greatest political thinkers in history</span>.  Disinterested guards (with pistols!) watch the exits.  Within line-of-sight, a homeless man curls against an office building, wrapped in a flowery blanket, sleeping despite the chilly breeze and the 2-o&#8217;clock sunlight. </p>
<p>I did see the Liberty Bell in person, but somehow it failed to move me:  the build-up included a long hallway full of tasteful displays which illustrated the Bell&#8217;s historical and political importance.  Then it was there, at the end of the hall, cordoned off with a metal bar.  It was smaller than I thought, its inscription blurry from the distance and the flash of cameras.  Somehow, it was larger (literally and metaphorically) in my mind than it seemed to be in person.</p>
<h3>OK, but brotherly love?</h3>
<p>Perhaps I&#8217;m just conflicted.  I came here for the Banner conference, and can&#8217;t help but feel melancholy when I think that, had he not died, my father might well be here.  In an alternate history, I could have just come back from sharing a beer with him at the Irish pub, shooting the shit about degree audits or portal design.  He and I would have had the sort of casual male relationships that fathers are eventually supposed to have with their sons, fraternal and yet deeply symbolic.</p>
<p>But my dad and I never had too many heart-to-hearts;  he was never the maudlin type, and he preferred treating his sons like friends and colleagues rather than children (once we were old enough, of course).  I know that he was—to my occasional embarrassment—a reader of this blog.  But he only ever left <em>one</em> comment&#8230; last year, when I blogged about the <a href="http://heliologue.com/2008/04/13/anaheim-and-other-larks/#comment-155529">2008 Summit</a>.  So, I suppose, my attendance this year is a constant reminder of what <em>should have been</em> in a just world.  Dad was the figurative strawberry field, and Disney bulldozed him to erect its latest ride. I&#8217;ll never know why he elected to comment upon <em>that</em> entry and none other.  I could posit that he was feeling alienated in his new job, in need of communication with his son(s).  I could argue that he circumstantially felt compelled to comment upon the strength of my writing (sure!) and perhaps some emotional resonance (slightly more plausible).  His single solitary comment has remained immortalized to me as a reminder of something innately human and youthful about my dad&#8230; that he—against perhaps all my expectations—showed up in a medium totally foreign to him, in order to communicate with me.  That he may have felt too embarrassed to talk this way with me in real life is no surprise—ask me sometime about my &#8220;birds &amp; bees&#8221; talk—but it still remains a focal point in my memory of him.</p>
<p>Philadelphia,  in many ways like my father, seems determined to conflict and confuse me.  Its downtown area is a nice grid—except in the part where I&#8217;m staying and traveling, which devolves into curves and circles.  Though I arrived yesterday (Saturday, March 21st), I have yet to do anything in Summit-related as of today (Sunday, March 22):  the only sessions today were of the useless &#8220;Banner! Whoo!&#8221; variety, which I swore after last year I would no longer attend.  Tomorrow starts the meat and potatoes of the conference, 2.5 days of solid sessions, though those sessions&#8217; usefulness has yet to be determined.</p>
<p>I spent today sightseeing.  I ate lunch at the Down Home Diner, a small greasy spoon in the Reading Terminal Market (a strange name for an indoor marketplace, selling just about everything).  I had a bacon cheeseburger with bacon slices that were—I kid you not— a quarter of an inch thick.  I was so positively ecstatic about pork as a result that I made an impulse purchase of an &#8220;I &hearts; Bacon&#8221; t-shirt;  a cheese-steak is pending, since I don&#8217;t think that TSA employees let you fly out unless you can prove you&#8217;ve eaten one.</p>
<p>Just like last year, I&#8217;ve gotten excessively introspective and maudlin.  New places will do that to me, especially places that make me walk around with my eyes upward and my mouth slightly agape.  Philadelphia, for all its (very obvious) faults, is an incomprehensible city, confusing as it is large.  Its apparent insouciance toward its own history serves only to beleaguer the enthusiastic tourist, who is earnest until five beers in (then belligerent or solemn, depending on the tourist).</p>
<p>The conference, too, seems to some degree insouciant, as though it is merely going through the motions this year.  From 8&#8217;000 attendees (Anaheim + Disneyland) to 5&#8217;500 (Philadelphia and mid-40&deg;s), the scale of the conference has dropped proportionally.  Such is the danger of a conference whose appeal is not predicated upon the appeal of the system so much as the whim of its functional users.</p>
]]></content:encoded>
			<wfw:commentRss>http://heliologue.com/2009/03/22/the-city-of-brotherly-love/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using YUI compressor in a web project</title>
		<link>http://heliologue.com/2008/09/22/using-yui-compressor-in-a-web-project/</link>
		<comments>http://heliologue.com/2008/09/22/using-yui-compressor-in-a-web-project/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 23:35:42 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://heliologue.com/?p=2692</guid>
		<description><![CDATA[Last year, I moved our small programming department from using JDeveloper and editing shared files directly on a network drive to using Netbeans 6.x and a proper version control system (Subversion). After the initial learning curve, this has all been going swimmingly. I merged my first development branch into the trunk yesterday, and this branch [...]]]></description>
			<content:encoded><![CDATA[<p>Last year, I moved our small programming department from using JDeveloper and editing shared files directly on a network drive to using Netbeans 6.x and a proper version control system (Subversion).</p>
<p>After the initial learning curve, this has all been going swimmingly.  I merged my first development branch into the trunk yesterday, and this branch just so happens to dovetail nicely into the whole point of this post, which is the <a href="http://developer.yahoo.com/yui/compressor/">YUI compressor</a>, an open-source javascript and CSS minification tool developed by Yahoo&#8217;s <abbr title="Yahoo User Interface">YUI</abbr> team.</p>
<p><span id="more-2692"></span></p>
<h3>The Problem</h3>
<p>To understand quickly why one should minify production client-side code, consider only that with the upward trend of size in javascript libraries (and the necessary files for such libraries), it&#8217;s possibly to be downloading a <em>lot</em> of client-side code in a typical web application, especially as its scope grows.</p>
<p>For a long time, I was using <a href="http://dean.edwards.name/packer/">Dean Edward&#8217;s Packer</a>, as was everyone, because its Base62 encoding produced the very lowest file size.  However, what should have been obvious to everyone is that <code>eval(bunch_of_stuff_goes_here)</code> is making the browser do a lot more work, and this is a problem on dinosaurs like IE6.  </p>
<p>To make matters worse, the nature of such encoding also meant that for servers which tried to compress outgoing content like javascript (either with zlib or gzip), the compression ratio suffered.  Just look at this table that Julien Lecomte posted last August.</p>
<table class="sortable rowstyle-even">
<caption>Javascript compression</caption>
<thead>
<tr>
<th class="sortable-text">File</th>
<th class="sortable-numeric">File size (bytes)</th>
<th class="sortable-numeric">Gzipped file size (bytes)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Original jQuery libraries</td>
<td>62,885</td>
<td>19,758</td>
</tr>
<tr>
<td>jQuery minified with <a href="http://www.crockford.com/javascript/jsmin.html">JSMin</a></td>
<td>36,391</td>
<td>11,541</td>
</tr>
<tr>
<td>jQuery minified with Packer</td>
<td>21,557</td>
<td>11,119</td>
</tr>
<tr>
<td>jQuery minified with the YUI compressor</td>
<td>31,822</td>
<td>10,818</td>
</tr>
</tbody>
</table>
<p>I said to myself, &#8220;Hey, we use a lot of this stuff, and we still support a lot of users with slow computers and slow browsers.&#8221;  So, I moved our project from a Packer-based compression to a YUI-based compression, and turned on server-side GZIP compression for javascript files.  The only problem was that I was storing the javascript files already minified, and simply pasted them into a large a couple of large global <code>.js</code> files.  I had to keep a separate source directory, along with any customizations.</p>
<p>This got to be a pain in the ass, as you might well expect, and so when it occurred to me that I might be able to use the YUI library at build-time in our Netbeans project, I immediately sprung into action.</p>
<p>This was around April, and one night while attending <a href="http://heliologue.com/2008/04/13/anaheim-and-other-larks/">Sungard Summit</a> in Anaheim.  I did the initial work to get our Netbeans project into a state that could use the YUI compressor at build-time, creating separate source file directories and breaking our massive javascript file into modules;  I did the same with our CSS, splitting it up based on what it decorated.</p>
<p>There are a few tutorials about using the YUI library.  <a href="http://blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task/">Some of them</a> involve adding the YUI library to Ant&#8217;s classpath (didn&#8217;t want to go down this route); <a href="http://www.henke.ws/machblog/index.cfm?event=showEntry&#038;entryId=8A5CAB53-19B9-BA51-EECADB57919F9714">a lot of them</a> involve invoking the library as an external executable during the build process, which is messy.</p>
<p>The solution I finally settled on was <a href="http://code.google.com/p/javaflight-code/">yui-compressor-ant-task</a>, a small library that allows Ant to use YUI as a build task.  By adding this library and the YUI compressor library to our common libraries folder, and enabling them at build only (and not for deploying in the web archive), it makes using the compressor pretty easy.</p>
<p>Here&#8217;s part of our <code>build.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!--</span>
<span style="color: #808080; font-style: italic;">   * minify will concatenate all of our non-TinyMCE javascripts and stylesheets</span>
<span style="color: #808080; font-style: italic;">   * then use the YUI compressor library to compress them</span>
<span style="color: #808080; font-style: italic;">   --&gt;</span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;minify&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
       <span style="color: #808080; font-style: italic;">&lt;!--${libs} is path to the downloaded jars --&gt;</span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span></span>
<span style="color: #009900;">           <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;yui-compressor.jar&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;${file.reference.yuicompressor.jar}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span></span>
<span style="color: #009900;">           <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;yui-compressor-ant-task.jar&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;${file.reference.yui-compressor-ant-task.jar}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;path</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;task.classpath&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathelement</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;${yui-compressor.jar}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathelement</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;${yui-compressor-ant-task.jar}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/path<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
       <span style="color: #808080; font-style: italic;">&lt;!-- yui-compressor task definition --&gt;</span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;taskdef</span></span>
<span style="color: #009900;">           <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;yui-compressor&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">classname</span>=<span style="color: #ff0000;">&quot;net.noha.tools.ant.yuicompressor.tasks.YuiCompressorTask&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;classpath</span> <span style="color: #000066;">refid</span>=<span style="color: #ff0000;">&quot;task.classpath&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/taskdef<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
       <span style="color: #808080; font-style: italic;">&lt;!-- concatenation of javascript --&gt;</span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Building global javascript&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;concat</span> <span style="color: #000066;">destfile</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/js/global.js&quot;</span> <span style="color: #000066;">force</span>=<span style="color: #ff0000;">&quot;no&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
           <span style="color: #808080; font-style: italic;">&lt;!-- explicitly order js concat because ordering matters here --&gt;</span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.bgiframe.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.hoverIntent.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/ui.core.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/ui.autocomplete.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/ui.datepicker.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/ui.tabs.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/tablesort.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/customsort.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.blockUI.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.form.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.ifixpng.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.superfish.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.cluetip.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.scrollTo.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.jqModal.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/validation.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/js/jquery.timeentry.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/concat<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
       <span style="color: #808080; font-style: italic;">&lt;!-- concatenation of cascading stylesheets --&gt;</span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Building global cascading stylesheets&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;concat</span> <span style="color: #000066;">destfile</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/css/global.css&quot;</span> <span style="color: #000066;">force</span>=<span style="color: #ff0000;">&quot;no&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/base.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/superfish.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/announcements.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/myvt.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/forms.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/cluetip.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>   
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/tables.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/ui.tabs.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/ui.datepicker.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/ui.autocomplete.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/linkspan.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/stepMenu.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/print.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">includes</span>=<span style="color: #ff0000;">&quot;web/common/css/youHaveMessages.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/concat<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
       <span style="color: #808080; font-style: italic;">&lt;!-- invoke compressor --&gt;</span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;yui-compressor</span> <span style="color: #000066;">warn</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">charset</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000066;">fromdir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;${build.dir}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;web/common/js/global.js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
           <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;web/common/css/global.css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/yui-compressor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
   <span style="color: #808080; font-style: italic;">&lt;!--</span>
<span style="color: #808080; font-style: italic;">   * purge-src takes our compressed files, moves them to the base /common dir</span>
<span style="color: #808080; font-style: italic;">   * and deletes the source js and css dirs from the build dir</span>
<span style="color: #808080; font-style: italic;">   --&gt;</span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;purge-src&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;minify&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Purging javascript and stylesheet sources&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;move</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/js/global-min.js&quot;</span> <span style="color: #000066;">tofile</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/global.js&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;move</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/css/global-min.css&quot;</span> <span style="color: #000066;">tofile</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/global.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;delete</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/js&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;delete</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${build.dir}/web/common/css&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>What you see there is essentially four steps.</p>
<ol>
<li>Concatenate all the constituent source files into a <code>global.js</code> and a <code>global.css</code></li>
<li>Compress both of these files, which creates <code>global-min.js</code> and <code>global-min.css</code> (default behavior)</li>
<li>Move these files out of the source directories and into the root of the common web directory as <code>global.js</code> and <code>global.css</code></li>
<li>Delete the source directories in our build folder so they don&#8217;t get deployed with the web archive</li>
</ol>
<p>Because certain browsers (IE) break without explicit ordering, we unfortunately can&#8217;t just use &#8220;*.js&#8221; and &#8220;*.css&#8221; in our concatenation step, but having to explicitly list our components in the build file certainly isn&#8217;t the end of the world.  The nice thing is that the Ant task will even print out handy statistics on just how much you&#8217;ve been able to compress the files down.  In our case, we have about 441.8KB of common Javascript and CSS in our source code that, by the time it gets sent to the user, has been minified and/or gzipped to about 89KB.</p>
]]></content:encoded>
			<wfw:commentRss>http://heliologue.com/2008/09/22/using-yui-compressor-in-a-web-project/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Creating an admissions dashboard</title>
		<link>http://heliologue.com/2008/09/11/creating-an-admissions-dashboard/</link>
		<comments>http://heliologue.com/2008/09/11/creating-an-admissions-dashboard/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 19:02:16 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://heliologue.com/?p=2354</guid>
		<description><![CDATA[This entry pertains to work done in the context of my employment. Please remember, however, that any opinions expressed on this blog do not necessarily reflect those of my employer or co-workers. The Problem Admissions needed help. They had been moved from their former product, Exeter, to Banner&#8217;s native admissions module. But Banner&#8217;s interface stinks, [...]]]></description>
			<content:encoded><![CDATA[<p class="alert">
This entry pertains to work done in the context of my employment.  Please remember, however, that any opinions expressed on this blog do not necessarily reflect those of my employer or co-workers.
</p>
<h3>The Problem</h3>
<p>Admissions needed help.  They had been moved from their former product, Exeter, to Banner&#8217;s native admissions module.  But Banner&#8217;s interface stinks, and there was no decent way for counselors to do, well, anything.  They relied on daily reports run out of an Excel pivot table by the executive directory of admissions, and therefore they lived on paper.  The counselors needed a better way to get their work done and stay on top (figuratively speaking) of their recruits.</p>
<p>Enter my department.  It fell to us, after some discussion, to build a tool that would be initial for undergraduate counselors, to let them slice and dice their data as needed.  After a pilot run, it will gradually be expanded to include graduate and transfer admissions, as well as reporting tools for directors and and other muckity-mucks.</p>
<p><span id="more-2354"></span></p>
<p>The current iteration is 4808 lines of code, for both the views and the comment submissions servlet.  Most of it was written by me, though some was reused code, and the initial servlet skeleton was written by my boss.</p>
<div class="gallery">
<h4 class="gallery">Admissions Dashboard</h4>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_01.png" title="Parameter page, loading recruiter list via AJAX" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_01_thumb.png" alt="Parameter page, loading recruiter list via AJAX" /></a></p>
<div class="gallery-hidden" id="admissionsdashboard">
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_02.png" title="Parameter page, using the high school autocomplete" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_02_thumb.png" alt="Parameter page, using the high school autocomplete" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_03.png" title="The table view" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_03_thumb.png" alt="The table view" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_04.png" title="Base detail view" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_04_thumb.png" alt="Base detail view" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_05.png" title="Checklist detail view" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_05_thumb.png" alt="Checklist detail view" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_06.png" title="Comments" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_06_thumb.png" alt="Comments" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_07.png" title="Mailings" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_07_thumb.png" alt="Mailings" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_08.png" title="Contacts" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_08_thumb.png" alt="Contacts" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_09.png" title="Entering a comment (with date widget)" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_09_thumb.png" alt="Entering a comment (with date widget)" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_10.png" title="Financial Aid summary" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_10_thumb.png" alt="Financial Aid summary" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_11.png" title="Student Bill" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_11_thumb.png" alt="Student Bill" /></a></p>
<p><a href="http://heliologue.com/img/albums/admissions_dashboard/dashboard_12.png" title="Student schedule" rel="lightbox[admissionsdashboard]"><img src="http://heliologue.com/img/albums/admissions_dashboard/dashboard_11_thumb.png" alt="Student schedule" /></a></p>
</div>
<p><a class="showImages" rel="admissionsdashboard">toggle thumbnails</a>
</div>
<h3>Setting Parameters</h3>
<p>The first thing an admissions counselor sees is a parameter page.  There are a number of options to choose from:</p>
<ul>
<li>Term (can be multiple)</li>
<li>Population selection (e.g. active applicants, active but non-applied recruits, enrolled applicants, etc)</li>
<li>Student level (can be multiple)</li>
<li>Recruiter (signed-in counselors will be auto-selected (can be multiple)</li>
<li>High School (can be multiple)</li>
</ul>
<p>Selecting from term or student level repopulates the possible recruiter list with only applicable options.  Selecting &#8220;Undergraduate&#8221; applicants will necessarily filter out (or should filter out) graduate admissions counselors so they&#8217;re no longer an option.</p>
<p>Perhaps the toughest engineering challenge here was high schools.  We currently have ≈10&#8217;000 high schools in our database, and will likely have a lot more soon.  Loading all those into a multiple select box would make the page huge, and likely overload some underpowered browsers.  My solution?  Autocomplete.  Using a simple JSP fragment and the <a href="http://docs.jquery.com/UI/Autocomplete">Autocomplete</a> plugin for jQuery, I was able to make a simple autosearch/complete behavior;  selecting an item drops it into a list below the input box.</p>
<p>The odd thing about the plugin was that it didn&#8217;t end up being very flexible about the format of returned data.  I had figured it would ask you to specify a data type and do your own parsing.  It seems, though, that it only wanted one format:  pipe-delimited data, with newlines between records.  After wrestling with it for a while, I finally got it to work, but I really would have rather just returned XML and done some simple parsing.</p>
<h3>The Table View</h3>
<p>Once the parameters are chosen, the user gets a very complex table (the specifications were given to us by the Admissions department).</p>
<ul>
<li>Name</li>
<li>Term (if >1 chosen)</li>
<li>High School (if >1 chosen or none specified)</li>
<li>Intended major (code display; full description on hover)</li>
<li>Application decision (e.g. accepted, denied, etc) (code display; full description on hover)</li>
<li>Student type (e.g. new freshman, transfer, etc)</li>
<li>Athlete indicator</li>
<li>Registered indicator</li>
<li>Application status
<ul>
<li>Green:  complete, no pending items</li>
<li>Yellow:  complete, but pending items which don&#8217;t affect admission</li>
<li>Red:  incomplete: pending items affect admission</li>
<li>None (has no application;  is only a recruit)</li>
</ul>
</li>
<li>Financial Aid
<ul>
<li>Green:  all items complete, and aid is packaged</li>
<li>Yellow:  all items complete, but aid is not yet packaged</li>
<li>Red:  outstanding items; aid cannot be packaged</li>
<li>None (has no financial aid)</li>
</ul>
</li>
<li>Date of application</li>
<li>Composite admissions score</li>
<li>Date of last comment (usually a contact with applicant)</li>
<li>Visited campus indicator (is not currently used)</li>
</ul>
<p>The recruiter can export this table as an Excel document for easy printing and carrying;  otherwise, clicking on a recruit/applicant&#8217;s name will bring up a detail screen, which is divided into several sections.</p>
<h3>The Detail View</h3>
<h4>Basic</h4>
<p>I call it basic, but this is really the most detailed tab of this entire view.</p>
<ul>
<li><strong>Application-related Items</strong>
<ul>
<li>Entry Term</li>
<li>Source</li>
<li>Major</li>
<li>Admissions Counselor</li>
<li>Application Status</li>
</ul>
</li>
<li><strong>Biographical Items</strong>
<ul>
<li>Banner ID</li>
<li>PIN (for helping with portal access)</li>
<li>Last Portal login</li>
<li>Student Type</li>
<li>Advisor (email link)</li>
<li>Residence (dorm icon for on-campus, car icon for commuter)</li>
<li>College (Education, Arts &#038; Science, etc)</li>
<li>Date of Birth</li>
<li>Phone Number(s) (shows primary; expands to show others)</li>
<li>Email Address(es) (shows primary; expands to show others)</li>
<li>Address</li>
</ul>
</li>
<li><strong>Holds</strong> (is only shown when there are holds on the student&#8217;s account)
<ul>
<li>Hold Type</li>
<li>List of items which this hold prevents</li>
</ul>
</li>
<li><strong>Education</strong>
<ul>
<li>High School (for undergrad and transfer)
<ul>
<li>Name of high school</li>
<li>Graduation Date</li>
<li>GPA</li>
<li>Class rank</li>
<li>ACT composite score</li>
</ul>
</li>
<li>College (for graduate and transfer)
<ul>
<li>Name of college</li>
<li>Dates of attendance</li>
<li>GPA transferred</li>
</ul>
</li>
</ul>
</li>
<li><strong>Athletics</strong> (list of sports/activities)</li>
</ul>
<h4>Checklist</h4>
<p>The checklist is a simple table displaying pending and completed items necessary for admission.  The applicant sees the exact same table when they sign into the portal, so now the counselor can see what the applicant sees.</p>
<h4>Mailings/Contacts/Comment</h4>
<p>This is a tripartite screen.  The first and most important section is &#8220;Comments,&#8221; which is a sort of chronicle of counselors contacts with the applicant or the applicant&#8217;s parents.  This screen is especially nasty using the native Banner interface, and so the object was not only to make the viewing nice, but also allow for the deletion, editing, and creation of comments.</p>
<p>Contacts and mailings are merely for records of correspondence the applicant or recruit has received, aggregated from several places.</p>
<h4>Financial Aid</h4>
<p>This screen gives detail of all awarded financial aid, as well as both completed and outstanding documents.  This, too, is almost exactly what the applicant will see when signed into his or her portal.  </p>
<h4>Bill</h4>
<p>This screen, which details charges and payments for the student, is once again a replica of screens available to the applicant when logged in.   These screens are mostly to provide parity for support with applicants who have questions about financial aid, bills, or schedules.</p>
<h4>Schedule</h4>
<p>Once an applicant is accepted, and registers for class, this schedule tab will be filled out.  It is a slight modification of the student&#8217;s schedule, which is displayed to them upon portal sign-in.   Advisor see a similar view, since this is a module we reuse in several different portions of the web app.</p>
<h3>The Big Finish</h3>
<p>There are always bugs.  I realize, just before going live, that the <abbr title="abbreviation">abbr</abbr> tag that I used so heavily in the tabular view isn&#8217;t natively supported by Internet Explorer 6.</p>
<p>Luckily, good old <a href="http://dean.edwards.name/my/abbr-cadabra.html">Dean Edwards</a> notes that for some reason, prefixing the namespace to the <code>&lt;abbr&gt;</code> tag makes the damn thing suddenly work, and it&#8217;s still valid XHTML!  Crisis averted.</p>
<p>As with most of our web application, we make heavy use of <a href="http://jquery.com">jQuery</a>. Specifically for this application, we make use of the UI Tabs plugin, the UI Autocomplete plugin, and jQuery&#8217;s native AJAX functionality.  We also use the <a href="http://www.frequency-decoder.com/2006/09/16/unobtrusive-table-sort-script-revisited">Unobtrusive Tablesort Script</a> from Frequency Decoder, which has much better performance than jQuery equivalents.</p>
<p>As I said, this is only a first try at a first stage, but we&#8217;re pretty happy with the progress, and the admissions folks seem to be as well, so we&#8217;re doing <em>something</em> right.</p>
]]></content:encoded>
			<wfw:commentRss>http://heliologue.com/2008/09/11/creating-an-admissions-dashboard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Various and sundry technology stuff pertaining to work</title>
		<link>http://heliologue.com/2007/12/08/various-and-sundry-technology-stuff-pertaining-to-work/</link>
		<comments>http://heliologue.com/2007/12/08/various-and-sundry-technology-stuff-pertaining-to-work/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 07:38:25 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://heliologue.com/blog/2007/12/08/various-and-sundry-technology-stuff-pertaining-to-work/</guid>
		<description><![CDATA[I don&#8217;t usually talk about work on this blog, simply because I&#8217;ve read enough horror stories about blogging work matters to know how badly it ends. Granted, if I were to blog about my job, it would mostly consist of technology bits, but it&#8217;s still one of those grey areas I avoid out of propriety. [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t usually talk about work on this blog, simply because I&#8217;ve read enough horror stories about blogging work matters to know how badly it ends.  Granted, if I were to blog about my job, it would mostly consist of technology bits, but it&#8217;s still one of those grey areas I avoid out of propriety.</p>
<p>Yet, I find myself at home, with a <a href="http://en.wikipedia.org/wiki/White_Russian_(cocktail)">White Russian</a> and the urge to opine.</p>
<p><span id="more-1941"></span></p>
<h3>The Background</h3>
<p>In the summer of 2006, my workplace (<a href="http://www.stfrancis.edu">The University of St. Francis</a>, my alma mater) went live with a portal.  For the previous year and half, when I was a student worker, we&#8217;d been working desperately to implement <a href="http://portalcenter.oracle.com/">Oracle Portal</a>.  At a conference that summer, my boss, Tim, heard about <a href="http://uportal.org">uPortal</a>, an open-source J2EE portal.  On the <a href="http://heliologue.com/2006/06/30/the-conference-day-iii/">ride back from Ohio</a>, we more or less decided to try it on a lark.  It&#8217;s basic ease of setup let us switch to uPortal and go live in 6 weeks.  That&#8217;s right, a production-ready portal in 6 weeks.  </p>
<p>Much of the work in that time was tying <a href="http://www.ja-sig.org/products/cas/">CAS</a> into our LDAP implementation (Novell&#8217;s eDirectory), customizing the view (props to Virginia Tech for their excellent <a href="http://my.vt.edu/content/myvt3/myvt/tour-uportal/">Tab-Column customization</a>), and writing some basic portlets to allow quick views into student data:  schedule, personal info, billing, &amp;c.  We&#8217;re a Banner school, so we could basically just reach into our Oracle database and pull the data we needed.</p>
<h3>The Cool Bits</h3>
<p>Since that time, we&#8217;ve poured a tremendous amount of energy into the portal, as it&#8217;s become our go-to spot for finding information and getting things done.  Actually, we&#8217;ve spent very little time on uPortal at all, as it already contains much of the quick-view functionality we want.  Much of what we do is a custom extension to the portal that transparently shares session data via CAS.  </p>
<blockquote title="A brief overview of our functionality, as noted by my boss">
<p>We have completed our portal rollout using uPortal (running on apache/tomcat), and are integrated with Sungard Banner 7.x for much of the information we pull and display, and we are using Novell E-Directory for our directory.</p>
<p>We used uPortal which proved to be a much more promising and easier to use platform than Oracle portal. Within 6 weeks we had our first production portal deployment. Over the last year we have built and put the following into production:</p>
<ul>
<li>Student Schedule and Grades Display (pulled realtime from Banner)</li>
<li>WebCT Integration/SSO</li>
<li>Announcements (Targeted coming by end of summer &#8217;07)</li>
<li>SSO to Novell WebMail, Netstorage, and Banner Self Serve</li>
<li>Bookstore Integration with Barnes and Noble (Shopping cart of books)</li>
<li>Financial Aid Portlet/Accept Loans &#8211; Display and update banner data</li>
<li>Tuition Bill Portlet &#8211; Pulled in realtime from Banner AR</li>
<li>Payment of Tuition Bill/Post Directly to Banner AR</li>
<li>My Profile Portlet (information pulled realtime from Banner)</li>
<li>GPA/Credit Hours Portlet (Pulled realtime from banner)</li>
<li>Banner Security Question/Reset Password Functionality</li>
<li>Expired Password Functionality</li>
<li>Faculty Schedule/Class Rosters/Email Class, Export to Excel</li>
<li>Banner Survey Integration</li>
<li>HR Leave Balances</li>
<li>Budget Reporting/Financial Activity/View Documents, checks cut, etc</li>
<li>Banner Requisition Approval</li>
<li>Web Based University Income/P&#038;L Statement</li>
<li>Banner Finance Journal Voucher Upload</li>
<li>PIDM Usage Utility to help identify and resolve duplicate pidms</li>
<li>EZProxy/Library Databases Integration</li>
<li>Advancement Constituent Profiles</li>
<li>Advancement Fundraising Activity Reports</li>
<li>Advancement Constituent Contacts Data Entry/Reminders</li>
<li>Financial Aid targeted messages</li>
<li>GUAMESG</li>
<li>Residence Life View your Room/Roomates</li>
<li>Bulletin Boards (phpBB)</li>
<li>VT Calendar</li>
<li>Various Web based Reports</li>
<li>E-Directory Integration/Account Creation</li>
<li>Early alert and midterm warning submission, that allows the student, advisor, registrar, athletic coaches, and other support staff know when a student is having academic difficulties.</li>
<li>An online advising center. Advisors can now see all of their advisees, look at who&#8217;s registered, view issues with the students account such as registration or medical holds, etc. The goal is so that advisors can also help the students get their issues resolved.</li>
<li>Our initial stab at targeted announcements is done. We can now target based on the student type, level, or college as currently stored in the Banner ERP, as well as target to only employees or faculty members. The framework is in place to target off of any data element stored in Banner. Now we just need to expand our GUI allowing users to target messages.</li>
<li>Accounts Receivable Reporting Suite &#8211; Our finance office now uses the portal to do various AR reporting tasks, drilling into student details, etc.</li>
<li>Enrollment/Registration Status Reports &#8211; Various members of the university can now easily look at the overall student registration status through the portal.</li>
<li>A faculty attendance tracking module for faculty to electronically submit the attendance of students in their classes at the beginning of term and at the mid-term point. This helps the registrar and financial aid determine who is actually attending, and replaces an old paper based process.</li>
<li>On online Student Check-In procedure. Students can now confirm their class schedules, financial aid, and pay their bill through an easy to use &#8220;wizard&#8221; interface. The system will notify when they need to perform the electronic check in process before the start of the term, and then walks them through the process. This helps to collect payments sooner and determine which students are actually going to show up to class on day 1.</li>
<li>Our portal now has a targeted messaging facility which looks at business rules and notifies the students of issues or action items related to their student records. For example, if a student has holds on their account the system will tell them, show them the hold, tell them what it prevents them from doing, and who to contact to resolve the hold. For students with incomplete medical records they are notified, and shown which parts of their medical records are incomplete (and for our nursing program, which shots, etc they need to have on file to be able to attend clinicals).</li>
<li>A co-curricular transcript which pulls from Banner all the clubs, organizations, and sports a student has been a member of during their time at the university, and shows them in a nicely formatted page that they can print.</li>
<li>A real-time registration status dashboard for administrators, deans, and faculty members. This dashboard now shows the head counts, course registration counts, credit hours, and billing hours generated for registered students, and the number of potential students who are left to register. It breaks the summary counts down in several ways: by college, major, advisor, or level (graduate, undergrad, etc). The users can drill into this report and extract lists of students who still need to get registered, whom to call to see if they need advising help or assistance registering, etc.</li>
</ul>
</blockquote>
<p>As the UI architect for the portal extension, I decided this past summer to standardise on <a href="http://jquery.com">jQuery</a>, and certainly haven&#8217;t regretted it.  The only bad thing about javascript is that it becomes easy to rely on it for things which should really be controlled server-side.  Important validation checks, for instance.   Since our ERP system has certain business logic which it enforces on the database level, we usually do two checks for important data:  one (javascript) for the user&#8217;s sake, and one (servlet) for ours.</p>
<p>It got to the point where we were loading 10 different jQuery javascripts and 2 stylesheets in our header.  Most of the javascripts were either <a href="http://dean.edwards.name/packer/">packed</a> or uncompressed (if packing broke them), and totaled about 200Kb.  Not only was this too much, but the <code>eval()</code> caused a delay for each script.  Recently, after one of our rollouts to production, when I got more leeway to play, I completely upgraded our script layout.  I&#8217;m not going to provide an apples-to-apples comparison table here, since the prior configuration was a hodgepodge, but after <a href="http://developer.yahoo.com/yui/compressor/">minifying</a> and turning on server-side compression for javascripts and stylesheets, I managed to reduce the load from 200Kb in 12 requests to about 50Kb in 5 requests.  According to <a href="http://www.julienlecomte.net/blog/2007/08/13/">Julien Lecomte</a>, running mod_deflate on a minified (but no obfuscated) javascript yields the lowest file size;  regardless of how often that&#8217;s true, I like the idea of avoid latency from the <code>eval()</code>.  A lot of our users are still on IE6, and they take some pretty big performance hits.</p>
<p>Goodness knows there&#8217;s more I could do, but given the nature of our portal (single-image CSS layouts, anyone?), it wouldn&#8217;t be a productive use of our time);  I have enough crap to do with counting pixels.</p>
<h3>jQuery rocks my socks</h3>
<p>I might take a moment here to say just how much I love jQuery.  For those of you who don&#8217;t know, jQuery is a javascript framework which abstracts a lot of functions into a much more easily-written manner.  In the past, I&#8217;ve sort of been a Copy &amp; Paste javascript programmer, since it&#8217;s been easier to use some free script than to write one&#8217;s own code.  jQuery and it&#8217;s vast array (har!) of plugins makes it easy to implement or write new code.  For instance, if we want to implement a support for CSS hover effects in IE, all we do is this:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">$<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">&quot;input:text,input:password,textarea&quot;</span><span style="color: #00AA00;">&#41;</span>.focus<span style="color: #00AA00;">&#40;</span>function<span style="color: #00AA00;">&#40;</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
     $<span style="color: #00AA00;">&#40;</span>this<span style="color: #00AA00;">&#41;</span>.addClass<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">&quot;focused&quot;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
&nbsp;
$<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">&quot;input:text,input:password,textarea&quot;</span><span style="color: #00AA00;">&#41;</span>.blur<span style="color: #00AA00;">&#40;</span>function<span style="color: #00AA00;">&#40;</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
     $<span style="color: #00AA00;">&#40;</span>this<span style="color: #00AA00;">&#41;</span>.removeClass<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">&quot;focused&quot;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span></pre></div></div>

<p>Easy as pie.</p>
<p>Granted, there are a lot of frameworks to choose from.  Originally, there was only <a href="http://">Prototype</a>;  now there&#8217;s also jQuery, <a href="http://dojotoolkit.org/">Dojo</a>, <a href="http://developer.yahoo.com/yui/">YUI</a>, <a href="http://mootools.net/">Mootools</a>, <a href="http://openrico.org/">Rico</a>, and any one of a number of others.  </p>
<p>The one I wanted to talk about in this post in particular is <a href="http://extjs.com/">ExtJS</a>, which was originally an extension of the YUI framework, but which eventually split off into its own project.  It recently went 2.0, and boasts some rather impressive <a href="http://extjs.com/deploy/dev/examples/">demos</a>.  I marvel at the Vista-like UI, which, admittedly, is very slick.</p>
<p>But the more I look at ExtJS, and half-heartedly consider its possible deployment within our portal, the less enthused I become.  ExtJS&#8217;s grid, for instance, doesn&#8217;t even function on existing HTML table markup:  you mass it an array of data as a javascript variable, and it creates markup on the fly&#8230; a <em>lot</em> of markup, in order to create it&#8217;s slick Office 2007 interface.  While this is <em>good</em> insofar as it manages to completely abstract data from presentation, I&#8217;m not sure how much I <em>like</em> the idea, since it <strong>(1)</strong> relegates users to the script default without heavy customization, and <strong>(2)</strong> doesn&#8217;t allow for any kind of fallback mechanism if the javascript should fail or the user has it disabled.  Our table-sorting function, in a case like that, doesn&#8217;t at all prevent the table markup and data itself from being rendered.</p>
<p>Work can be fun sometimes.</p>
]]></content:encoded>
			<wfw:commentRss>http://heliologue.com/2007/12/08/various-and-sundry-technology-stuff-pertaining-to-work/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

