<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2803683318731698468</id><updated>2011-11-02T07:31:46.323-05:00</updated><title type='text'>Code Weird</title><subtitle type='html'>"If this blog were a dog, it would nuzzle up to ASP.NET, wag its tail at web design and development, and bark at software development in general."

~ Steve McConnell, Code Complete (paraphrased with apologies)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2803683318731698468.post-8032136407799110509</id><published>2010-07-16T15:29:00.001-05:00</published><updated>2010-07-16T15:29:54.845-05:00</updated><title type='text'>jQuery, JSONP, and the Same-Origin Policy</title><content type='html'>&lt;p&gt;First of all, my apologies for the rather massive delay on my JavaScript template series.&amp;#160; The combination of a new job and a family doesn’t allow much time for blogging.&amp;#160; But the topic of client-side template engines is still a hot one, so I plan to resume the series in the near future.&lt;/p&gt;  &lt;p&gt;I just finished reading &lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=540&amp;amp;utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%253A+netCurryRecentArticles+%2528.NET+Curry%253A+Recent+Microsoft+ASP.NET%252C+Silverlight%252C+WinForms%252C+Vista%252C+C%2523%252C+VB.NET+Articles%2529"&gt;the post&lt;/a&gt; on DotNetCurry about using jQuery to query Twitter’s public API.&amp;#160; It is a great post, but I thought that some developers might want some additional details on how exactly the code in the article is able to get around browsers’ same-origin policy.&amp;#160; At first glance, there appears to be some magic involved.&lt;/p&gt;  &lt;p&gt;As I’m fond of saying, there is no magic in software development, so let’s see what is really going on:&lt;/p&gt;  &lt;p&gt;Browsers prevent JavaScript code from accessing resources from a different domain than the one that delivered the page in the first place.&amp;#160; This is a security feature designed to prevent the browser from unwittingly passing (possibly sensitive) data from one site (your bank’s online account page, for example) to a malicious third party.&amp;#160; Unfortunately, this same policy means that well-meaning scripts are unable to access potentially useful external resources (a third-party web service like Twitter’s, for example).&lt;/p&gt;  &lt;p&gt;Is there a loophole?&amp;#160; It turns out that the &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; tag is exempt from the same-origin policy.&amp;#160; It really must be, if you think about it: otherwise, a page would only be able to reference JavaScript files served from the same domain as the page.&amp;#160; Content delivery networks, for example, would be impossible as a result.&lt;/p&gt;  &lt;p&gt;JSONP to the rescue.&amp;#160; JSONP stands for “JSON with Padding”.&amp;#160; Actually, I’ve always thought that this was a misleading name.&amp;#160; It is padded, in a sense, but I think a better name would have been “JSONC” for “JSON with &lt;strong&gt;Callback&lt;/strong&gt;”.&amp;#160; Instead of using vanilla Ajax to call a remote web service that then returns JSON to our page, we put the URL to the remote web service in the &lt;strong&gt;src=””&lt;/strong&gt; attribute of a &lt;strong&gt;&amp;lt;script&amp;gt;&lt;/strong&gt; tag and (here is the key part) include the name of a callback function in the URL.&amp;#160; The typical way this is done is to append &lt;strong&gt;callback=&amp;lt;functionname&amp;gt;&lt;/strong&gt; to the end of the URL:&lt;/p&gt;  &lt;div style="border-bottom: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; background-color: #f0f0f0; font-family: monospace; color: #006; border-top: #d0d0d0 1px solid; border-right: #d0d0d0 1px solid" class="javascript"&gt;&lt;span style="color: #339933"&gt;&amp;lt;&lt;/span&gt;script type&lt;span style="color: #339933"&gt;=&lt;/span&gt;&lt;span style="color: #3366cc"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src&lt;span style="color: #339933"&gt;=&lt;/span&gt;&lt;span style="color: #3366cc"&gt;&amp;quot;http://api.twitter.com/1/statuses/user_timeline/mattspeterson.json?callback=DisplayResults&amp;quot;&lt;/span&gt;&lt;span style="color: #339933"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;script&lt;span style="color: #339933"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;&lt;em&gt;We&lt;/em&gt; are responsible for writing the &lt;strong&gt;DisplayResults()&lt;/strong&gt; function to handle the JSON data returned by the web service call and passed as a parameter to this function.&amp;#160; The &lt;em&gt;remote web service&lt;/em&gt; is responsible for noticing that we have appended the name of a callback function and wrapping the results appropriately when they are sent to us.&lt;/p&gt;  &lt;p&gt;But the example in &lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=540&amp;amp;utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%253A+netCurryRecentArticles+%2528.NET+Curry%253A+Recent+Microsoft+ASP.NET%252C+Silverlight%252C+WinForms%252C+Vista%252C+C%2523%252C+VB.NET+Articles%2529"&gt;the blog post&lt;/a&gt; referenced above didn’t use this technique.&amp;#160; So what gives?&lt;/p&gt;  &lt;p&gt;It turns out that jQuery’s &lt;strong&gt;&lt;a href="http://api.jquery.com/jQuery.getJSON/"&gt;$ajax.getJSON()&lt;/a&gt;&lt;/strong&gt; method is doing some extra leg-work for us.&amp;#160; Let’s have a look at a similar example:&lt;/p&gt;  &lt;div style="border-bottom: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; background-color: #f0f0f0; font-family: monospace; color: #006; border-top: #d0d0d0 1px solid; border-right: #d0d0d0 1px solid" class="javascript"&gt;&lt;span style="color: #339933"&gt;&amp;lt;&lt;/span&gt;script type&lt;span style="color: #339933"&gt;=&lt;/span&gt;&lt;span style="color: #3366cc"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: #339933"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $&lt;span style="color: #009900"&gt;(&lt;/span&gt;document&lt;span style="color: #009900"&gt;)&lt;/span&gt;.&lt;span style="color: #660066"&gt;ready&lt;/span&gt;&lt;span style="color: #009900"&gt;(&lt;/span&gt;&lt;span style="color: #003366; font-weight: bold"&gt;function&lt;/span&gt; &lt;span style="color: #009900"&gt;(&lt;/span&gt;&lt;span style="color: #009900"&gt;)&lt;/span&gt; &lt;span style="color: #009900"&gt;{&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $.&lt;span style="color: #660066"&gt;getJSON&lt;/span&gt;&lt;span style="color: #009900"&gt;(&lt;/span&gt;&lt;span style="color: #3366cc"&gt;&amp;quot;http://api.twitter.com/1/statuses/user_timeline/mattspeterson.json?callback=?&amp;quot;&lt;/span&gt;&lt;span style="color: #339933"&gt;,&lt;/span&gt; DisplayTweets&lt;span style="color: #009900"&gt;)&lt;/span&gt;&lt;span style="color: #339933"&gt;;&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #009900"&gt;}&lt;/span&gt;&lt;span style="color: #009900"&gt;)&lt;/span&gt;&lt;span style="color: #339933"&gt;;&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #003366; font-weight: bold"&gt;function&lt;/span&gt; DisplayTweets&lt;span style="color: #009900"&gt;(&lt;/span&gt;tweets&lt;span style="color: #009900"&gt;)&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #009900"&gt;{&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-style: italic; color: #006600"&gt;// Bind the tweets returned to the DOM using your JavaScript template engine of choice...&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #009900"&gt;}&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #339933"&gt;&amp;lt;/&lt;/span&gt;script&lt;span style="color: #339933"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;The &lt;strong&gt;getJSON()&lt;/strong&gt; method looks for &lt;strong&gt;callback=?&lt;/strong&gt; in the first parameter (the URL) and if it is present, dynamically creates a “throwaway” callback function and puts its name in the &lt;strong&gt;?&lt;/strong&gt; placeholder when it makes the Ajax call to the URL.&lt;/p&gt;  &lt;p&gt;Using your web developer tool of choice (I’m using Google Chrome’s tools), you can verify that this is what is happening:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_qjMsn857PBw/TEDBNPYfM_I/AAAAAAAAALA/IOrnZ3ZZFes/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_qjMsn857PBw/TEDBNcl3XhI/AAAAAAAAALE/urThll-Kkp0/image_thumb%5B2%5D.png?imgmax=800" width="644" height="221" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Let’s have a look at the response we get back from &lt;a href="http://apiwiki.twitter.com/Twitter-REST-API-Method:-statuses-user_timeline"&gt;this call to the Twitter API&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_qjMsn857PBw/TEDBN7bRxVI/AAAAAAAAALI/bPeThHMSupk/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_qjMsn857PBw/TEDBOTwJJ3I/AAAAAAAAALM/648Ag6sFS8E/image_thumb%5B4%5D.png?imgmax=800" width="488" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The response isn’t JSON-encoded data, it is &lt;em&gt;a call to the ad-hoc callback function that jQuery created for us on the fly with the data passed as a parameter&lt;/em&gt;.&amp;#160; So where is this callback function?&amp;#160; jQuery has dynamically added it to the DOM:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_qjMsn857PBw/TEDBOhUSt4I/AAAAAAAAALQ/DA21UjGorpI/s1600-h/image%5B13%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_qjMsn857PBw/TEDBPa7gujI/AAAAAAAAALU/rTbksDW6feU/image_thumb%5B7%5D.png?imgmax=800" width="753" height="204" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_qjMsn857PBw/TEDBPtvcqVI/AAAAAAAAALY/bzKEpzqMGUs/s1600-h/image%5B23%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_qjMsn857PBw/TEDBPyF-0HI/AAAAAAAAALc/UC1n2ftYsWo/image_thumb%5B13%5D.png?imgmax=800" width="301" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;$ajax.getJSON()&lt;/strong&gt; does one more bit of work for you: it calls &lt;strong&gt;$.parseJSON()&lt;/strong&gt; to convert the JSON-encoded string returned from the Twitter web service to a JavaScript object before passing it to your &lt;em&gt;named&lt;/em&gt; callback function:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_qjMsn857PBw/TEDBQJJzUII/AAAAAAAAALg/_D-BGUsV5Ns/s1600-h/image%5B22%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_qjMsn857PBw/TEDBQtoQ0OI/AAAAAAAAALk/x6znRDlZ3_U/image_thumb%5B12%5D.png?imgmax=800" width="799" height="234" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Hope this helps shine a light on the inner workings of JSONP.&amp;#160; The lesson here is that jQuery really does a lot of the messy heavy lifting for you so that your web application can get around a well-intentioned security policy imposed by your browser.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2803683318731698468-8032136407799110509?l=codeweird.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/8032136407799110509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2803683318731698468&amp;postID=8032136407799110509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/8032136407799110509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/8032136407799110509'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/2010/07/jquery-jsonp-and-same-origin-policy.html' title='jQuery, JSONP, and the Same-Origin Policy'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_qjMsn857PBw/TEDBNcl3XhI/AAAAAAAAALE/urThll-Kkp0/s72-c/image_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2803683318731698468.post-997032108260634255</id><published>2010-03-29T09:57:00.001-05:00</published><updated>2010-03-29T10:13:19.980-05:00</updated><title type='text'>JavaScript Template Engines - Introduction</title><content type='html'>&lt;p&gt;I’m about to begin a series of posts on JavaScript template engines.&amp;#160; There is currently a fair amount of buzz about them among web developers and I think they serve a purpose, so I’d like to dig into them a bit.&amp;#160; I’m considering using this series as the basis for an upcoming talk as well.&lt;/p&gt;  &lt;p&gt;In the next post (part I), I’ll explain what JavaScript template engines are and how they work.&amp;#160; In part II, I’ll look at the use cases for them and break down when they are (and are not) appropriate.&amp;#160; Finally, I’ll put together a series of posts where I investigate particular template solutions.&amp;#160; Among the criteria I’ll be evaluating are: size of the library, template syntax style, features, and performance.&amp;#160; I don’t have a fixed list in mind, but I imagine I’ll write about five or six of the most popular ones.&amp;#160; Some candidates are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://beebole.com/pure/" target="_blank"&gt;PURE&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jtemplates.tpython.com/" target="_blank"&gt;jTemplates&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://ejohn.org/about/" target="_blank"&gt;John Resig&lt;/a&gt;’s &lt;a href="http://ejohn.org/blog/javascript-micro-templating/" target="_blank"&gt;Micro-Templating utility&lt;/a&gt; (as well as some of the spin-offs like &lt;a href="http://aefxx.com/jquery-plugins/jqote/" target="_blank"&gt;jQote&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.overset.com/2009/06/28/jqtemplate--jquery-lightweight-javascript-template-engine-plugin/" target="_blank"&gt;JQTemplate&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://sourceforge.net/projects/nanojs/" target="_blank"&gt;jQuery nano&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In addition, Microsoft has &lt;a href="http://stephenwalther.com/blog/archive/2010/03/16/microsoft-jquery-and-templating.aspx" target="_blank"&gt;recently announced a proposal&lt;/a&gt; for a template engine to be built into a future release of &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; core, which seems like a natural addition to the library.&amp;#160; I’ll keep an eye on this as well.&lt;/p&gt;  &lt;p&gt;Finally, I’m aware that client-side data binding is a feature of the ASP.NET Ajax library (now integrated into the ASP.NET Ajax Control Toolkit).&amp;#160; I imagine that there are also similar capabilities in &lt;a href="http://developer.yahoo.com/yui/" target="_blank"&gt;YUI&lt;/a&gt;, although I haven’t used it.&amp;#160; However, both of these solutions include a great deal of functionality beyond pure JavaScript templates, so I doubt I’m going to spend any time on them.&amp;#160; Microsoft seems to have acknowledged this and is &lt;a href="http://stephenwalther.com/blog/archive/2010/03/16/microsoft-jquery-and-templating.aspx" target="_blank"&gt;nudging developers&lt;/a&gt; interested in a simple client-side solution to the aforementioned jQuery proposal.&lt;/p&gt;  &lt;p&gt;Stay tuned!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2803683318731698468-997032108260634255?l=codeweird.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/997032108260634255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2803683318731698468&amp;postID=997032108260634255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/997032108260634255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/997032108260634255'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/2010/03/javascript-template-engines.html' title='JavaScript Template Engines - Introduction'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2803683318731698468.post-3749765125404717033</id><published>2009-08-06T13:24:00.002-05:00</published><updated>2009-08-06T13:27:16.523-05:00</updated><title type='text'>Debugging Tip of the Day</title><content type='html'>I feel like a moron for having to be reminded of something obvious like this, but when tracking down a particularly nasty bug, it helps to start by looking into parts of the code you don't understand particularly well...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2803683318731698468-3749765125404717033?l=codeweird.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/3749765125404717033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2803683318731698468&amp;postID=3749765125404717033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/3749765125404717033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/3749765125404717033'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/2009/08/debugging-tip-of-day.html' title='Debugging Tip of the Day'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2803683318731698468.post-8395960917759761117</id><published>2008-04-28T09:58:00.002-05:00</published><updated>2008-04-28T10:58:11.941-05:00</updated><title type='text'>Coding Music</title><content type='html'>I love music as much as I love writing software, but I've found that most music is too distracting for listening &lt;span style="font-weight: bold;"&gt;while&lt;/span&gt; coding. Then I discovered &lt;a href="http://en.wikipedia.org/wiki/Ambient_music"&gt;ambient music&lt;/a&gt;. Like most music genres, the definition as to what constitutes ambient music is a bit fuzzy, but I would define it as music which is written to be &lt;span style="font-style: italic;"&gt;heard&lt;/span&gt;, but not necessarily to be &lt;span style="font-style: italic;"&gt;listened to&lt;/span&gt;. Very often, ambient is lumped into the category of &lt;a href="http://en.wikipedia.org/wiki/New_Age_music"&gt;new age music&lt;/a&gt; and indeed, some new age music is also ambient, but they aren't technically the same thing.&lt;br /&gt;&lt;br /&gt;But I try to be practical, so if you are interested in exploring the genre, here are artists and albums I would recommend starting with:&lt;br /&gt;&lt;br /&gt;(I've linked to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;downloadable&lt;/span&gt; MP3 album on Amazon where possible; some albums aren't available in MP3 format, so I linked to the CD version.  In some cases, these are available for download on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;iTunes&lt;/span&gt; music store, but in keeping with my recent "no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;DRM&lt;/span&gt;" policy, I'm not linking to those...but just so you know, many of them are there.)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Ambient-1-Music-For-Airports/dp/B000TERDJS/ref=sr_f3_1?ie=UTF8&amp;amp;s=dmusic&amp;amp;qid=1209395244&amp;amp;sr=103-1"&gt;Brian &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Eno&lt;/span&gt; - Ambient 1/Music for Airports&lt;/a&gt; - Brian &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Eno&lt;/span&gt; is generally considered to be the father of modern ambient music and this album, released in 1977, is his first major work in the genre.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Discreet-Music/dp/B000TERDSY/ref=sr_f3_1?ie=UTF8&amp;amp;s=dmusic&amp;amp;qid=1209395480&amp;amp;sr=103-1"&gt;Brian &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Eno&lt;/span&gt; - Discreet Music&lt;/a&gt; - To be honest, I don't care for the B-sides on this album (variations on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Pachelbel's&lt;/span&gt; famous &lt;span style="font-style: italic;"&gt;Canon in D&lt;/span&gt;), but the 31-minute title track is worth the price.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Ambient-2-Plateaux-Mirror/dp/B000TEPDTU/ref=sr_f3_3?ie=UTF8&amp;amp;s=dmusic&amp;amp;qid=1209395244&amp;amp;sr=103-3"&gt;Harold Budd and Brian &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Eno&lt;/span&gt; - Ambient 2/The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Plateaux&lt;/span&gt; of Mirror&lt;/a&gt; - This time, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Eno&lt;/span&gt; collaborates with another of the early ambient composers, Harold Budd (more on him later).&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/The-Room/dp/B00123BB0M/ref=dm_ap_alb2?ie=UTF8&amp;amp;qid=1209395601&amp;amp;sr=101-2"&gt;Harold Budd - The Room&lt;/a&gt; - Budd has a similar style to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Eno&lt;/span&gt;, but different enough for variety.  This is my favorite Harold Budd album.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Dreamtime-Return-Steve-Roach/dp/B000A8AXRM/ref=sr_1_3?ie=UTF8&amp;amp;s=music&amp;amp;qid=1209396371&amp;amp;sr=1-3"&gt;Steve Roach - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Dreamtime&lt;/span&gt; Return&lt;/a&gt; - Steve Roach is another giant of the genre, and this album would easily make most ambient fan's "top ten" list.  This album has a more tribal, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;rhythmic&lt;/span&gt; sound than most of his work (or the rest of this list, for that matter), but is still beautiful.  Unfortunately, Amazon doesn't seem to currently have this album in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;downloadable&lt;/span&gt; form.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Structures-Silence-Steve-Roach/dp/B00005M94W/ref=sr_1_1?ie=UTF8&amp;amp;s=music&amp;amp;qid=1209396551&amp;amp;sr=8-1"&gt;Steve Roach - Structures from Silence&lt;/a&gt; - Another great album from Steve Roach. Again, this one isn't available in MP3 format, but Amazon does have the CD.&lt;/li&gt;&lt;/ul&gt;A few more that are a little less well-known, but I love nonetheless:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Barometric-Sea-Deepspace/dp/B000RQIAAY/ref=sr_1_2?ie=UTF8&amp;amp;s=music&amp;amp;qid=1209396671&amp;amp;sr=1-2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Deepspace&lt;/span&gt; - The Barometric Sea&lt;/a&gt; - This one lives a little closer to the "space music" corner of the ambient genre, but a great album.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Earth-Blue/dp/B000XXS1I2/ref=dm_ap_alb3?ie=UTF8&amp;amp;qid=1209396781&amp;amp;sr=101-3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Deuter&lt;/span&gt; - Earth Blue&lt;/a&gt; - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Deuter&lt;/span&gt; usually lives in the meditative, "spiritual" area of the genre.  All of their albums are good, but I have this album and like it, so I've included it.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Touch/dp/B0013R5WNE/ref=sr_f3_1?ie=UTF8&amp;amp;s=dmusic&amp;amp;qid=1209396938&amp;amp;sr=103-1"&gt;Falling You - Touch&lt;/a&gt; - This isn't strictly an ambient album (some of the tracks actually have lyrics), but it is incredibly haunting and beautiful.  One of my favorites.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/s/ref=nb_ss_dmusic?url=search-alias%3Ddigital-music&amp;amp;field-keywords=Jon+Serrie&amp;amp;x=0&amp;amp;y=0"&gt;Jon &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Serrie&lt;/span&gt; - Century Seasons&lt;/a&gt; - Jon &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Serrie&lt;/span&gt; specializes in space music.  His work is so beautiful.  This is a compilation album, but since Amazon does not carry it (the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;iTunes&lt;/span&gt; store does), I've linked to a page of his other &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;downloadable&lt;/span&gt; albums.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/s/ref=sr_f3_all?ie=UTF8&amp;amp;rs=&amp;amp;keywords=Liquid%20Mind&amp;amp;rh=i%3Adigital-music%2Ck%3ALiquid%20Mind%2Ci%3Adigital-music-album"&gt;Liquid Mind&lt;/a&gt; - I haven't linked to a specific album because, unfortunately, I think all of his stuff sounds pretty much the same.  But that doesn't make it any less beautiful.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Encounter-Journey-Space-Michael-Stearns/dp/B000000X5A/ref=pd_bbs_sr_2?ie=UTF8&amp;amp;s=music&amp;amp;qid=1209397621&amp;amp;sr=8-2"&gt;Michael &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Stearns&lt;/span&gt; - Encounter&lt;/a&gt; - This is my absolute favorite ambient album.  Cold, distant, and haunting, I would describe this as an alien abduction set to music.  When I was a kid living near Little Rock, I used to sit in bed at night listening to a local AM radio talk show about weird stuff like UFOs and space travel.  The host used bits of this album as bumper music, so I would fall asleep with this in my head.  I never knew the album title or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Stearns&lt;/span&gt;' name until years later when I stumbled across it online and recognized the music from the title track.  Amazon has the CD, but I believe &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;iTunes&lt;/span&gt; has it in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;downloadable&lt;/span&gt; form if you want it right away.  Great stuff, but oddly, none of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;Stearns&lt;/span&gt;' other music sounds like this.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;Oöphoi&lt;/span&gt; - Hymns to a Silent Sky - Amazon doesn't have this one at all, but &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;iTunes&lt;/span&gt; does.  Very strange name, but very nice music.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Sky-Of-Grace/dp/B000TPYR4G/ref=dmusic_cd_album?ie=UTF8&amp;amp;qid=1209398145&amp;amp;sr=8-4"&gt;Paul &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;Avgerinos&lt;/span&gt; - Sky of Grace&lt;/a&gt; - Another album I would put in the "not quite ambient" basket, but beautiful nonetheless.&lt;/li&gt;&lt;/ul&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2803683318731698468-8395960917759761117?l=codeweird.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/8395960917759761117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2803683318731698468&amp;postID=8395960917759761117' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/8395960917759761117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/8395960917759761117'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/2008/04/coding-music.html' title='Coding Music'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2803683318731698468.post-4123464564347738169</id><published>2008-03-05T20:44:00.010-06:00</published><updated>2008-03-05T21:29:06.768-06:00</updated><title type='text'>Where's My DataItem?</title><content type='html'>One of the most commonly-used patterns when developing with ASP.NET's data-bound controls is the idea of catching the control's RowDataBound or ItemDataBound event and customizing the display of that row/item in some way based on the data in the underlying data item:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px inset Gainsboro; padding: 10px; overflow: auto; line-height: 6pt; white-space: nowrap;font-family:Consolas,Monospace;font-size:10pt;color:white;"&gt;&lt;br /&gt;&lt;span style='color:Blue'&gt;protected&lt;/span&gt;&lt;span style='color:Black'&gt; &lt;/span&gt;&lt;span style='color:Blue'&gt;void&lt;/span&gt;&lt;span style='color:Black'&gt; grdBallots_RowDataBound ( &lt;/span&gt;&lt;span style='color:Blue'&gt;object&lt;/span&gt;&lt;span style='color:Black'&gt; sender, &lt;/span&gt;&lt;span style='color:#2b91af'&gt;GridViewRowEventArgs&lt;/span&gt;&lt;span style='color:Black'&gt; e )&lt;br/&gt;&lt;br /&gt;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Blue'&gt;if&lt;/span&gt;&lt;span style='color:Black'&gt; ( e.Row.RowType == &lt;/span&gt;&lt;span style='color:#2b91af'&gt;DataControlRowType&lt;/span&gt;&lt;span style='color:Black'&gt;.DataRow )&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:#2b91af'&gt;DataRowView&lt;/span&gt;&lt;span style='color:Black'&gt; rowView = ( &lt;/span&gt;&lt;span style='color:#2b91af'&gt;DataRowView&lt;/span&gt;&lt;span style='color:Black'&gt; ) e.Row.DataItem;&lt;br/&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Blue'&gt;if&lt;/span&gt;&lt;span style='color:Black'&gt; ( rowView != &lt;/span&gt;&lt;span style='color:Blue'&gt;null&lt;/span&gt;&lt;span style='color:Black'&gt; )&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Green'&gt;// ...do customizations here...&lt;br/&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style='color:Black'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br/&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;One of the new server controls that is part of the recent &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en"&gt;v3.5 release of the .NET Framework&lt;/a&gt; is the &lt;a href="http://msdn2.microsoft.com/en-us/library/bb459902.aspx"&gt;ListView control&lt;/a&gt;.  This control combines the templated flexibility of the older &lt;a href="http://msdn2.microsoft.com/en-us/library/w9283stf.aspx"&gt;Repeater&lt;/a&gt; control with the power and ease of use of the &lt;a href="http://msdn2.microsoft.com/en-us/library/4w7ya1ts.aspx"&gt;GridView&lt;/a&gt; control. However, the first time you attempt to use the technique above to customize the way a particular item is displayed, you will notice that the ListViewItem object (obtained in the ItemDataBound event through the ListViewItemEventArgs.Item property) does not contain a reference to the DataItem. So how &lt;span style="font-weight: bold;"&gt;do&lt;/span&gt; you get a reference to the DataItem?&lt;br /&gt;&lt;br /&gt;It turns out that an extra object layer has been added to the ListView control's class hierarchy:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px inset Gainsboro; padding: 10px; overflow: auto; line-height: 6pt; white-space: nowrap;font-family:Consolas,Monospace;font-size:10pt;color:white;"&gt;&lt;br /&gt;&lt;span style='color:Blue'&gt;protected&lt;/span&gt;&lt;span style='color:Black'&gt; &lt;/span&gt;&lt;span style='color:Blue'&gt;void&lt;/span&gt;&lt;span style='color:Black'&gt; lvwFiles_ItemDataBound ( &lt;/span&gt;&lt;span style='color:Blue'&gt;object&lt;/span&gt;&lt;span style='color:Black'&gt; sender, &lt;/span&gt;&lt;span style='color:#2b91af'&gt;ListViewItemEventArgs&lt;/span&gt;&lt;span style='color:Black'&gt; e )&lt;br/&gt;&lt;br /&gt;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Blue'&gt;if&lt;/span&gt;&lt;span style='color:Black'&gt; ( e.Item.ItemType == &lt;/span&gt;&lt;span style='color:#2b91af'&gt;ListViewItemType&lt;/span&gt;&lt;span style='color:Black'&gt;.DataItem )&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:#2b91af'&gt;ListViewDataItem&lt;/span&gt;&lt;span style='color:Black'&gt; dataItem = ( &lt;/span&gt;&lt;span style='color:#2b91af'&gt;ListViewDataItem&lt;/span&gt;&lt;span style='color:Black'&gt;) e.Item;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:#2b91af'&gt;DataRowView&lt;/span&gt;&lt;span style='color:Black'&gt; fileData = ( &lt;/span&gt;&lt;span style='color:#2b91af'&gt;DataRowView&lt;/span&gt;&lt;span style='color:Black'&gt; ) dataItem.DataItem;&lt;br/&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Blue'&gt;if&lt;/span&gt;&lt;span style='color:Black'&gt; ( fileData != &lt;/span&gt;&lt;span style='color:Blue'&gt;null&lt;/span&gt;&lt;span style='color:Black'&gt; )&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style='color:Green'&gt;// ... do your customization here...&lt;br/&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style='color:Black'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br/&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So there you go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2803683318731698468-4123464564347738169?l=codeweird.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeweird.blogspot.com/feeds/4123464564347738169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2803683318731698468&amp;postID=4123464564347738169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/4123464564347738169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2803683318731698468/posts/default/4123464564347738169'/><link rel='alternate' type='text/html' href='http://codeweird.blogspot.com/2008/03/wheres-my-dataitem.html' title='Where&apos;s My DataItem?'/><author><name>Matt Peterson</name><uri>http://www.blogger.com/profile/15534408036466596740</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://photos1.blogger.com/img/155/5513/320/mattp.jpg'/></author><thr:total>0</thr:total></entry></feed>
