iPhone App: pTerm
August 11, 2008 | 3 Comments
At long last a Terminal application is available on the iPhone, and pTerm is its name! Based on the desktop client PuTTY, you can SSH, Telnet, and raw TCP from your iPhone/iPod Touch!
Its features are:
- xterm terminal emulation
- Standard 80×24 screen
- SSH, Telnet, or “raw” TCP connections
- Ctrl key support
- Landscape and Portrait modes
- Works over Edge, 3G, or WiFi
- Stores your list of host/port/protocol for convenient access
- Terminal supports pinch and zoom
- Based on PuTTY, a stable and feature-rich code base
All in all, the app seems pretty solid. My only gripe is the lack of a tab key for tab completion. Now I’ll be able to debug stuff remotely WITHOUT using VNCLite for the iPhone. Check pTerm out, it is well worth the $4.99.
Update:
There are some more things that I find annoying:
- No tab key - no tab completion…
- No arrow keys - this makes navigating around a line a little bit of a pain.
- You can’t hide the keyboard. It’d be nice to see a full screen of top.
- No color customization
Despite the annoyances, the app is still pretty solid. Lets just hope new versions come out sooner than later with some of my hopes and dreams attached.
Compiling Invalid Objects in PL/SQL
June 25, 2008 | 4 Comments
While I do a lot of and prefer PHP and JavaScript development, my daily job has a darker side...PL/SQL. At times the packages that I oversee invalidate during upgrades or poor compilations of a package that ends up having a ripple effect.
Here's a query I wrote to find the invalid objects and generate compile statements to attempt to fix whatever is busted.
-
SELECT CASE object_type
-
WHEN 'PACKAGE' THEN
-
'ALTER '||object_type||' '||owner||'.'||object_name||' COMPILE;'
-
ELSE
-
'ALTER PACKAGE '||owner||'.'||object_name||' COMPILE BODY;'
-
END
-
FROM dba_objects
-
WHERE STATUS = 'INVALID'
-
AND object_type IN ('PACKAGE','PACKAGE BODY','FUNCTION','PROCEDURE');
Luminis: Forcing CSS/JavaScript Updates to Clients
June 2, 2008 | 1 Comment
Contents:
Introduction
I gave a talk at SunGard Summit in Anaheim this spring on Plymouth State's portal (myPlymouth). There were a number of really great questions that came up following my presentation, one of which is the topic of this post:
When upgrading Plymouth State's Luminis installation from III to IV, we had to tackle this same issue and after banging my head against the wall a number of times, I found our answer. I wanted to:
- Ensure that the JavaScript and CSS that is being served up to our users can be cached by their browser in order to optimize their download speeds.
- Control when a user's browser has to re-download a new version of the code.
- Do the above within the bounds of the very restrictive caching provided by the Luminis product.
All of it was super easy to do, although I must admit I knocked my head against the wall a few times coming up with the solution to the 3rd in that list.
Step 1: Basic Browser Caching
When I sat down to tackle this problem, I knew that the inline JavaScript within nested_tables.xsl was an unforgiving issue - if I wanted to make a change to some of the inline JavaScript, those changes would not be forced upon the users until Luminis decided to let go of its cached nested_tables.xsl.
That didn't work for me. So I ripped the inline styles out and combined a few JavaScript files into one...called combined.js.
My header within the regularLayout template in nested_tables.xslnow looked something like this:
-
<head .......>
-
<title>.........</title>
-
<script type="text/javascript" src="/js/clientsniffer.js"></script>
-
<script type="text/javascript" src="/js/util.js"></script>
-
<script type="text/javascript" src="/psu/js/combined.js"></script>
-
<script type="text/javascript" src="/psu/js/behavior.js"></script>
-
<link rel="stylesheet" type="text/css" href="/psu/style.css"/>
-
</head>
The files clientsniffer.js and util.js are SunGard delivered and I did not touch those two. As I mentioned before, I yanked out all the inline JavaScript (provided by SunGard) and dropped that into combined.js along with a number of jQuery code. Our own custom Luminis JavaScript that controls a lot of our Ajax-like functionality in myPlymouth is in behavior.js. And of course, style.css holds the CSS for our portal.
All of these files could now be cached by users' browsers. Yay. I bounced the development portal and saw my changes in all their glory. Life was good.
Step 2: Browser Cache, Code Changes, and You
Invigorated by my recent success of effectively doing nothing, I grabbed a soda and began tackling the next objective. I had done this numerous times in my PHP applications and it was as simple as placing a version number at the end of the URLs used in the link and script tags. As such:
-
<head .......>
-
<title>.........</title>
-
<script type="text/javascript" src="/js/clientsniffer.js"></script>
-
<script type="text/javascript" src="/js/util.js"></script>
-
<script type="text/javascript" src="/psu/js/combined.js?v=1.0.0"></script>
-
<script type="text/javascript" src="/psu/js/behavior.js?v=1.0.5"></script>
-
<link rel="stylesheet" type="text/css" href="/psu/style.css?v=1.0.5"/>
-
</head>
Once again, I bounced our portal, saw the changes, and danced around the room. Step 2. Accomplished.
Step 3: Taming Versioning/Cache Expiration in Luminis
The goal of taming this versioning/cache expiration was to do so without the need for bouncing the portal so I could make changes on the fly without planning for down times. Step 2 - as I detailed above - only gets you so far. With Step 2 in place, I could easily make a change in my CSS file and edit nested_tables.xsl to one-up my version number. But, because nested_tables is cached by Luminis, that wasn't good enough. Here's what I came up with:
I removed the script and link tags in the header of the regularLayout template in nested_tables, created a file called load.js, and dropped the homeless script/link tags as document.writes in load.js...as so:
Start of a Solution: load.js
-
document.write('<script type="text/javascript" src="/js/clientsniffer.js"></script>');
-
document.write('<script type="text/javascript" src="/js/util.js"></script>');
-
document.write('<script type="text/javascript" src="/psu/js/combined.js?v=1.0.0"></script>');
-
document.write('<script type="text/javascript" src="/psu/js/behavior.js?v=1.0.5"></script>');
-
document.write('<link rel="stylesheet" type="text/css" href="/psu/style.css?v=1.0.5"/>');
But wait...
This gave me a file with all of my script/link tags and their appropriate versions. However...I couldn't simply replace all those script/link tags with a script tag that pointed at load.js because load.js itself would be cached by users' browsers. So this got past the Luminis caching, but not our end users. So I came up with this:
Final Solution: pre_load.js
So...I wanted to cache all my sub-files and prevent load.js from caching so that I could version my scripts easily without bouncing the portal. The solution? Yet another file! I called it pre_load.js and it looks something like this:
-
document.write('<script type="text/javascript" src="/psu/js/load.js?nocache=' + (new Date()).getTime() + '"></script>');
A simple document.write of a script tag with an appended variable based on time in order to prevent caching on the browser side. Yup...load.js is never cached, but it is a small price to pay.
Now my header in the regularLayout template in nested_tables.xsl looks like this:
How it works
- Luminis happily caches the pre_load.js script tag in the nested_tables.xsl.
- The JavaScript within pre_load.js writes another script tag to the document at render time. That script's URL is a call to load.js along with a variable that changes each page load thus preventing load.js from being cached.
- load.js then document.writes the appropriately versioned script/link tags into the document.
- The individual script/link tags load the associated JavaScript/CSS files. If the browser has already cached that script/link URL (remember, we change the version numbers when we make changes to the JS or CSS), then the cached file is loaded...otherwise the new version is retrieved from the server.
Summary
The set-up is fairly basic but the results just what we were hoping! And all it took was:
- Placing inline JavaScript into a file (combined.js)
- Creating load.js to document.write script/link tags
- Creating pre_load.js to document.write a script tag that uses a cache-free URL call to load.js
To date, we have not had any reported issues with local or server-side caching of our JS/CSS files using this method! You just need to make sure you remember to version your URLs in load.js!
The Best Photoshop Tutorials Ever
March 7, 2008 | 3 Comments
My Damn Channel, an entertainment studio, has a series of Photoshop tutorials that are hilarious and...well...really good. I saw You Suck At Photoshop #8 via Digg and ended up watching them all. Really good stuff.
Here's #7:
myPlymouth: Thanksgiving Theme
November 28, 2007 | 3 Comments
Thursday before Thanksgiving, users of the myPlymouth portal at Plymouth State were greeted by an altered header graphic similar to that of the Halloween theme I had done for the previous month.
This one, however, changed daily for 9 days. Here's the sequence:
Now, once I finished that final graphic Dan approached me and made a funny request. He wanted a special little violent ending for himself. The thought of a custom final header for a few sketchy people sounded fun...so I obliged with this header that showed for a mere 5 people on campus:
In addition to the internal alteration of the header, I did another alteration on the login page for the Tuesday and Wednesday before as well as the Thursday of Thanksgiving. My pal, the turkey, showed up in place of the random image. Here he is:
Overall, the header was well received be the campus feuling my desire to come up with something nifty for the coming holidays! A special thanks to Ken, Zach, and Dan for giving good content suggestions and allowing me to bounce ideas off them!
Plymouth State: JavaScript Workshop
November 11, 2007 | 1 Comment
Tonight I led a workshop on JavaScript for some PSU Employees. We discussed JS basics, node manipulation, DOM traversal, AJAX, JavaScript libraries, and myPlymouth implementations of those topics. Here are the slides:
A few resources that were mentioned:
myPlymouth: Halloween Theme
November 2, 2007 | 4 Comments
As I alluded to on my last post, on Halloween, Zach, Dan, and I unveiled a new feature in Plymouth State University's portal. Plymouth State will begin customizing the myPlymouth logo and/or the entire header withing the portal.
Using some snazzy CSS easter-egg functionality combined with some PHP, we can dynamically alter the look of the portal and target customizations to the entire campus, groups of people, or individuals. On Halloween, we customized and targeted the entirety of our user population with the following header theme. We changed this:
To this:
The Halloween theme was a surprise to the campus and received a number of good reviews and comments! The theme didn't reduce the portal's functionality, it simply gave it a nice candy coating to add a little flair. Overall, I'm pretty happy with the layout (which is actually made up of 7 images). Due to the excitement around the Halloween theme, the campus can be sure that more are coming!
As I mentioned before, targeting the entire campus is doable along with targeting groups of people and individuals. Needless to say the targeting capabilities of this can be exploited by...well...by me. And I've had some fun exploiting it, too! Here's a couple of fun ones that I targeted at specific users:
This header was targeted at my manager, Ken:
This one is targeted at Dee:
Here's one that I targeted at Dan and Zach:
Fun times. So far, Dan, Zach, and I have some pretty sexy ideas for what can be done...ranging from minor tweaks to the logo (similar to the goofy ones I did above), to fully customized headers (like the Halloween one), all the way to full blown themes that customize a larger portion of myPlymouth. I look forward to getting creative with what I can draw and implement.
Art: Turkey Sketch
November 1, 2007 | 6 Comments
I've begun the design of custom headers for holiday themed portal action in Plymouth State University's portal. Here's a quick turkey sketch I did with my Wacom tablet in preparation for a Thanksgiving themed header. I'm still a little undecided on what I plan to do with the header as a whole. I have a few weeks to figure that out, I suppose :)
Automattic Acquires Gravatar!
October 18, 2007 | Leave a Comment
In a surprising move, Automattic has acquired Gravatar, which was announced this morning in Gravatar's new WordPress installation. This breathes life into a quality idea that had floundered due to fast popularity and (I can only assume) poor funding.
For those of you that don't know what Gravatar is:
I became a fan of Gravatar during my first launch of the SexyComments WordPress Plugin and was saddened at the instability and slowness of the avatar service after a few months of usage. My frustration grew so much that I looked to MyBlogLog as an avatar service despite its lack of features. As of release 1.4 of SexyComments, I had almost entirely wiped my hands of Gravatar.
Until now. Gravatar once again serves up avatars in the comments of this site and am excited at the changes that have already taken place:
- They have transferred the Rails application and most of the avatar serving to their WordPress.com infrastructure and servers.
- Avatar serving is now more than three times as fast, and works every time.
- They have moved the Gravatar blog from Mephisto to WordPress. :D
Additionally, I look forward to the features that Automattic is planning for Gravatar's future:
- They’re going to make all of the Premium features free, and refund anyone who bought them in the last 60 days.
- Move the gravatar serving to a Content Delivery Network so not only will they be fast, it’ll be low latency and not slow down a page load.
- Take the million or so avatars that exist on WordPress.com and make them available through the Gravatar API, to compliment the 115k already hosted at Gravatar.
- From Gravatar, integrate them into all WordPress.com templates and bring features like multiple avatars over.
- From WordPress.com, bring the bigger sizes (128px) over and make that available for any Gravatar. Currently Gravatars are only available up to 80px.
- Allow Gravatar profile pages with Microformat support for things like XFN
rel="me"and hCard. - Develop a new API that has cleaner URLs and allows Gravatars to be addressed by things like URL in addition to (or instead of) email addresses.
- Rewrite the application itself (site.gravatar.com) to fit directly into our WordPress.com grid, for internet-scale performance and reliability.
All in all, this made me pee my pants a little.
Yahoo Acquires Zimbra
September 17, 2007 | 1 Comment
Today, Zimbra announced today that they have been acquired by Yahoo! for $350 million. Zimbra was bound to be acquired by someone and the acquisition by Yahoo! wasn't an overly surprising move as it has had a tendency to pick up Web 2.0 and Ajax Web Apps over the past few years. It will be great to see where Zimbra (which is an amazing application) goes with the resources that Yahoo! brings to the table.
This purchase is interesting seeing how Plymouth State University, my place of employment, just finished an implementation this summer. With such a large organization backing Zimbra now, it will be interesting how licensing will change over the years. We can always hope that the changes will be minimal...but as always, change is inevitable.
Regardless, the two companies in bed together isn't too scary of a thought and I look forward to seeing things unfold!
jQuery 1.2 Released!
September 11, 2007 | Leave a Comment
This is a major release for the JavaScript library that I have grown to love. Before I list the new features, it is important to note what functionality has been removed from jQuery.
Here's the deprecated functionality:
- These Selectors
- XPath Descendant Selector: $("div//p")
- XPath Child Selector: $("div/p")
- XPath Parent Selector: $("p/../div")
- XPath Contains Predicate Selector: $("div[p]")
- XPath Attribute Selector: $("a[@href]")
- Calling clone() with an argument: $("div").clone(false);
- These Traversal Functions use the new .slice() instead):
- $("div").eq(0);
- $("div").lt(2);
- $("div").gt(2);
- These Ajax Functions:
- $("#elem").loadIfModified("some.php");
- $.getIfModified("some.php");
- $.ajaxTimeout(3000);
- $(...).evalScripts();
Thankfully a number of those don't effect me. I'll have to comb through my code to get rid of the .gt, .lt, and .eq traversal functions as well as a few of the selectors...but other than that, I'm good to go. To find out more about workarounds for the above removed functionality, check the jQuery 1.2 release notes
Now...on to the good stuff.
New features!
- Selectors
- :has(selector)
- :header
- :animated
- XPath Selector Plugin
- Attributes
- .val() Overhaul
- Traversing
- .map()
- .prevAll() / .nextAll()
- .slice()
- .hasClass()
- .andSelf()
- .contents()
- Manipulation
- .wrapInner() / .wrapAll()
- .replaceWith() / .replaceAll()
- Event Cloning
- CSS
- .offset()
- .height() / .width() for document and window
- Ajax
- Partial .load()
- Cross-Domain getScript
- JSONP
- .serialize() Overhaul
- Disable Caching
- Effects
- .stop()
- %/em Animations
- Color Animations
- Relative Animations
- Queue Control
- :animated
- step: Function
- Events
- Namespaced Events
- .triggerHandler()
- Internals
- Documentation Move
- Expando Management
I have to say...it is a pretty snazzy release and I'll begin implementing the new version shortly. w00t.
My First Keynote Presentation
August 23, 2007 | 1 Comment
After long consideration, I've dived into Apple's iWork Keynote full bore and have compiled this amazing presentation for Keynote to YouTube testing. Enjoy.
The presentation was awe-inspiring, I know. But what I was really doing was testing Keynote's ease of recording a presentation and sending that data to YouTube. My summary: it's so freaking easy your dog's owner could do it? All you do is build your presentation, go to the beginning and click Record Slide Show. Simply talk into the mic, then click stop recording when you are done! All you need to do from there is use Keynote's SendTo menu to send to YouTube. Authorize Keynote when it asks and BAM...done.
The Zach that I was referring to is my pal from NoSheep and the other voice is Dan from Tall Birch.
jQuery Plugin: Live Query
August 22, 2007 | 1 Comment
My hear is exploding with happiness and joy at the existence of Brandon Aaron. He has built a sweet jQuery plugin (Live Query) that reduces complexity in Ajax and general DOM manipulation coding by a great deal (when it comes to applying behaviors). First, let me tell you the problem (if you don't already know):
Say I build a web application where I want to assign an onClick event to an <a> tag. In jQuery I'd do it like this:
First the HTML:
Now lets do up the JavaScript:
-
$(document).ready(function(){
-
$('a.whatever').bind('click',function(){
-
alert('ZOMG Hai');
-
return false;
-
});
-
});
Simple, right? Yeah. It is. Nothing new. Now...say that I manipulate the DOM and add in another <a> tag with the class "whatever" that I want the same even applied (with or without Ajax, doesn't matter). Here's what I would have had to do in the past:
-
$(document).ready(function(){
-
$('a.another').bind('click',function(){
-
$('ul').append('<a href="whee.html" class="whatever">Bork</a>');
-
-
$('a.whatever').bind('click',function(){
-
alert('ZOMG Hai');
-
return false;
-
});
-
-
return false;
-
});
-
});
See that? Kinda complex. Things become quite complex when you begin doing Cross Domain Scripting via Remote JavaScript calls (which is what is heavily used in one of the apps I have done front-end development for).
The Live Query plugin is a beautiful thing as it "auto-magically" binds events to dynamically added elements within the page as they appear! So ALL of that JavaScript from both examples becomes:
-
$(document).ready(function(){
-
$('a.whatever').livequery('click',function(){
-
alert('ZOMG Hai');
-
return false;
-
});
-
-
$('a.another').bind('click',function(){
-
$('ul').append('<a href="whee.html" class="whatever">Bork</a>');
-
return false;
-
});
-
});
Yup. That's it. Bind a livequery event to an element and as elements that match appear on the page...BAM! The event is applied.
There are some more advanced things you can do with the plugin and you can find those out at the Live Query site.
Internet Explorer - Web Developer Toolbar
August 8, 2007 | 5 Comments
In a world of FireFox and its beautiful extensions of web-development power, Internet Explorer has been a horrid browser to develop/debug your code.
Microsoft has a fancy FireBug clone for the bane of every web developer...Internet Explorer! They call it the Web Developer Toolbar (although it isn't much of a toolbar and more of a tool set) and it is a blessing for finding problems in IE. Its features include:
- Explore and modify the document object model (DOM) of a Web page.
- Locate and select specific elements on a Web page through a variety of techniques.
- Selectively disable Internet Explorer settings.
- View HTML object class names, ID's, and details such as link paths, tab index values, and access keys.
- Outline tables, table cells, images, or selected tags.
- Validate HTML, CSS, WAI, and RSS web feed links.
- Display image dimensions, file sizes, path information, and alternate (ALT) text.
- Immediately resize the browser window to a new resolution.
- Selectively clear the browser cache and saved cookies. Choose from all objects or those associated with a given domain.
- Display a fully featured design ruler to help accurately align and measure objects on your pages.
- Find the style rules used to set specific style values on an element.
- View the formatted and syntax colored source of HTML and CSS.
The Developer Toolbar can be pinned to the Internet Explorer browser window or floated separately.
This toolbar isn't a match for the features, look, or usability of FireBug...but it is a great start and a pretty decent tool provided by the guys at Microsoft. As many developers can attest, developing sites that work according to standards AND Internet Explorer is a pain...this tool eases that pain.
Oh, and once you install the toolbar, it is hard to see where to open the thing. After installing, a little blue arror will appear in the icon bar at the top of the browser. Click that and the tool will open at the bottom of the screen.
Book Review: Learning jQuery
August 6, 2007 | 2 Comments
I'm a huge fan and avid user of jQuery and have been extremely impressed by the documentation provided on the jQuery website. The one thing that documentation lacks, however, is really contextual examples that drive home some bare essentials of JavaScripting with the jQuery library. Learning jQuery - a book by Jonathan Chaffer and Karl Swedberg - is an excellent introductory book for those that are thinking about using (or struggling with) jQuery.
jQuery, while a fairly high level JavaScript library is a beautiful thing but can be very daunting to a developer that is new to JavaScripting or is coming from a dissimilar library, being thrust full bore into a 'new' way of doing old tricks. (Which jQuery is great at by the way...it makes the new ways super sexy, sleek, and easy). The authors do a great job of explaining what jQuery is and why it is such a powerful tool.
Throughout the book are examples on traversing and manipulating the DOM, event handling, leveraging jQuery's JS effect capabilities, AJAX, etc; many of which are built off of previously detailed examples, allowing the reader to easily grasp what is going on and why a chunk of code was used.
While I feel this book is primarily an excellent introductory source for diving into the world of JavaScript development with jQuery, the fairly seasoned jQuery user (like myself) may find a trick or two that they hadn't quite thought of... As I read through, I found a few choice bits that allowed me to make my own code more efficient!
My only real complaint with the book is the index at the back. There are a number of jQuery functions that are discussed within the chapters yet weren't referenced in the index. A small nitpick, I know, but I'm a sucker for a good index :)
So. Overall, I think the book is a good thing to keep on the bookshelf, whether a you are a jQuery n00b or not. There's always a co-worker/friend/programming buddy that will want to learn jQuery and what better way to get them rolling on there own than a link to the jQuery docs and a sweet book?
You can get the book here.






















