<?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>James Van Dyne &#187; Development</title>
	<atom:link href="http://www.james-vandyne.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.james-vandyne.com</link>
	<description>The Life and Times</description>
	<lastBuildDate>Sat, 08 Oct 2011 16:11:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>3 DRY Techniques for Maintainable Ajax</title>
		<link>http://www.james-vandyne.com/3-dry-techniques-for-maintainable-ajax/</link>
		<comments>http://www.james-vandyne.com/3-dry-techniques-for-maintainable-ajax/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 16:09:21 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=196</guid>
		<description><![CDATA[Using ajax on the web is old technology. Writing a good javascript to achieve this is not difficult, but it is rarely covered in introduction to ajax tutorials. The result is a mixing of html &#8220;templates&#8221; inside your javascript code. &#8230; <a href="http://www.james-vandyne.com/3-dry-techniques-for-maintainable-ajax/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Using ajax on the web is old technology. Writing a good javascript to achieve this is not difficult, but it is rarely covered in introduction to ajax tutorials. The result is a mixing of html &#8220;templates&#8221; inside your javascript code. If you change your original markup at all, you have to remember to also update your template and if you have more than a single ajax call on your website, your site becomes a fragile mess.</p>

<p>Below I will outline some techniques that I use when developing websites that help keep my Javascript to a minimum and prevent me from repeating myself.</p>

<h4>Create a convention, and stick to it</h4>

<p>Create your naming scheme for your DOM ids and CSS classes and stick to it. This will make it a lot easier to write your javascript in a generic fashion and then process requests on the server.</p>

<p>For IDs, I usually combine at minimum the action and a unique identifier ( record id or primary key ) sandwiching a hyphen. If I am doing work with multiple forms on a page, I might also include the form prefix in the identifier as well.</p>

<p>Create css class conventions for basic actions, and use them consistently. The main 2 that I use are a class named &#8220;link&#8221; and &#8220;ajaxAction&#8221;.</p>

<h4>Render responses server side</h4>

<p>You should never embed html templates into your javascript. Ever. As stated above this creates a fragile mess that is difficult to maintain. Instead take advantage of your web framework&#8217;s template rendering system ( you are using some kind of framework, right? ). Make sure it&#8217;s the same template that you also use to originally generate the page in the first place. I use Django for most of my web development, so if I am rendering a table that is ajax&#8217;ified my table template might look something like this:</p>


<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;!-- table.html --&gt;
&lt;table&gt;
	{% for row in data %}
		{% if forloop.first %}
			&lt;tr&gt;
				&lt;th&gt;Date&lt;/th&gt;
				&lt;th&gt;Message&lt;/th&gt;
			&lt;/tr&gt;
		{% endif %}
		{% include 'message_row.html' %}
	{% endfor %}
&lt;/table&gt;
&nbsp;
&lt;!-- message_row.html --&gt;
&lt;tr&gt;
	&lt;td&gt;{{row.data}}&lt;/td&gt;
	&lt;td&gt;{{row.message}}&lt;/td&gt;
&lt;/tr&gt;</pre></div></div>


<p>My ajax response would then simply render message_row.html as part of its response. This insures that by ajax response and my original rendering are always the same.</p>

<h4>Use Delegates Instead of Bindings</h4>

<p>When first learning how to use jQuery, we usually bind our dom objects either directly via identifiers or by css classes. This works fine, until you try to add a new element after initial binding. You can click all that new element all you want, but it won&#8217;t respond until you rebind it. Again, unsustainable.</p>

<p>Learn to use delegates instead. The effectively automatically binds all elements on the page, no matter when they are added, by doing lazy processing of the request.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">	$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.ajaxAction'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//BAD</span>
&nbsp;
	$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">delegate</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.ajaxAction'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//GOOD</span></pre></div></div>


<h3>Conclusion</h3>

<p>Javascript doesn&#8217;t have to be ugly and repetitive, although it is often introduced in manners that encourage this. Writing clean and concise Javascript is not difficult, but it does take some discipline and planning. Following the 3 above techniques alone will not guarantee your code is perfect, but it will greatly enhance maintainability and reduce errors in common functions on your site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/3-dry-techniques-for-maintainable-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thoughts on Xcode 4 Price</title>
		<link>http://www.james-vandyne.com/thoughts-on-xcode-4-price/</link>
		<comments>http://www.james-vandyne.com/thoughts-on-xcode-4-price/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 06:18:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=184</guid>
		<description><![CDATA[With the release of Xcode 4 came a completely unknown feature, even for developers like myself: a price tag. This is the first time that Xcode has ever had a price. Since the release of OS X, Xcode (and its &#8230; <a href="http://www.james-vandyne.com/thoughts-on-xcode-4-price/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>With the release of Xcode 4 came a completely unknown feature, even for developers like myself: a price tag. This is the first time that Xcode has ever had a price. Since the release of OS X, Xcode (and its predecessor Project Builder) have been available free of charge.</p>

<p>At the time, having a full, professional grade IDE available for free was mostly unheard of. Compared with Visual Studio, who&#8217;s minimum entrance fee was in the range of $1000. Students, of course, got a discount. Since then having a free IDE on your platform has become the norm. If this is because of Xcode or not, I am not sure.</p>

<p>Suddenly, for the first time, Xcode has a price for non-paid developers: $4.99. There has been an uproar as to what open source developers and people who are interested in learning to program will do. That Apple is somehow taking away a lot from developers by adding this barrier to entry. I would argue, they aren&#8217;t.</p>

<p>Open source developers often list Xcode as a dependency for those that wanted to compile from source, not because the project required Xcode, but because it installed the requisite compilers. If having Xcode as a dependency is  not something that developers want, then the community is going to need to pick up the slack as per keeping the toolchain current and packaged.  As these tools are open source, it shouldn&#8217;t be that difficult to do (although we do know what happens when we say shouldn&#8217;t&#8230;.)</p>

<p>Ignoring the argument that if you can afford a Mac, and you&#8217;re interested in learning to program, you can afford $5 dollars for tools to develop with. More than likely, the book you pick up to learn Objective-C will cost a heck of a lot more than that.</p>

<p>At the end of the day, any serious mac developer is going to have the $99 dollar subscription to the Mac developer program. If you&#8217;re looking to learn to program for the Mac, 5 dollars is a minimal investment for access to a world class development tools. If you&#8217;re just looking to program on your Mac but don&#8217;t want to spend the $5 for Xcode or $99 for the developer subscription, learn a language different than Objective-C. There are many build in programming languages in OSX, including Python and Ruby.</p>

<p>As for me? I will keep my paid developer accounts ignore the rest of the uproar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/thoughts-on-xcode-4-price/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to Create Realistic Buttons with CSS3</title>
		<link>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/</link>
		<comments>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 04:51:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=168</guid>
		<description><![CDATA[In a modern web application we don&#8217;t really use buttons (ala the input tag) so much. More often than not, we use some kind of div or link that when combined with some javascript behaves as a button. I&#8217;m not &#8230; <a href="http://www.james-vandyne.com/creating-realistic-buttons-with-css3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In a modern web application we don&#8217;t really use buttons (ala the input tag) so much. More often than not, we use some kind of div or link that when combined with some javascript behaves as a button. I&#8217;m not going to cover how to hook this all up into your application, but rather just the styling of buttons.</p>

<h3>Problem</h3>

<p>Traditionally, web developers have had to create graphics for every non-standard button they used on their site. This is expensive in terms of time, money, and usability. It takes extra work for our buttons to be assessable, increases load times, and if we ever want to change the wording of our button, we have to start all over again.</p>

<p>Using various features afforded in css3, we can remove the need for images altogether, lower load times (and save bandwidth) while gaining scalability of our user interface, full accessibility, and never have something that is completely reusable throughout our site without any extra work.</p>

<p>We are going to go from the one on the left to the one on the right.</p>

<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/before-after.png"/></p>

<h3>Solution</h3>

<p>First, we need to begin with our basic markup.</p>


<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;a href=&quot;#&quot;&gt;My Button&lt;/a&gt;</pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/no-style.png"/></p>

<p>Because we want to style it and reuse said styles more than once on a page (potentially), we&#8217;re going to want to add a css class name.</p>


<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;a href=&quot;#&quot; class=&quot;gradient_button&quot;&gt;My Button&lt;/a&gt;</pre></div></div>


<p>That&#8217;s all the html markup we will use. From here on out, we will just be adding styles to our stylesheet. The first thing we need to do is decide which color our button needs to be. We need a minimum of 2 colors: one lighter color for the top of the button and one darker color (of the same shade) for the button of the button.</p>

<p>I used the <a href="http://gradients.glrzad.com/" target="_blank">CSS3 Gradient Generator</a> to select my colors and generate the rules. I&#8217;ve picked a grey color for this tutorial. Feel free to pick anything you like. Let&#8217;s set it as the background for our button. Let&#8217;s create our gradient_button selector and add our gradient background</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">a<span style="color: #6666ff;">.gradient_button</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.43</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.72</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #993333;">center</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">43%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">72%</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/gradient.png"/></p>

<p>It&#8217;s ugly, but we&#8217;re getting closer. Next, let&#8217;s add some padding around our button, create a border, and give it rounded corners. Add the following to the gradient_button selector.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span><span style="color: #993333;">solid</span> <span style="color: #933;">1px</span> <span style="color: #cc00cc;">#111</span><span style="color: #00AA00;">;</span>
-webkit-border-radius<span style="color: #00AA00;">:</span><span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
-moz-border-radius<span style="color: #00AA00;">:</span><span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span><span style="color: #933;">5px</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/rounded.png"/></p>

<p>Already we are looking much better and more realistic. However, the text completely throws the button off. It looks like it&#8217;s just pasted on there. We want our text to be a part of the button. We can do that by insetting the text with a shadow. So, next, let&#8217;s remove the text decoration, change the color, and inset that text.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#111</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">bold</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#ffe</span> <span style="color: #933;">0px</span> <span style="color: #933;">1px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">,</span> <span style="color: #cc00cc;">#333</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">-1px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/inset.png"/></p>

<p>Already, you can see our button finally looks like a button. We could stop there, but we should go the extra mile for that last bit of polish. Especially considering how much time we can save because we never have to visit photoshop to make a button again.</p>

<p>First, we need to recognize that objects are never flat. Everything casts a shadow. Our buttons are no different. Remember to try and keep a consistent light source when implementing shadows on your website, my light source is directly above, so I only want to cast a shadow below my button. Add the following to the selector:</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">-moz-box-shadow<span style="color: #00AA00;">:</span>  <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span>
-webkit-box-shadow<span style="color: #00AA00;">:</span>  <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span>
box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">0px</span> <span style="color: #933;">2px</span> <span style="color: #933;">5px</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/shadow.png"/></p>

<p>Our button now looks great. Try clicking on it. Notice that? It maybe look like a button, but it surely doesn&#8217;t behave like a button. We can fix that by adding one more selector. We need to style the :active state of the link, which is displayed when a button is pressed.</p>

<p>When picturing a physical button pressed, what sort of changes we see? I imagine that the shadow would disappear, as the button is now becoming flat with the surface from which it protrudes. Also, I imagine that the shine of our gradient would change. I think that it would become almost a solid color, but not quite. Let&#8217;s one last style to make our button behave a lot more naturally when clicked.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">a<span style="color: #3333ff;">:active</span><span style="color: #6666ff;">.gradient_button</span> <span style="color: #00AA00;">&#123;</span>
	-webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	-moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	box-shadow<span style="color: #00AA00;">:</span><span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span><span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.18</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.59</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>color-stop<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">0.8</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> -moz-linear-gradient<span style="color: #00AA00;">&#40;</span><span style="color: #993333;">center</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">18%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">176</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">59%</span><span style="color: #00AA00;">,</span><span style="color: #993333;">rgb</span><span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">234</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">237</span><span style="color: #00AA00;">&#41;</span> <span style="color: #933;">80%</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><img src="http://www.james-vandyne.com/wp-content/uploads/2011/03/pushed.png"></p>

<p>There we have it. A completely realistic button using nothing but CSS3 and a hyperlink.</p>

<h3>Conclusion</h3>

<p>CSS3 buttons allows us to save time (and therefore money) when developing a modern web application. Moreover, we get fringe benefits such as being able to make our website more accessible and fully scalable for free.</p>

<p><a href="http://www.james-vandyne.com/wp-content/uploads/2011/03/gradient_button.html" target="_blank">View Realistic CSS3 Button</a></p>

<h3>Update:</h3>

<p>This doesn&#8217;t work in IE. If you&#8217;d like to use a similar effect for the gradient, you can use the IE filter styles. The major caveat is that IE only seems to render these with a div wrapper or an absolute position. The div wrapper really kills the elegance of being able to have any link suddenly look and behave like a regular button with a single style. I recommend a graceful-degradation in IE, and just set the background color to a be solid.</p>

<p>The css for getting the same gradient effect in IE is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">	<span style="color: #808080; font-style: italic;">/* For Internet Explorer 5.5 - 7 */</span>
	filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.gradient<span style="color: #00AA00;">&#40;</span>startColorstr<span style="color: #00AA00;">=</span><span style="color: #cc00cc;">#EDEAED</span><span style="color: #00AA00;">,</span> endColorstr<span style="color: #00AA00;">=</span><span style="color: #cc00cc;">#B0B0B0</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
	<span style="color: #808080; font-style: italic;">/* For Internet Explorer 8 */</span>
	-ms-filter<span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;progid:DXImageTransform.Microsoft.gradient(startColorstr=#EDEAED, endColorstr=#B0B0B0)&quot;</span><span style="color: #00AA00;">;</span>
	<span style="color: #808080; font-style: italic;">/* graceful-degradation when the filter doesn't work */</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#EDEAED</span><span style="color: #00AA00;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/creating-realistic-buttons-with-css3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>8 Things I Learned About Software Development (Without writing code)</title>
		<link>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/</link>
		<comments>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 09:02:26 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=146</guid>
		<description><![CDATA[In 2009 I set out to make a major elease of my Japanese-English dictionary Jisho 4.0. Jisho 4.0 was to be a complete overhaul of the existing codebase and a 100% new interface. After a scrapped interface and a few &#8230; <a href="http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In 2009 I set out to make a major elease of my Japanese-English dictionary <a title="Japanese English Dictionary Jisho" href="http://www.sugoisoft.com/jisho/">Jisho 4.0</a>. Jisho 4.0 was to be a complete overhaul of the existing codebase and a 100% new interface.</p>

<p>After a scrapped interface and a few delays, I forced myself stop adding new features and move the &#8220;nice to haves&#8221; into a future release. Jisho 4.0 was shipped in December 2009.</p>

<p>Soon after the 4.0 release I began work on Jisho 4.1 to take care of these issues. Jisho 4.1 was released in January 2011. The development time was quite long, but most of it was not spent writing code. Below are some lessons I learned while developing Jisho 4.1.</p>

<h2>Define the scope of the release</h2>

<p>Define features or fixes in a given release and stick to it. With a proper scope written there will be no second guessing if your program is ready to ship. Have you implemented the planned changes? Yes? Ship.</p>

<h2>Keep it limited</h2>

<p>If it sounds like it could be broken into multiple releases, it probably should be. Try to keep releases small. I made the mistake of trying to refactor the backend to improve search and add in some new UI features for a single release. The end result was looking 3 major undertakings directly after a major release was paralyzing.</p>

<h2>Fully plan an interface before committing to development of a feature</h2>

<p>Fully plan how a feature is going to work and integrate with the rest of the application before committing to develop it for a particular release.</p>

<p>With Jisho 4.1, I wanted to refine the interface so the user could see kanji in a larger view. I hadn&#8217;t planned the interaction properly and a clean design was not forth coming.</p>

<p>I spent the majority of development time trying various interactions that inevitably felt unnatural. Simply planning this refinement more completely would have told me it&#8217;s enough for it&#8217;s own release.</p>

<h2>Push features to if it means you can release</h2>

<p>If you have a feature that is sapping development time and holding up bug fixes or already completed features, push it. There&#8217;s no shame in pushing a feature to a future release so your users can get better software today.</p>

<p>Users tend to get upset if you promise a feature for a given release and then pull it. So, this lesson is most applicable if you don&#8217;t promise particular features while they are still in development or even before they are released.</p>

<h2>Git (or your scm of choice) is a good thing</h2>

<p>Creating a branch for development of a new feature is a great way to make it easy to revert to a prior version so you can release. If you only merge branches once the fix or feature is stable and complete, you will always have a stable version ready.</p>

<p>I just started using Git before the development of 4.0. Before that I was coding dangerously with random zip archives of the code, usually at each point release, and a changelog that only mentioned the changes the end-user would see.</p>

<h2>Lower the barrier</h2>

<p>The more steps required when releasing a piece of software has the same effect as adding steps during checkout. You&#8217;re going to lose a lot of people (or in our case inertia) towards making an actual release. Simply your release process as much as possible.</p>

<p>Until 4.1, Jisho was distributed as a dmg for new users. This dmg had a custom background, readme, shortcut to the applications folder. Each release was built by hand. I would spend a good hour crafting this dmg for each release.</p>

<p>Now Jisho 4.1 is simply distributed as a zip file of the application. I still have to zip / upload it manually at this point, which takes 2 minutes, but that&#8217;s still an extra step. Future plans include automating the entire process from within Xcode.</p>

<h2>Release something</h2>

<p>Releasing is like software food. Software lives by releasing new versions. The quickest way to kill a software project is to get weighed down by a single non-critical feature of fix.</p>

<p>The guilt associated with keeping fixes out of the hands of your users in the name of an unannounced feature will only grow with time. Assuming you haven&#8217;t pre-announced the feature, users won&#8217;t know what they&#8217;re missing. If you have, they might complain a bit, but most users would rather have something new rather than nothing.</p>

<h2>It&#8217;s not too late</h2>

<p>If you find yourself agreeing with any of this, stop reading this and figure out the fastest way to get a release out the door. It&#8217;s not to late to release something.</p>

<p>Jisho was well on it&#8217;s way to death by starvation. By reverting to the latest stable version and cutting the features that were holding up release I was able to breath life back into Jisho.</p>

<p>Was the release technically what one would consider a release worthy of a new sub-number version release? By itself &#8211; probably not*. However, the principal still stands &#8211; if your software looks like it&#8217;s starving, cut whatever you need to and feed it now. Failing to do so may inadvertently cause the death of your project.</p>

<hr />

<p><small>
* There were <a href="http://www.sugoisoft.com/blog/2011/01/09/jisho-4-1-and-the-mac-app-store/">other factors at play</a> with the version number, which I written about on the  <a href="http://www.sugoisoft.com/blog/">Sugoi Software blog</a>.
</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/8-things-i-learned-about-software-development-without-writing-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Process Paypal IPN Requests Through WordPress</title>
		<link>http://www.james-vandyne.com/process-paypal-ipn-requests-through-wordpress/</link>
		<comments>http://www.james-vandyne.com/process-paypal-ipn-requests-through-wordpress/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 15:38:41 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Paypal]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.james-vandyne.com/?p=36</guid>
		<description><![CDATA[Introduction Paypal is perhaps the easiest way to send/receive money online and WordPress is perhaps the most popular blogging platform out there. Wouldn&#8217;t it be great if there was a way we could integrate them together? There are currently a &#8230; <a href="http://www.james-vandyne.com/process-paypal-ipn-requests-through-wordpress/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>

<p>Paypal is perhaps the easiest way to send/receive money online and WordPress is perhaps the most popular blogging platform out there. Wouldn&#8217;t it be great if there was a way we could integrate them together?</p>

<p>There are currently a number of plugins available that allow you use WordPress with paypal for invoicing customers and such. However if you want to do anything custom you are going to need to process IPNs (Instant Payment Notifications) yourself.</p>

<h3>Problem</h3>

<p>One could easily just put a php file on their server to process the IPN independently of WordPress. However if you want to interact with your database at all you have three basic options:</p>

<ol>
<li>Hardcode your database settings in your IPN processor.  </li>
<li><em>include</em> your wp-config.php and pull the database settings from that manually.</li>
<li>Integrate with WordPress so you can use the <em>$wpdb</em> object in your plugin ( I assume that you are developing your own larger plugin and paypal support is part of that).</li>
</ol>

<p>Hardcoding your settings is fine for one off scripts, but if you change servers you could easily forget to update your settings breaking your website or worse: stopping people from giving you money!</p>

<p>Including your wp-config.php has a number of drawbacks. It makes certain assumptions that break your software. Namely it assumes that wp-config.php is a directory or two up in <em>../../wp-config.php</em> or something of that nature. As WordPress allows you to have you config file in other locations e.g. not ../../wp-config.php this is very risky business.</p>

<p>Integrating with WordPress allows the user to use the plugin without any extra configuration to access their database. If WordPress can access the database so can we. We also get access to some wordpress convenience methods &#8211; always a plus.</p>

<p>To be able to access the $wpdb object requires WordPress initialize and for the IPN somehow call our plugin. Obviously telling Paypal to send its requests to <em>/wp-content/plugins/my_plugin/ipn_listener.php</em> is a bad idea ( and I don&#8217;t think it would even work).</p>

<h3>Solution</h3>

<p>Let&#8217;s ponder for a moment <em>how</em> WordPress processes our requests. 
Usually we see the exact details of the request and they look pretty thanks to mod_rewrite. A typical request would look something like</p>


<div class="wp_syntax"><div class="code"><pre class="url" style="font-family:monospace;">http://example.com?/2009/08/01/delicious-cheese</pre></div></div>


<p>Or as WordPress sees it:</p>


<div class="wp_syntax"><div class="code"><pre class="url" style="font-family:monospace;">http://example.com?year=2009&amp;month=08&amp;day=01&amp;name=delicious-cheese.</pre></div></div>


<p>Understanding this, my solution was to build upon this and direct the IPN to index.php with some extra variables set.</p>


<div class="wp_syntax"><div class="code"><pre class="url" style="font-family:monospace;"> http://www.example.com?my_plugin=paypal.</pre></div></div>


<p>Now that we&#8217;ve got that far. Next we need to tell WordPress to be on the look out and accept more variable names from the request. We do this by adding a filter to query_vars. We have to do this because WordPress ignores them if we don&#8217;t in an effort to prevent processing unknown and possibly malicious inputs.<cite>1</cite></p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_plugin_query_vars<span style="color: #009900;">&#40;</span><span style="color: #000088;">$vars</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// add my_plugin to the valid list of variables</span>
	<span style="color: #000088;">$new_vars</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'my_plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$vars</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$new_vars</span> <span style="color: #339933;">+</span> vars<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$vars</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query_vars'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_plugin_query_vars'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Now that WordPress accepts GET variables with the name my_plugin it&#8217;s time to do something with that. We add an action on parse_request which gives us first change to parse given request before WordPress does.</p>

<p>Notice that we check to make sure that our specified variable exists and is the value we are expecting. If we do not do this we end up processing all requests. <cite>2</cite> Once we have confirmed that both our GET variable and is the name we expect we call the function in our plugin that processes the IPN.</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> muy_plugin_parse_request<span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// only process requests with &quot;my_plugin=paypal&quot;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'my_plugin'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$wp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query_vars</span><span style="color: #009900;">&#41;</span> 
            <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$wp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query_vars</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'my_plugin'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'paypal'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        my_plugin_proccess_paypal_ipn<span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'parse_request'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_plugin_parse_request'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>As per processing the IPN you can start by simply copy/pasting the Paypal sample code in the function. You then access your database using the $wpdb object. Don&#8217;t forget that it&#8217;s global so you must first</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">;</span></pre></div></div>


<p>before you can access it.</p>

<h3>Update</h3>

<p>I thought we were finished but we aren&#8217;t. The above works fine with Paypal&#8217;s Tester IPN as it doesn&#8217;t check URLs. Paypal does not allow you to active your IPN in Paypal if a given URL has GET arguments.</p>

<p>We can fix this with just a little more code and the magic of mod_rewrite. First you will need to enable mod_rewrite in WordPress (Options -> Permalinks) by selecting one that is non-default e.g. Day and name.</p>

<p>Then we need to add a hook in WordPress rewrite system and then create a rule that tell WordPress to forward all requests to</p>


<div class="wp_syntax"><div class="code"><pre class="url" style="font-family:monospace;">http://example.com/my_plugin/paypal</pre></div></div>


<p>to</p>


<div class="wp_syntax"><div class="code"><pre class="url" style="font-family:monospace;">http://example.com/?my_plugin=paypal</pre></div></div>


<p>The code to do this is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'generate_rewrite_rules'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_plugin_rewrite_rules'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_plugin_rewrite_rules<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wp_rewrite</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$new_rules</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'my_plugin/paypal'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'index.php?my_plugin=paypal'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$wp_rewrite</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rules</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$new_rules</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$wp_rewrite</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rules</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<h3>Notes</h3>

<p><cite>1</cite> If you wish to access the paypal and other variables (both GET and POST) via $wp->query_vars you must declare them in your query_vars filter as well. Since there are loads of them with paypal this may or may not be worth the effort.</p>

<p><cite>2</cite> It might not hurt to make the value a bit more obscure e.g. ei190A0F (random gibberish). Another side bonus is you could also add support for other services quite easily.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.james-vandyne.com/process-paypal-ipn-requests-through-wordpress/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

