<?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>Pro Bono Geek &#187; Technology</title>
	<atom:link href="http://blog.probonogeek.org/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.probonogeek.org</link>
	<description>Technology for the Good of People</description>
	<lastBuildDate>Tue, 06 Dec 2011 10:00:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>On the Predicted Death of the PC, the Game Console, and Scripting Languages</title>
		<link>http://blog.probonogeek.org/2011/12/on-the-predicted-death-of-the-pc-the-game-console-and-scripting-languages/</link>
		<comments>http://blog.probonogeek.org/2011/12/on-the-predicted-death-of-the-pc-the-game-console-and-scripting-languages/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 02:10:39 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=862</guid>
		<description><![CDATA[In 2011 I have heard predicted the death of the PC, of gaming consoles, and scripting languages so often that the claim hardly seems shocking anymore. The cottage industry of making bold predictions has gotten so big that in order to make any true waves you need to predict increasingly more outrageous outcomes and just [...]]]></description>
			<content:encoded><![CDATA[<p>In 2011 I have heard predicted the death of the PC, of gaming consoles, and scripting languages so often that the claim hardly seems shocking anymore. The cottage industry of making <i>bold</i> predictions has gotten so big that in order to make any true waves you need to predict increasingly more outrageous outcomes and just hope you strike it lucky often enough that no one notices all the times you get it wrong. But the three predictions above strike a little too close to home for me to not take notice. The death of the PC, the gaming console, and scripting languages would essentially mean the death of my knowledge and interest in technology.<span id="more-862"></span></p>
<p>I admit, for all my technical knowledge, among other developers I&#8217;m a bit of a luddite. I&#8217;ve never owned a game console <i>not</i> made by Nintendo, I run Linux on all of my computers, and my first scripting language was Perl, which I only reluctantly gave up for Ruby a couple of years ago. I&#8217;ve not drawn to buy the latest PlayStation, or keep up with the latest desktop PC, or to the <i>hawt</i> new computer language that lets you run your software on 32 cores with only four lines of code. I think the reason is that my attraction to these technologies was never their newness or their cool factor, it was that they were good solutions to problems I wanted to solve. Those problems still exist today, and I argue that while there may be new technologies out there that solve other problems better, they don&#8217;t solve the original problems in a way that poses a serious challenge.</p>
<h3>Gaming: A Search for Experience</h3>
<p>The easiest one to debunk is the coming death of gaming consoles. In a <a href="http://www.industrygamers.com/news/game-industry-legends-richard-garriott-de-cayeux/">recent interview</a> Richard Garriott, the man behind the <i>Ultima</i> franchise, is reported to have said the following when asked about gaming consoles:</p>
<blockquote><p>I think we might get one more generation, might, but I think fundamentally they&#8217;re doomed. I think fundamentally the power that you can carry with you in a portable is really swamping what we&#8217;ve thought of as a console.</p></blockquote>
<p>And, of course, he&#8217;s right about the power of my mobile device. It&#8217;s clearly got more power than my old Nintendo or SNES ever had, and I imagine it&#8217;s probably more powerful than my current (but aging) generation console, the Wii. Where I don&#8217;t agree is with the claim that it&#8217;s <i>swamping</i> anything. My phone&#8217;s great and all, but it&#8217;s never going to replace a game console for me. What makes game consoles great is they leverage my existing investments. Hanging on my wall right now is a big TV, surrounded by comfy couches, and hooked into a 5.1 surround sound system. Today I can go and buy a Wii, a PS3, and an XBOX 360 and all will hook neatly into my existing infrastructure. What&#8217;s my phone got that will ever compete with that? Controls that are difficult to use because they have to exist on a flat surface? A screen that is tiny by <i>design</i>? Battery life that can be reasonably measured in minutes when under active load? A network connection that is a faction of my home connection?</p>
<p>Which isn&#8217;t to say that the mobile device won&#8217;t be a successful gaming platform! Far from it. Publishers that crack the nut of good mobile gaming are going to make bucket-loads of money tapping into a market that has been historical averse to video games. More power to &#8216;em, I say! But they are trying to solve a <b>new</b> problem: how to attract new non-gaming customers? But see, that&#8217;s a problem that game publishers have&#8230; it is not a problem <i>I</i> have, or the million of other gamers who grew the gaming industry into a billion dollar juggernaut. Our problem remains the same: how do I play immersive games that best leverage the technology I already own? I don&#8217;t want my new 40&#8243; TV to sit idle while I squint at my phone, and I don&#8217;t think anyone playing games for the past 20 years wants to either. It&#8217;s silly to let such a resource lay fallow. Game consoles solve that problem and do so incredibly well, while giving me customized controllers, fast internet, and a wired power source. If someday the mobile device is created that lets me do all those things, I would suggest that game consoles won&#8217;t have been killed by mobile devices, so much as mobile devices <i>became</i> game consoles.</p>
<h3>Personal Computers: &#8220;It&#8217;s not in the box, it&#8217;s in the band&#8221;</h3>
<p>Thirty points if you identified the above quote as coming from <i><a href="http://www.imdb.com/title/tt0218817/">Antitrust</a></i> a highly-decent film about an evil software company who is literally killing its young competitors. There&#8217;s a moment in the film where the Bill Gates-esque figure (played by Tim Robbins) turns to the young protagonist (played by Ryan Phillippe) and mutters the above line. This brilliant phrase allows them to overcome some roadblock with the development of Nurv, their amazing new content delivery system that will revolutionize the world. Ahead of its time, <i>Antitrust</i> seems to be making a cloud computing comment way back in 2001&#8230; that the solution to their problem wasn&#8217;t with the devices, but the network that connected those devices.</p>
<p>Sadly, in today&#8217;s world of technology predictions, the ability to differentiate between those two concepts seems rarer and rarer. On more than one occasion I&#8217;ve heard it declared that the age of the Personal Computer is over. As evidence, the prognosticator points to Cloud Computing as PC computing&#8217;s angle of death. I can only assume these people just don&#8217;t understand what Cloud Computing even means when they say such things.</p>
<p>Let&#8217;s start with the stipulation that Cloud Computing is a poorly defined term, and it <i>can</i> mean all things to all people. But given that, it still have a reasonable well accepted definition for 2011&#8230; it is the process of moving computer resources from <b>specific</b> nodes on the resource graph to <b>arbitrary</b> nodes. </p>
<p><i>Say what?!</i></p>
<p>Perhaps an example will help. Consider a media server that stores gigabytes of media files which can be accessed by various client computers. In this example, the resource is <b>storage</b>, because we are talking about the data that comprises these media files. But contrary to what you might have heard, a media server isn&#8217;t cloud computing! The relationship I described has been around since we had networks&#8230; it&#8217;s the standard server/client model where there are discrete resources on specific nodes. What <i>would</i> make this cloud computing is if instead of a single server, there were lots of servers all working together to store the music, but that the client was unaware of this arrangement. The client connects to the &#8220;cloud&#8221; and just gets the media files like it always has, while the servers work to move the files around ensuring prompt delivery. <i>Now</i> we&#8217;ve come to the cloud.</p>
<p>Something should jump out at you about this example&#8230; the <i>client</i> didn&#8217;t change! And the client in this case is the supposedly dying PC! You see, we still need a specific client to connect to our clouds. Whether we are talking about huge CPU clusters or massive petabyte data arrays, we need clients to make use of these non-fixed resources. To give another example, I often hear it claimed that gmail revolutionized email. And yes, it gave us a radically new user interface, but it didn&#8217;t change anything when it came to the storage and delivery of email. The idea of email residing on a server that is universally available has been around since the invention of <a href="http://en.wikipedia.org/wiki/Internet_Message_Access_Protocol">IMAP</a> in 1986. </p>
<p>Perhaps the doomsayers of the PC era aren&#8217;t talking about the cloud so much as they are talking about the different nature of devices that will be able to connect to the cloud. Today I can access my email from my phone, my tablet, and no doubt, someday, my refrigerator. Which is great, I&#8217;m all for more options when it comes to data consumption. But the assumption that these devices are going to <i>kill</i> the PC makes the same mistake as the gaming console. If you don&#8217;t start by looking at the <i>problem</i> PCs were invented to address, you&#8217;ll never understand what it will take to replace the PC.</p>
<p>I propose the PC was invented to give us a way to use computer resources in a <i>productive</i> manner. It follows that to end the PC era, we need to invent a device (or set of devices) that is more productive than the PC. Of course, this doesn&#8217;t answer the question of what is <i>productive</i>. That&#8217;s going to be a personal evaluation, but I think we can all agree that <i>communicating</i> is a productive task. So, let&#8217;s take communicating and evaluate it in the context of the PC and the smartphone.</p>
<p>The smartphone has some incredible advantages, not least of which is that its mobile. But in addition to a mobile network connection, smartphones <i>are</i> phones, and thus are ready for voice communication right out of the box. They also increasingly equipped with video cameras, opening the possibility for video communication. So, it&#8217;s got mobility, it&#8217;s got voice, and it&#8217;s got video. All great stuff&#8230; but I&#8217;m not the least bit worried about it replacing the PC as the primary form of communication. Contrary to what Star Trek may have lead us to believe, video and audio communication poses few threats to text based forms of communication. The problem with audio and video is it&#8217;s all <i>single</i> band. For demonstration, I encourage you and your significant other to break out your smart phones in the same room and start video chatting, simultaneously, with your respective families. Let me know how it turns out. Now, try writing an email to your parents at the same time&#8230; easier, right? You can both do it at the same time, because text doesn&#8217;t collide with others engaging in the same activity.</p>
<p>Sure, smart phones and tablets do text, but nothing beats a QWERTY keyboard when it comes to text input. The PC form factor provides unrivaled means of <i>creating</i> content. Whether it&#8217;s writing text, editing a spreadsheet or cutting up a Photoshop document, the mouse/keyboard/monitor are the gold standard. Sure, you can hook up a tablet to those same input devices, but at what point have you just built a PC in a crazy slim form factor?</p>
<p>In the end, these new devices provide exceptionable mobility, and that&#8217;s a powerful answer to the problem: how can I be productive when I&#8217;m mobile? But when put to the question, how can I maximize the productivity of my computing resources, it&#8217;s gonna fall short. But to those who insist they can ditch their PCs entirely&#8230; I say, <i>bring it on</i>! I&#8217;m all too happy to have the  advantage.</p>
<h3>Scripting Languages: Putting Text on a Screen</h3>
<p>This last item hits closest to home, because I spend most of my professional day writing in one of a handful of scripting languages, so I get a bit defensive whenever someone says I&#8217;m coding in the past. The broad claim here is that content delivery has evolved over the year from static documents, like raw HTML, to dynamic documents powered by a combination of server and client side scripting languages, and that another transformation is coming. Instead of dynamic documents, we are going to be <i>streaming</i> documents&#8230; data&#8230; media? Actually, it&#8217;s not entirely clear what we are going to be streaming, but whatever it is, it&#8217;ll come in stream format. As proof of the assertion, the doomsayers point to <a href="http://nodejs.org/">nodeJS</a>, the revolutionary javascript server.</p>
<p>I lucked out last year and saw a nodeJS demo by its developer at SenchaCon and was admittedly blown away but how awesome it was. There&#8217;s no doubt about it, you can do stuff with nodeJS that is harder to do in more traditional languages, and its introducing a whole new generation of developers to the world of functional programming. But it&#8217;s <b>not</b> new. Functional programming has been around since the 1950s with the development of Lisp. It&#8217;s a crazy powerful, yet mind-boggling, technology. Wrapping it up into a server isn&#8217;t really new either, as I understand it. The big plus with nodeJS is that language is Javascript, not some parenthesis laden jumble, and thus modern web developers can jump in with their existing knowledge.</p>
<p>But what about NodeJS suggests the death of scripting languages? For that matter, what about scripting languages suggested the death of static documents? Like before, it all goes back to the nature of the problem needing to be solved. With static documents, we were trying to get information out to the client as quickly and as reliably as possible. Static HTML answered that problem brilliantly (more so than I think anyone expected at the time). With dynamic pages, we had two objectives: (1) allow a page to be built through the combination of a smaller discrete parts; and (2) the customization of content based on the user&#8217;s input or environment. But here&#8217;s the rub&#8230; the best web applications still work with static HTML as much as possible. Caching pre-rendered objects, or whole pages, is essential to any application that is going to deal with significant load. So it&#8217;s not that scripting killed static pages, it&#8217;s that it enhanced what we could do with it. But a developer who doesn&#8217;t learn the basics of serving static content does so at his or her own peril.</p>
<p>So, does NodeJS allow us to solve either of the problems that static or dynamic documents solve? I suppose you can use NodeJS <i>as</i> a dynamic document generator. But, that&#8217;s not really it&#8217;s strong suit as I understand it. It&#8217;s power is the ability to handle multiple concurrent users and allow them to exchange information. Which, like I said, is awesome. But it doesn&#8217;t mean we won&#8217;t need to serve static pages in the future.</p>
<h3>Overstating Death</h3>
<p>In part, I realize, I&#8217;ve fallen victim to the prognosticators&#8217; bombastic claim. To get press, they seem to need to say more and more outrageous things. No one bothers to print the headline that says &#8220;Technology gets incrementally better, most things remain the same.&#8221; I worry that too many developers get educated in a world of over-hyped expectations and a thirst for the bleeding edge. This obsession strikes me as dangerous. The point of technology, from a societal standpoint, is to help us solve problems. Being <i>shiny</i> isn&#8217;t a good enough reason to discard what came before. If all of the current developers are dancing on the graves of old technology, how will we effectively evaluate it against the latest and greatest?</p>
<p>The next time you read an article that says HTML5 will <i>end the way we think of webpages</i> or that your smartphone is going to replace your tax accountant, stop and ask yourself: what is the problem trying to be solved here, and does this new technology solve it in a way that totally displaces the previous solution, or does it just solve a particular part of the problem in a new way? My personal experience is that, in most cases, technology is rarely revolutionary&#8230; and when it is revolutionary, no one sees it coming until it&#8217;s already here.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2011/12/on-the-predicted-death-of-the-pc-the-game-console-and-scripting-languages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Amazing Graphic Accomplishment</title>
		<link>http://blog.probonogeek.org/2010/12/my-amazing-graphic-accomplishment/</link>
		<comments>http://blog.probonogeek.org/2010/12/my-amazing-graphic-accomplishment/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 21:17:02 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=759</guid>
		<description><![CDATA[Let&#8217;s start this off by saying that I am a bad artist with zero sense of graphic design. When talking to clients about development projects they inevitably ask me a design question, to which I respond &#8220;I&#8217;ll pull in a designer to answer that question, because believe me: you don&#8217;t want my design advice. If [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s start this off by saying that I am a bad artist with zero sense of graphic design. When talking to clients about development projects they inevitably ask me a design question, to which I respond &#8220;I&#8217;ll pull in a designer to answer that question, because believe me: you don&#8217;t want my design advice. If I designed our sites, everything would be in black and white.&#8221; Usually worth a good laugh out of the client and helps set the expectations &#8212; Sean != Designer.</p>
<p>But, this holiday season I found myself in need of a specific icon for a project I&#8217;m working on, and the design staff is either slammed or on a well earned vacation, so what&#8217;s an enterprising developer to do? Role up his sleeves and get dirty with a graphics application, that&#8217;s what! And my success was so complete, I couldn&#8217;t help but share in the wonder.<span id="more-759"></span></p>
<p>What you&#8217;re about to see was all done using The GIMP, but no reason this couldn&#8217;t be done in Photoshop or really any program that supports layers and opacity. With that, let&#8217;s get started.</p>
<h3>The Need</h2>
<p>The application I&#8217;m building makes use of a great set of <a href="http://www.famfamfam.com/lab/icons/silk/">freely available icons</a>, which I also use on this blog. Included in that 1000+ icon package are a set of folder icons depicting different types of folders. Some with filetypes, some with pictures, almost anything you could want inside of a folder is represented. Except for &#8220;groups&#8221;. There&#8217;s a whole set of group icons, but no icon for a group folder.</p>
<h3>The Building Blocks</h2>
<p>Which isn&#8217;t to say I started from nothing. As I mention, there were group icons, like the plain group.png:</p>
<div id="attachment_760" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/group.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/group.png" alt="" title="group.png" width="348" height="290" class="aligncenter size-full wp-image-760" /></a><p class="wp-caption-text">group.png</p></div>
<p>I also have the plain folder.png:</p>
<div id="attachment_761" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder.png" alt="" title="folder.png" width="348" height="290" class="aligncenter size-medium wp-image-761" /></a><p class="wp-caption-text">folder.png</p></div>
<p>And as a reference I have the folder_user.png, which is essentially where I want to end up, but with the group icon instead of the user icon.</p>
<div id="attachment_768" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_user.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_user.png" alt="" title="folder_user.png" width="348" height="290" class="size-full wp-image-768" /></a><p class="wp-caption-text">folder_user.png</p></div>
<p>And lastly, I have the user.png icon itself:</p>
<div id="attachment_769" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/user.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/user.png" alt="" title="user.png" width="348" height="290" class="aligncenter size-full wp-image-769" /></a><p class="wp-caption-text">user.png</p></div>
<h3>Step #1: Resize and Positioning</h3>
<p>First I took the original folder.png and moved the folder icon into the bottom-left corner, as all the other folder icons looked:</p>
<div id="attachment_762" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group1.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group1.png" alt="" title="Step #1 - Folder Positioning" width="348" height="290" class="size-full wp-image-762" /></a><p class="wp-caption-text">Step #1 - Folder Positioning</p></div>
<p>Next I determined that the person in the folder_user.png was only 12 x 12 pixels, while the original user.png was 16 x 16. So I resized group.png to 12 x 12 and then pasted it as a new layer into my work space. I moved it into the upper-right corner, where it would eventually need to be, so that layer looked like this:</p>
<div id="attachment_763" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group2.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group2.png" alt="" title="Step #1 - Group Positioning" width="348" height="290" class="size-full wp-image-763" /></a><p class="wp-caption-text">Step #1 - Group Positioning</p></div>
<p>When both layers were made visible, I had the general layout of the final icon:</p>
<div id="attachment_764" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group3.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group3.png" alt="" title="Step #1 - Final Positioning" width="348" height="290" class="size-full wp-image-764" /></a><p class="wp-caption-text">Step #1 - Final Positioning</p></div>
<h3>Step #2: Overlap</h3>
<p>The astute viewer will notice that on the reference folder_user.png icon, the person appears inside of the folder, such that the front flap of the folder is in front of the person graphic. At first I thought I was done for&#8230; how was I going to recreate the folder flap <i>in front</i> of the group layer? This is when the true genius struck (at least, for me, as a non-designer!). I copied the section of the folder that is the front flap and create a new layer with just those pixels, like this:</p>
<div id="attachment_765" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group4.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group4.png" alt="" title="Step #2 -- The Flap Layer" width="348" height="290" class="size-full wp-image-765" /></a><p class="wp-caption-text">Step #2 -- The Flap Layer</p></div>
<p>Which I then positioned above the other two layers. With visibility turned on for all three layers, we now get a much closer to our final goal:</p>
<div id="attachment_766" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group5.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group5.png" alt="" title="Step #2: With the Flap" width="348" height="290" class="size-full wp-image-766" /></a><p class="wp-caption-text">Step #2: With the Flap</p></div>
<h3>Step #3: Opacity</h3>
<p>After a quick self-congratulatory dance, I realized this icon wasn&#8217;t quite right. If you take a look at the reference icon again, you&#8217;ll see that the person graphic isn&#8217;t quite fully covered by the flap. It&#8217;s more that the part of the person that is covered is faded&#8230; like, the flap itself is partially transparent. The physics of transparent folder flaps aside, I was determined to get an icon that would match the set, so I set about trying to get this last detail just right.</p>
<p>It was then that I realized I could simply turn down the opacity of the flap layer. With only 75% opacity, I ended up with a layer that looked like this:</p>
<div id="attachment_779" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group6.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group6.png" alt="" title="Step #3 -- Flap with Decreased Opacity" width="348" height="290" class="size-full wp-image-779" /></a><p class="wp-caption-text">Step #3 -- Flap with Decreased Opacity</p></div>
<p>Because I had only copied the clap to a new layer, not <i>cut</i> the flap, there was an exact copy of the flap behind the top-most flap layer. By turning down the opacity on the flap layer, the group graphic was able to show through a bit as well as the identical full-opacity flap immediately behind. This way the background itself didn&#8217;t show through (which would have resulted in blue showing through when the icon was embedded in the webapp). Here&#8217;s what the semi-transparent flap looks like with a blue background without the the identical full opacity version behind it:</p>
<div id="attachment_780" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group7.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group7.png" alt="" title="Step #3 -- Transparency without Full Opacity Backing" width="348" height="290" class="size-full wp-image-780" /></a><p class="wp-caption-text">Step #3 -- Transparency without Full Opacity Backing</p></div>
<p>So, when we combine it all together, we have the the semi-transparent flap as the top layer, the resized group graphic as the second layer, and the full-opacity folder as the third layer, which gives us the finalized folder_group.png:</p>
<div id="attachment_767" class="wp-caption aligncenter" style="width: 358px"><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group_final.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group_final.png" alt="" title="folder_group.png" width="348" height="290" class="size-full wp-image-767" /></a><p class="wp-caption-text">folder_group.png</p></div>
<p>All the above graphics have been at 800% size, so here is the original reference user.png and group.png side-by-side, and then the reference folder_user.png side-by-side with my new folder_group.png.</p>
<p><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/user1.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/user1.png" alt="" title="user.png" width="16" height="16" class="alignnone size-full wp-image-787" /></a>&nbsp;&nbsp;<a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/group1.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/group1.png" alt="" title="group.png" width="16" height="16" class="alignnone size-full wp-image-788" /></a></p>
<p><a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_user1.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_user1.png" alt="" title="folder_user.png" width="16" height="16" class="alignnone size-full wp-image-784" /></a>&nbsp;&nbsp;<a href="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group.png"><img src="http://blog.probonogeek.org/wp-content/uploads/2010/12/folder_group.png" alt="" title="folder_group.png" width="16" height="16" class="alignnone size-full wp-image-783" /></a></p>
<p>I think I&#8217;m going to apply for a job as a designer now.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2010/12/my-amazing-graphic-accomplishment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FCC and Network Neutrality</title>
		<link>http://blog.probonogeek.org/2010/04/fcc-and-network-neutrality/</link>
		<comments>http://blog.probonogeek.org/2010/04/fcc-and-network-neutrality/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 10:20:33 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=672</guid>
		<description><![CDATA[This is a test.]]></description>
			<content:encoded><![CDATA[<p>Some months ago the FCC &#8212; now with a majority of Democratic commissioners &#8212; implemented network neutrality rules using it&#8217;s &#8220;ancillary&#8221; regulatory powers. I&#8217;m on record as a proponent of network neutrality, taking the general position that the internet should be treated like a common carrier and/or utility, and that the only thing providers should be in the business of is delivering reliable and fast service. The moment providers become content filters is the moment their interests stop being aligned with the general good. Think of it like a road builder who also sold cars&#8230; don&#8217;t you think you&#8217;d build your roads to benefit <i>your</i> cars? After a failed effort to enact a network neutrality statute in Congress, the FCC stepped in, however a <a href="http://www.msnbc.msn.com/id/36193558/ns/technology_and_science-security/">Federal Court has struck down the regulation</a> taking us back at square one. But don&#8217;t worry, that&#8217;s a good thing.<span id="more-672"></span></p>
<p>You might be wondering how the overturning of a policy I support is a good thing, and the simple answer is <i>process matters</i>. The process matters because not all law is of equal value, and this particular regulation wasn&#8217;t the sort of foundation upon which you would want to build a free internet. To understand what I&#8217;m driving at, you need a basic understanding of the interplay between Congress, regulatory agencies like the FCC, and the Courts. Here&#8217;s a quick set of principles</p>
<ul>
<li><b>Congress doesn&#8217;t act unless it needs to</b> &#8212; This is generally true in all areas, but especially true in technology policy. Congress, for all its many faults, recognizes it&#8217;s the least good way of getting things done. It lacks expertise and is highly susceptible to outside interests whose goals are not always aligned with the public. As such, there are numerous mechanisms in Congress to ensure only a small fraction of bills get approved, even if they have majority support.</li>
<li><b>Regulatory agencies are expected to pick up the slack</b> &#8212; Congress can sit on its hands because it has already setup numerous agencies to make the sorts of expert technical decisions Congress is not so good at. For example, the recent health care reform bill, while very long, will pale in comparison to the length of the regulations that will eventually be written to implement the same. Those regulations will largely come from the Department of Health and Human Services. When flaws are found in the original bill, it won&#8217;t be Congress that tries to fix it, it will be DHHS using its regulatory power.</li>
<li><b>Courts act as a check against undemocratic law making</b> &#8212; Yes, for all you may have heard from conservatives about courts being undemocratic, it is their responsibility to ensure regulators do not overstep the authority granted to them by Congress. This is a challenging but critical task. Regulators are under heavy pressure from advocates, legislators, and the President to push the bounds of their authority to avoid spending political capital on enacting a statute. It is the Courts job to ensure that this doesn&#8217;t get out of hand.</li>
</ul>
<p>The interplay between these three forces is subtle and complex, and I don&#8217;t claim to be anywhere close to an expert. But what I can speculate is that when network neutrality failed in the last Congress it was in <i>part</i> because would-be supporters didn&#8217;t feel the issue was sufficiently ripe. Why cast a potentially difficult vote when you can have the FCC do your dirty work for you? Now that the courts have ruled that the FCC lacks sufficient authority, the issue goes back to Congress where we can finally get a good sense of just what kind of political support exists.</p>
<p>In the meantime, the court&#8217;s decision tells us something else important: the FCC lacks authority to regulate the internet in whatever manner it sees fit. As anyone in the TV business will tell you, that&#8217;s probably a good thing from a content perspective, least we end up with such delightful concepts as <a href="http://www.fcc.gov/cgb/consumerfacts/obscene.html">&#8220;community standards&#8221;</a> being forced upon us all. With clear limits on the FCC&#8217;s ancillary regulatory powers over the internet, Congress can now draft specific authority for the purposes of network neutrality while avoiding the pitfalls of creating a overbearing internet regulator, but also ensure a durable and lasting legislative framework for a free and open internet.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2010/04/fcc-and-network-neutrality/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cool New Media Health Care Advocacy</title>
		<link>http://blog.probonogeek.org/2009/10/cool-new-media-health-care-advocacy/</link>
		<comments>http://blog.probonogeek.org/2009/10/cool-new-media-health-care-advocacy/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 06:53:34 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=600</guid>
		<description><![CDATA[Yesterday a tool I built for Service Employees International Union went live at http://ticket.seiu.org. The SEIU folks came up with a pretty good idea to take advantage of the Facebook and Twitter status update phenomenon. Instead of pushing out an identical message for supporters to publish, they created a unique number for each visitor and [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday a tool I built for Service Employees International Union went live at <a href="http://ticket.seiu.org">http://ticket.seiu.org</a>. The SEIU folks came up with a pretty good idea to take advantage of the Facebook and Twitter status update phenomenon. Instead of pushing out an identical message for supporters to publish, they created a unique number for each visitor and embedded that into the update message about gender discrimination in health care. This way visitors could easily see what number their friend was&#8230; with hopes that folks would rush to sign up and get the next number. We also generated a unique image with their number for each visitor for use with Facebook via the power of GD. After the first day we hit nearly 5000 tickets &#8220;taken&#8221;&#8230; don&#8217;t really know if that&#8217;s good or not, but the concept was pretty nifty. The campaign even got a <a href="http://techpresident.com/blog-entry/twitter-ads-daily-kos-seius-new-health-care-campaign">write up in TechPresident</a>.</p>
<p>Then, unrelated to anything I did, MoveOn released this really great video on the Public Option.</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/bvaJYYeXf70&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bvaJYYeXf70&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
<p>That may be the single best <i>piece</i> I&#8217;ve seen on the topic.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/10/cool-new-media-health-care-advocacy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExtJS Git Submodule</title>
		<link>http://blog.probonogeek.org/2009/04/extjs-git-submodule/</link>
		<comments>http://blog.probonogeek.org/2009/04/extjs-git-submodule/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 00:36:58 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=573</guid>
		<description><![CDATA[I know it&#8217;s been a while since I last posted about ExtJS&#8230; things have been quite busy at work and I&#8217;ve forced myself to take a sabbatical from the project that has me working with ExtJS everyday. I&#8217;ll get back to it soon, don&#8217;t worry, and I have lots of topics in the queue. In [...]]]></description>
			<content:encoded><![CDATA[<p>I know it&#8217;s been a while since I last posted about ExtJS&#8230; things have been quite busy at work and I&#8217;ve forced myself to take a sabbatical from the project that has me working with ExtJS everyday. I&#8217;ll get back to it soon, don&#8217;t worry, and I have lots of topics in the queue. In the meantime, I have a bit of a public service announcement for those who use ExtJS with git.<span id="more-573"></span></p>
<p>If you&#8217;re not familiar with <a href="http://git-scm.com/">git</a> as a version control system, I encourage you to check it out. I came from Subversion, which was great&#8230; but, at least for me, git is better. Better yet, if you use git with open source projects, you can use <a href="http://github.com">github.com</a> for free to host your code, which is pretty cool, and self-hosting isn&#8217;t very challenging either. One of the aspects of git I&#8217;m just coming to understand is <a href='http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html'>git-submodule</a>. The idea is that there is an external project you&#8217;d like to pull into your project, but instead of committing it to your own repository, you want to use the external project&#8217;s repository. Lots of reasons to want to do this, such as making it easier to track upstream changes, or reducing the size of your own repository.</p>
<p>Ever since I learned about git submodules, I&#8217;ve thought that ExtJS seemed like a perfect candidate. As there is a mechanism to change the library at runtime without changing the code on the file system, there&#8217;s very little reason to have the library in your own repository. On top of which, ExtJS is <i>big</i>, so why waste the space. Sadly, the fine folks at extjs.com do not provide ExtJS in git form. There is a subversion repository for commercial clients (of which my employer is) but subversion is not git.</p>
<p>Thus, I have decided to take matters into my own hands. As ExtJS is licensed under the GPL, I have the legal right to redistribute the code. So I created my own <a href="http://github.com/probonogeek/extjs/tree/master">git repository just for ExtJS</a> at github which anyone can use as to add ExtJS as a git submodule. I&#8217;m still trying to figure out some aspects of git-submodule&#8230; like, is it possible to specify a tag from the external repo? If so, I will start adding tags to the repository as new versions are released.</p>
<p>For those who want to jump right into using the repo, here&#8217;s the magical incantation you want to run from your project root (change the &#8220;public/extjs&#8221; part to the relative path you want to install ExtJS at):</p>
<pre class="brush: shell">
git submodule add git://github.com/probonogeek/extjs.git public/extjs
git submodule init
git submodule update
</pre>
<p>Lastly, if there are any extjs.com folks reading this who object to what I&#8217;ve done, please don&#8217;t hesitate to contact me. While the GPL gives me permission to do as I&#8217;ve done, there is a big difference between legal right and community consent. Right now I&#8217;m operating on a sort of tacit consent, but will take the repository down if requested.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/04/extjs-git-submodule/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>KDE4: Retry</title>
		<link>http://blog.probonogeek.org/2009/04/kde4-retry/</link>
		<comments>http://blog.probonogeek.org/2009/04/kde4-retry/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 19:56:36 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=567</guid>
		<description><![CDATA[Several months ago I made a good faith attempt to upgrade my laptop from the reliable KDE3 to the avant-guard KDE4. Having decided not to even dabble with KDE 4.0 and the growing-pains associated with that particular release, I had high hopes for the venerable desktop environment&#8217;s 4.1 release. Sadly, the experiment ended in disaster, [...]]]></description>
			<content:encoded><![CDATA[<p>Several months ago I made a good faith attempt to upgrade my laptop from the reliable KDE3 to the avant-guard KDE4. Having decided not to even dabble with KDE 4.0 and the growing-pains associated with that particular release, I had high hopes for the venerable desktop environment&#8217;s 4.1 release. Sadly, the experiment ended in disaster, with too many crashes, too much slowness, and too many missing features that &#8212; at least for my work flow &#8212; were critical. I thus reverted back to KDE3 and went about my business.<span id="more-567"></span></p>
<p>However, with the release of Debian/Lenny, Debian/Unstable has seen a flood of new packages including the transition from KDE3 -> KDE4, meaning it was simply no longer an option to avoid KDE4. Sure, I could have switched off of Debian/Unstable, but I&#8217;m just not that kind of guy. But I had hopes to delay the inevitable as long as possible.</p>
<p>This morning I could delay no further&#8230; too many packages were getting held up and it was time to bite the bullet. To my great pleasure, the upgrade has proven a much more enjoyable experience than last time. Instead of KDE 4.1, Debian/Unstable now runs with KDE 4.2.2 and it is just <i>so</i> much better.</p>
<p>Lots of GUI related stuff has cleaned up, applications work like I remember <i>or</i> have alternative mechanisms that I&#8217;m willing to learn, and generally things seem faster. I decided to turn off all of the eye-candy, as my laptop isn&#8217;t quite as powerful as one might want. But general CPU use is low enough that the fan doesn&#8217;t turn on, unlike the first attempt where it ran non-stop. Perhaps the most important feature enhancement is the introduction of a 12 hour clock! Not that I don&#8217;t appreciate 24-hour clocks, but my head just doesn&#8217;t work that way and I am otherwise surrounded by 12 hour clocks&#8230; it simply wasn&#8217;t practical to retrain <i>and</i> switch back-and-forth.</p>
<p>I think my only lasting critique is that KDE 4 was designed for big monitors. Everything seems to take up just a little bit more screen real estate that it used to, which makes a big difference on my tiny laptop monitor (only 14 inches, I think&#8230;). The appearance is much more in keeping with Web 2.0 design philosophy, which I generally like quite a bit, but on tiny monitors presents certain challenges. My guess is it will look gorgeous when I try it out my desktop&#8217;s 19 inch monitor.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/04/kde4-retry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Preparing Your ExtJS Environment</title>
		<link>http://blog.probonogeek.org/2009/04/preparing-your-extjs-environment/</link>
		<comments>http://blog.probonogeek.org/2009/04/preparing-your-extjs-environment/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 03:24:32 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=406</guid>
		<description><![CDATA[In my last post I said that ExtJS is a front-end widget system. No doubt you could use it to create an entire system, front to back, in nothing by ExtJS, but that&#8217;s not my project nor is what I plan to talk about in these posts. Which brings us to the first question you [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post I said that ExtJS is a front-end widget system. No doubt you could use it to create an entire system, front to back, in nothing by ExtJS, but that&#8217;s not my project nor is what I plan to talk about in these posts. Which brings us to the first question you need to answer when setting up your ExtJS environment: what am I going to use as a back-end? There are probably lots of <i>right</i> answers to this question, and a great deal of debate over which one is <i>more</i> right, and I gleefully leave that fight for others. For my purposes, the answer to that question is <a href="">merb</a> (it&#8217;s like rails, but better), so if that&#8217;s not your platform of choice, you will have to make some adaptations of your own.<span id="more-406"></span></p>
<p>First things first, setup your application by whatever magical incantation is appropriate, in my case:</p>
<pre class="brush: shell">
merb-gen app extjs_demo
</pre>
<p>Now we have a clean application all ready to go. Next you need to bring ExtJS into your codebase so you will have access to it. As ExtJS is 99% javascript, you will want to install in whatever directory your app will use as its document_root so that HTTP requests can get at it. In merb/rails, that directory is called public/. I recommend against using public/javascripts/, even though it&#8217;s <i>right there</i> calling out for javascript files. The way I see it, ExtJS is an external library, while public/javascripts/ is where you put your own application scripts, but reasonable minds can disagree.</p>
<p>Head on over to <a href="http://extjs.com/products/extjs/download.php">extjs.com</a> and grab the latests release (2.2.1 as of this writing). Pay attention here&#8230; you want to unzip the file in its own directory named extjs-2.2.1 (or whatever version you downloaded). If you unzip the file directly into public/, you&#8217;re going to be sorry. Now create a symlink pointing to extjs-2.2.1 called &#8220;extjs&#8221;. </p>
<pre class="brush: shell">
ln -s extjs-2.2.1 extjs
</pre>
<p>This symlinking strategy allows you to easily try out new releases of ExtJS and revert back without having to worry about blowing away old versions until you are ready.</p>
<p>Now you have ExtJS installed and can already do a great deal if you were to startup your empty app <i>right this very second</i> and access http://localhost:4000/extjs/docs/index.html with your trusty browser. Your framework may use a different port number (Rails defaults to 3000). With merb properly installed on my system, I can just startup the app from the merb root directory by running:</p>
<pre class="brush: shell">
bin/merb
</pre>
<p>Your browser should show you the API docs just as if you had accessed them on the <a href="http://www.extjs.com/deploy/dev/docs/">ExtJS website</a>. This is going to be your number one place to learn the finner points of ExtJS, and now you have it with you so long as you have your application&#8217;s source. Handy for those times you don&#8217;t have internet access. If you&#8217;re using source control, now is a good time to commit <img src='http://blog.probonogeek.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Next we face an important choice. As we build our application we are going to define different ExtJS subclasses (more on what that means in a later post). Those subclasses need to be loaded into your application via the familiar <b>script</b> tag. But there are two different ways our application can respond the script tags request:</p>
<ol>
<li>Serve static javascript files from public/</li>
<li>Serve dynamic javascript files from a controller/view setup</li>
</ol>
<p>Static files in public/ have the advantage of loading much faster, as they come directly off the file system and skip over the framework&#8217;s call stack. Dynamic files from a controller/view are dynamic, which allow the javascript to be custom tailored for the user&#8217;s needs. Both have their uses and after a lot of trial and experimentation, I determined the best approach is to use both. Okay, so I lied&#8230; there is no choice.</p>
<p>What we are going to do is define the various subclass methods in public/javascripts/. These files do not need to change on a per-user basis, so we get the benefit of the static load time. But any files that require dynamic generation will be done via a controller and a view. But before we go a step further we need to setup your application&#8217;s index page.</p>
<p>In my estimation, there are two ways to use ExtJS in your application. You can either use it as a widget set for things like buttons, dialog boxes, and grids in the way you might use <a href="http://jqueryui.com/">jQuery UI</a>. Or you can do <i>everything</i> in ExtJS. For the app I&#8217;m building at work, ExtJS powers the entire display of the administrative back-end. The setup I&#8217;ll show you today assumes that you&#8217;re entire app is going to be driven by ExtJS. If you think you&#8217;re going to be less whole-hog, don&#8217;t worry, many of the steps will be the same.</p>
<p>First things first, we need a root index page to work with. By default, I get a lovely <b>No routes match the request: /</b> error message when trying to access http://localhost:4000. There are lots of ways to setup an index page depending on your framework, all of which is beyond the scope of this post. What I did with merb was create a controller called &#8220;home&#8221; and added a route to connect &#8220;/&#8221; with &#8220;home/index&#8221;.</p>
<p>Next we need to get the view for home/index looking how we want. Many MVC frameworks use layouts to reduce code duplication between views &#8212; which is great &#8212; but for us, it&#8217;s actually a real problem. So I recommend you disable layouts for the home controller (in merb you just declare &#8220;layout false&#8221; in the controller file). Now head over to the view for home/index (in merb, it will be at app/views/home/index.html.erb). This file is going to serve as your loading point for all the ExtJS magic you need to make your application sing.</p>
<p>Now, add the following HTML right into the file:</p>
<pre class="brush: html">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
    &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Your ExtJS Application&lt;/title&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/extjs/resources/css/ext-all.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;

  &lt;!-- External Dependencies --&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;/extjs/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;/extjs/ext-all-debug.js&quot;&gt;&lt;/script&gt;

  &lt;!-- Application Runner --&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;/home/application.js&quot;&gt;&lt;/script&gt;

  &lt;!-- App Specific Classes --&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Let&#8217;s look at the lines that may not seem immediately obvious:</p>
<pre class="brush: html">
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/extjs/resources/css/ext-all.css&quot;&gt;
</pre>
<p>Loads the ExtJS master CSS file. This has all sorts of CSS definitions that make all the ExtJS widgets look super delicious.</p>
<pre class="brush: html">
&lt;!-- External Dependencies --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/extjs/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/extjs/ext-all-debug.js&quot;&gt;&lt;/script&gt;
</pre>
<p>These two lines load up the ExtJS library itself into your application. Make sure you load them in the order specified here. Couple of important notes here. The first line is the adapter line, and I&#8217;m told it allows you to teach ExtJS to play nice with other JS frameworks like jQuery and Prototype. I haven&#8217;t played with any of that, so your mileage may vary if you go that direction, here we are using ExtJS with ExtJS. The second line is the monster library include and here you actually have two choices. In development mode, I always load ext-all-debug.js, because Firebug output is far more useful&#8230; but in production, you&#8217;ll want to use ext-all.js, which has been <a href="http://www.crockford.com/javascript/jsmin.html">minified</a> for quicker download to your clients. In a more advanced application, we&#8217;d have the view determine which file to send programatically, but we are going to take it slow.</p>
<pre class="brush: html">
&lt;!-- Application Runner --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/home/application.js&quot;&gt;&lt;/script&gt;

&lt;!-- App Specific Classes --&gt;
</pre>
<p>The Application Runner is the starter pistol of your ExtJS application&#8230; the thing which makes it go. We are going to setup a basic one in just a moment. Then under that is where your application specific ExtJS subclasses are going to be loaded. There aren&#8217;t any at present, but we will write one shortly and it&#8217;s good to have a place ready to put them.</p>
<p>For the Application runner you will need to add an application action to the home controller and indicate that it serves up javascript. In Merb:</p>
<pre class="brush: ruby">
  def application
    provides :js
    render
  end
</pre>
<p>Then create a view at app/views/home/application.js.erb and dump in the following:</p>
<pre class="brush: javascript">
Ext.BLANK_IMAGE_URL = &#039;/extjs/resources/images/default/s.gif&#039;;
Ext.ns(&#039;demo&#039;);

// application main entry point
Ext.onReady(function() {

  var viewport = new Ext.Viewport({
    items: [
      {
        region:     &#039;north&#039;,
        html:       &#039;&lt;h1 class=&quot;x-panel-header&quot;&gt;Your Demo Application&lt;/h1&gt;&#039;,
        autoHeight: true,
        border:     false,
        margins:    &#039;0 0 5 0&#039;
      },{
        region:     &#039;center&#039;
      }
    ]
  });
  viewport.show();

});
</pre>
<p>The first two lines of code set some global configuration. The first line there is a request from the fine folks at ExtJS to use your own locally hosted single blank pixel instead of theirs (it&#8217;s the least you can do). The next creates a namespace for the code you are going to be writing. I&#8217;ve chosen the highly descriptive &#8220;demo&#8221; as my namespace here, but I recommend using a short-hand version of your application. The big advantage of using a namespace is now you can define whatever classes you want without bumping into native javascript classes. All of the ExtJS base classes are namedspaced to &#8220;Ext&#8221;, so I recommend using something other than that.</p>
<p>Then comes the starter pistol:</p>
<pre class="brush: javascript">
Ext.onReady(function() {
  // code goes here
});
</pre>
<p>If you are familiar with jQuery, this is equivalent to:</p>
<pre class="brush: javascript">
$(document).ready(function(){
  // code goes here
});
</pre>
<p>What it does is ensure the code inside of the block is not executed until the entire page is done loading. Meaning all of the javascript libraries, CSS files, etc. If you try to execute your application code right away, you can&#8217;t be sure the environment is full prepped. Wrapping your code in the Ext.onReady method gives you the confidence everything is, well, ready.</p>
<p>Then lastly we&#8217;ve got this Ext.Viewport constructor with some configuration parameters passed into the constructor. Don&#8217;t worry about the specifics of the configuration at the moment, we&#8217;ll talk about Viewports in some other post. What&#8217;s important to know is that Viewports setup a full browser window environment to instantiate other components. It is the starting point of any full ExtJS application.</p>
<p>At this point you can save these files, startup your application and go to the index page. You should get a panel at the top that reads &#8220;Your Demo Application&#8221;. Congratulations, you&#8217;ve got an ExtJS application!</p>
<p>One last thing to do before we close down for the day. The Viewport there has application specific configuration variables, and as you will learn in the post on subclassing, that is indicator number one that we should create an ExtJS subclass. To do so, create a file at public/javascripts/demo.viewport.js (note, if you declared a different namespace than &#8220;demo&#8221; use that wherever I use &#8220;demo&#8221; in all of the following examples). In the file you just created, paste the following:</p>
<pre class="brush: javascript">
demo.viewport = function(config) {

  var base_config = {
    items: [
      {
        region:     &#039;north&#039;,
        html:       &#039;&lt;h1 class=&quot;x-panel-header&quot;&gt;Your Demo Application&lt;/h1&gt;&#039;,
        autoHeight: true,
        border:     false,
        margins:    &#039;0 0 5 0&#039;
      },{
        region:     &#039;center&#039;
      }
    ]
  };

  Ext.apply(base_config,config);

  demo.viewport.superclass.constructor.call(this,base_config);

}

Ext.extend(demo.viewport, Ext.Viewport, {});
</pre>
<p>Update your application.js file to read:</p>
<pre class="brush: javascript">
Ext.BLANK_IMAGE_URL = &#039;/extjs/resources/images/default/s.gif&#039;;

Ext.ns(&#039;demo&#039;);

// application main entry point
Ext.onReady(function() {

  var viewport = new demo.viewport()
  viewport.show();

});
</pre>
<p>And under &#8220;App Specific Classes&#8221; in the index.html file, add:</p>
<pre class="brush: html">
&lt;script type=&quot;text/javascript&quot; src=&quot;/javascripts/demo.viewport.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Reload the index page and nothing should change. Except now we&#8217;ve got the static parts of the application being served from public/javascripts/ and the dynamic parts of the application from the home controller. With this basic framework we are ready to start learning about subclasses and how to organize you ExtJS code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/04/preparing-your-extjs-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing wp-extjs-loader</title>
		<link>http://blog.probonogeek.org/2009/02/introducing-wp-extjs-loader/</link>
		<comments>http://blog.probonogeek.org/2009/02/introducing-wp-extjs-loader/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 01:23:20 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=452</guid>
		<description><![CDATA[Today I wrote my first WordPress plugin. Its purpose is to load the ExtJS libraries into a WordPress post whose category has been set to &#8220;ExtJS&#8221;&#8230; just like the post you are reading now. See, ExtJS is a heavy library, and even minimified it clocks in at nearly 600 KBs. I don&#8217;t want to have [...]]]></description>
			<content:encoded><![CDATA[<p>Today I wrote my first WordPress plugin. Its purpose is to load the ExtJS libraries into a WordPress post whose category has been set to &#8220;ExtJS&#8221;&#8230; just like the post you are reading now. See, ExtJS is a heavy library, and even minimified it clocks in at nearly 600 KBs. I don&#8217;t want to have to pay that bandwidth cost if I don&#8217;t have to, nor do my readers who aren&#8217;t the least bit interested in ExtJS. So the plugin takes care of loading only when the post is about ExtJS.<span id="more-452"></span></p>
<p>I honestly can&#8217;t imagine a use for this plugin other than someone who blogs about both ExtJS and non-ExtJS topics. But, if you are interested in the plugin, it is <a href="http://github.com/probonogeek/wp-extjs-loader/">available at github</a>.</p>
<p>A few caveats&#8230; this plugin is still very much <i>in progress</i>. The ExtJS category ID is hard coded into the code. So, unless your ExtJS category ID == 10, as mine does, the code won&#8217;t work. Future releases will allow you to specify which category to load on&#8230; and maybe, down the road, allow you to specify which parts of ExtJS to load, as opposed to the whole suite like it&#8217;s doing right now.</p>
<p>But here&#8217;s the big payoff for all this work. I give you my first embedded ExtJS example:</p>
<p><script type="text/javascript">
  Ext.onReady(function() {
    button = new Ext.Button({
      text:     "Click me, I won't bite",
      renderTo: 'example-button',
      handler:  function(){
        Ext.Msg.alert("Congratulations","You clicked me!");
      }
    });
  });
</script></p>
<div class="extjs" id='example-button'></div>
<p></p>
<p>Now, if you think that was easy, you&#8217;ve got another thing coming&#8230; took me forever to get that to work. Not because of the ExtJS, but because of all the stylesheet interference with my kick-ass WordPress theme. But I think I&#8217;ve got it all sorted out. Here&#8217;s the entirety of the code I used to produce the above.</p>
<pre class="brush: javascript">
  Ext.onReady(function() {
    button = new Ext.Button({
      text:     &quot;Click me, I won&#039;t bite&quot;,
      renderTo: &#039;example-button&#039;,
      handler:  function(){
        Ext.Msg.alert(&quot;Congratulations&quot;,&quot;You clicked me!&quot;);
      }
    });
  });
</pre>
<p>And then I defined a DIV on the page with ID = &#8220;example-button&#8221;. It&#8217;s just that easy. I think all the kinks are finally worked out and we can get into some real learning with the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/02/introducing-wp-extjs-loader/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Javascript Foundation</title>
		<link>http://blog.probonogeek.org/2009/02/javascript-foundation/</link>
		<comments>http://blog.probonogeek.org/2009/02/javascript-foundation/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 07:15:57 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=414</guid>
		<description><![CDATA[To get any use out of ExtJS you need to understand javascript. It&#8217;s inescapable. This is not a framework were you are going to be writing ruby code that generates javascript for you, like you may have experienced with Rails/Prototype. There may, someday, be that sort of integrated support&#8230; but not today, and quite frankly, [...]]]></description>
			<content:encoded><![CDATA[<p>To get any use out of ExtJS you need to understand javascript. It&#8217;s inescapable. This is not a framework were you are going to be writing ruby code that generates javascript for you, like you may have experienced with Rails/Prototype. There may, someday, be that sort of integrated support&#8230; but not today, and quite frankly, it would be an abomination of the framework anyway. If you are an old pro at Javascript, chances are this isn&#8217;t going to be very informative, but if the last great Javascript trick you learned was how to change the browser&#8217;s status bar, you may learn a thing or two.<span id="more-414"></span></p>
<h3>Firebug, the Indispensable Tool</h3>
<p>The first central concept to cover is basic tools. Back in the day, javascript debugging involved peppering your code with alert() calls that would popup little messages&#8230; like print statements in a scripting language, but way more annoying because they would stop the process until you pressed the &#8220;okay&#8221; button. But now there is a <i>better way</i>. The better way is <a href="http://www.getfirebug.com">Firebug</a>. It&#8217;s a Firefox extension that lets you peer into your webpage in ways never before possible. It is absolutely essential to doing ExtJS work, so if you don&#8217;t have it, you need to get it. If there is a similar tool for IE, I haven&#8217;t encountered it, so even if IE is your target browser, use Firefox for development purposes and just be sure to occasionally test in IE for cross-browser issues.</p>
<p>By now I&#8217;m assuming you have Firebug installed. You should have a little bug icon in the bottom right of your browser. If you click on it, a panel will expand showing some Firebug options. You want to <b>enable</b> the Console. Script and Net have their uses too, but for today&#8217;s lesson, we want the Console. Turn it on for this blog&#8230; the page will reload and then you will see four items printed out to the terminal.</p>
<p>The first is a string I sent to the console with the following Javascript code:</p>
<p><script type="text/javascript">
  console.log('Hello Word');
</script></p>
<pre class="brush: javascript">
console.log(&#039;Hello Word&#039;);
</pre>
<p>By calling the log method on the console object I can send pretty much anything I want to the Console you now see below. Turns out you can send nearly anything to the console and Firebug will let you see all sort of internal data. But I&#8217;m getting ahead of myself. Before talking about the remaining items in the FireBug Console, I need to talk about some central features of Javascript.</p>
<p>If you were at all like me, you learned about the basic Javascript native types. Chances are that means you learned the following:</p>
<pre class="brush: javascript">
var n = 5; // is a Number
var s = &#039;Hello&#039;; // is a String
var a = new Array(&#039;red&#039;,&#039;blue&#039;,green&#039;); // is an Array
</pre>
<p>You may have even learned a little more advanced stuff, like:</p>
<pre class="brush: javascript">
var t = new Time(); // is a Time object
var a[&#039;key&#039;] = &#039;value&#039;; // is an associative array
</pre>
<p>And, of course, you learned about functions:</p>
<pre class="brush: javascript">
function do_stuff( argument ){
  // stuff gets done
}
</pre>
<p>That was probably good enough to do all sorts of stuff. But if that&#8217;s where you stopped you never really learned the fundamental attributes of Javascript that make it possible to do all the cool stuff that ExtJS does (to say nothing of JQuery or Prototype). There are two critical parts of your education that need reenforcement.</p>
<h3>Hashes (actually, objects)</h3>
<p>Basic computer science teaches us about arrays and hashes, one is ordered data and the other is keyed data. Each have strength and weaknesses. If all you learned was the above, then you probably came to believe &#8212; as I did &#8212; that Javascript used the Array type for both. Since it was possible to use both integers and strings as Array indexes, it&#8217;s not hard to see why.</p>
<pre class="brush: javascript">
addresses = new Array();
addresses[&#039;alice&#039;] = &#039;123 Fake Street&#039;;
addresses[&#039;bob&#039;] = &#039;1600 Pennsylvania Ave&#039;;
</pre>
<p>Sure looks like a hash to me. And in a way it is a hash, because it&#8217;s keyed data. But in Javascript there is another more powerful way to create a hash. Except, Javascript doesn&#8217;t call it a hash, it is called an object. Behold:</p>
<pre class="brush: javascript">
addresses = {
  alice: &#039;123 Fake Street&#039;,
  bob: &#039;1600 Pennsylvania Ave&#039;
};
</pre>
<p>Looks like awfully familiar syntax, don&#8217;t it? Like, here&#8217;s the same object expressed in Ruby:</p>
<pre class="brush: ruby">
addresses = {
  :alice =&gt; &#039;123 Fake Street&#039;,
  :bob =&gt; &#039;1600 Pennsylvania Ave&#039;
}
</pre>
<p>I honestly couldn&#8217;t tell you why it&#8217;s an object and not a hash, but there it is. The important part is that you can create arbitrarily complex data structures using this syntax in a single assignment. Oh, and for an additional syntactic win, instead of using <b>new Array()</b>, you can just use <b>[]</b>. Which means we can do the following:</p>
<p><script type="text/javascript">
console.log({
  first_name: 'Alice',
  address: {
    street: '123 Fake Street',
    city: 'Springfield',
    zipcode: '12345'
  },
  favorite_colors: ['blue','green']
});
</script></p>
<pre class="brush: javascript">
persona_data = {
  first_name: &#039;Alice&#039;,
  address: {
    street: &#039;123 Fake Street&#039;,
    city: &#039;Springfield&#039;,
    zipcode: &#039;12345&#039;
  },
  favorite_colors: [&#039;blue&#039;,&#039;green&#039;]
};
</pre>
<p>Now that you see how data structures in Javascript can be very sophisticated, let&#8217;s see how you can use the Firebug Console to peer inside. Open up the console again and click on the second row that reads <b> Object first_name=Alice address=Object favorite_colors=[2]</b>. In there you will see the different <i>properties</i> of the personal_data object we created above. You can expand the address property to discover it too is an object with its own properties, or expand the favorite_colors property to inspect an array.</p>
<h3>Functions as Properties</h3>
<p>It turns out that objects, like the ones above, can hold any type of Javascript native type in one of its properties. Arrays, strings, numbers, other objects&#8230; you&#8217;ve seen examples of all of that by now. The final piece of the puzzle then is to see that objects can also store functions. In Javascript, a function is just another piece of data that can be assigned to a variable, like this:</p>
<pre class="brush: javascript">
var my_method = function(){
  // do stuff
}
</pre>
<p>Now I can run around with the my_method variable, assign it to other variables, and even execute it. And here in lies the third and final lesson of the post. Consider an object like the following:</p>
<pre class="brush: javascript">
var refrigerator = {
  contents: [&#039;milk&#039;,&#039;eggs&#039;,&#039;cheese&#039;],
  grab_item: function(){
    return this.contents.pop();
  }
}
</pre>
<p>Here we&#8217;ve got our refrigerator object, it&#8217;s got some stuff in it, and we&#8217;ve got a grab_item method that returns the last item off the contents array. To call that method we have to use just the right syntactic sugar, which means putting parentheses at the end. Consider the following two lines of code:</p>
<pre class="brush: javascript">
  snack1 = refrigerator.grab_item // wrong, snack1 now equals the function
  snack2 = refrigerator.grab_item() // right, snack2 now equals &#039;cheese&#039;
</pre>
<p>See, we have to tell javascript we want to actually execute the function, not just assign the data. Firebug confirms this in lines three and four on the console.</p>
<p><script type="text/javascript">
var refrigerator = {
  contents: ['milk','eggs','cheese'],
  grab_item: function(){
    return this.contents.pop();
  }
}
console.log( refrigerator.grab_item );
console.log( refrigerator.grab_item() );
</script></p>
<p>Okay, with the concepts of objects and methods down, and Firebug installed, we are ready to start diving into ExtJS. Next ExtJS post will have actual ExtJS examples, I promise&#8230; I think I&#8217;ve nearly got all the bugs worked out for demoing live ExtJS code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/02/javascript-foundation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What is ExtJS and why do I care?</title>
		<link>http://blog.probonogeek.org/2009/02/what-is-extjs-and-why-do-i-care/</link>
		<comments>http://blog.probonogeek.org/2009/02/what-is-extjs-and-why-do-i-care/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 07:48:10 +0000</pubDate>
		<dc:creator>probonogeek</dc:creator>
				<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://blog.probonogeek.org/?p=341</guid>
		<description><![CDATA[If you don&#8217;t build websites, the answer to the second question is you don&#8217;t. There are better things for you to spend your limited internet time learning about&#8230; like, did you know there was a Simple Wikipedia project? I didn&#8217;t until just a few minutes ago.
Okay, now that we are just down to the web [...]]]></description>
			<content:encoded><![CDATA[<p>If you don&#8217;t build websites, the answer to the second question is you <i>don&#8217;t</i>. There are better things for you to spend your limited internet time learning about&#8230; like, did you know there was a <a href="http://simple.wikipedia.org">Simple Wikipedia</a> project? I didn&#8217;t until <a href="http://xkcd.com/547/">just</a> a few minutes ago.</p>
<p>Okay, now that we are just down to the web developers and the wannabe web developers, lets try and get the basics established so that future posts will have a common language we all agree on&#8230; or, at least, that I agree on and that you will be forced to understand to extract anything from my ramblings.<span id="more-341"></span></p>
<p><a href="http://extjs.com/products/extjs/">ExtJS describes itself</a> as a &#8220;Ext JS is a cross-browser JavaScript library for building rich internet applications.&#8221; Which is as good a description as any, if not a tad simplistic. I think a more complete description would be, &#8220;Ext JS is a GUI framework for building rich internet applications available under either a commercial or open source license.&#8221; The emphasis here is that ExtJS:</p>
<ol>
<li>allows for the quick deployment of reusable GUI components</li>
<li>is used to build front ends</li>
<li>contains a mixture of javascript, CSS, and binary assets</li>
<li>has a dual license model</li>
</ol>
<p>Let&#8217;s break those points down to understand what I&#8217;m driving at.</p>
<h3>Allows for the quick deployment of reusable GUI components</h3>
<p>Let&#8217;s talk about the sexy stuff first. ExtJS provides a whole ton of Graphical User Interface (GUI) components that you would expect to see in a modern Desktop Environment, but generally don&#8217;t see on the web. There is an outstanding <a href="http://extjs.com/deploy/dev/examples/samples.html">ExtJS Example</a> page that shows off most of what the framework can do.</p>
<p>Here&#8217;s a quick and dirty list of the various components:</p>
<ul>
<li>grids (like in a spreadsheet)</li>
<li>tabs</li>
<li>modal windows</li>
<li>trees</li>
<li>enhanced form elements</li>
<li>toolbars</li>
<li>menus</li>
<li>buttons</li>
<li>sliders</li>
<li>tooltips</li>
<li>progress bars</li>
</ul>
<p>Sadly, I haven&#8217;t come up with a good way to demo any of these bits of code in WordPress yet (all JS code is sanitized by default to protect against <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">evil</a>), but it&#8217;s something I very much plan to work out. In the mean time, let me show you how easy it would be to create an attractive looking button.</p>
<pre class="brush: javascript">
  buttonObj = new Ext.Button({
    text:&#039;Press Me&#039;,
    renderTo: &#039;button&#039;
    handler: function(){
      // button action goes here
    },
  })
</pre>
<p>Then, all we would need is an HTML DIV element with an ID set to &#8220;button&#8221; and we&#8217;d be done. Once the Javascript had executed it would render the button inside of the designated DIV complete with the handler functionality all ready to go. If all of that is Greek to you, don&#8217;t worry, I&#8217;m going to explain some of the Javascript basics in a future post.</p>
<h3>Is used to build front ends</h3>
<p>ExtJS&#8217;s primary function is to generate HTML for display via a web browser and to attach behaviors to those HTML elements that the user can interact with. This aspect is more important for what it isn&#8217;t, than what it is. What ExtJS shouldn&#8217;t be used for is application logic. That&#8217;s not to say it <i>cannot</i> be used for application logic, just that down that way is madness, so try to avoid it. Here&#8217;s some good reasons to keep application logic out of ExtJS.</p>
<ul>
<li>ExtJS talks to your webserver via AJAX, which means you will need backend scripts of some kind to process those requests. As those scripts are closer to the database that will back your application, it is those scripts that serve as the more appropriate vessel for your application logic.</li>
<li>ExtJS uses Javascript for anything functional, which means you would end up writing your application logic in Javascript. Not to dis on Javascript as a language, but most of us don&#8217;t have the experience with Javascript to write clean and maintainable application code.</li>
<li>ExtJS is more like the View part of an MCV application, and the MCV paradigm does not take kindly to embedding logic into the View. For example, if you put application logic into the view <b>and</b> have two views on the same data, you would need two implementations of the same logic. Talk about code duplication nightmares.</li>
</ul>
<p>If you are really dead set on making a pure ExtJS application, I wish you all the luck in the world, but I don&#8217;t think you&#8217;re going to find many of my posts very helpful. Consider yourself warned.</p>
<h3>Contains a mixture of javascript, CSS, and binary assets</h3>
<p>Here&#8217;s where I disagree most strongly with the official ExtJS definition. Yes, ExtJS is a &#8220;Javascript library,&#8221; but it&#8217;s so much more than that. In addition to the javascript files that comprise the core of ExtJS, there is a full 2.3 MBs of CSS and image resource files that go along with it. For the most basic uses of ExtJS, you may never look in the resources directory. But as you begin to understand the deeper relationships in the library, you will begin to see how fundamentally important those CSS definitions are, and how tweaking a few images can give you a wide range of flexibility.</p>
<h3>Has a dual license model</h3>
<p>If ExtJS were to ever be considered controversial, it would be because of this final point. I didn&#8217;t come to ExtJS until late 2008, at which point the library had been around for a while. The story goes that ExtJS used to be available under a more permissive open source license, such that commercial developers could use the code without buying a commercial license. At some point in ExtJS&#8217;s product development, the <a href="http://extjs.com/company/dual.php">company decided to change</a> the open source license to the strictest of all licenses, the <a href="http://www.opensource.org/licenses/gpl-3.0.html">GNU General Public License</a>. This engendered quite a bit of bad blood among those commercial developers, who felt like they were tricked into adopting a library and now either had to cough up the dough for a commercial license, GPL their own works, or start all over again.</p>
<p>My opinion is what it generally is involving the GPL&#8230; sounds good to me! If a commercial developer wants to benefit from the work, then they are free to pay for future development by buying a license or they can contribute back to the community. The value of a third option is marginal at best, and more likely to induce free-riding than stimulate community.</p>
<p>My company has the good fortune of being able to buy a commercial license outright, so we do all of our development in a closed source environment, so I won&#8217;t be showing any examples from that project. What you will see in these posts is using my own personal copy of ExtJS which I have under the terms of the GPL. Which, by my reckoning, makes any example code I throw up here also available under the terms of the GPL. Of course, a lot of the code will be more functional than expressive, in which case you don&#8217;t really need to worry about licenses&#8230; just use this to study and build your own.</p>
<p>I think that should do it for our introductory post (clocking in at 1133 words already!). Next time I&#8217;ll discuss some basic javascript concepts and then get into some of the GUI elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.probonogeek.org/2009/02/what-is-extjs-and-why-do-i-care/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

