<?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>Bradley Holt &#187; Best Practices</title>
	<atom:link href="http://bradley-holt.com/tag/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://bradley-holt.com</link>
	<description></description>
	<lastBuildDate>Fri, 06 Jan 2012 18:57:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>The Twelve-Factor App Applied to PHP</title>
		<link>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/</link>
		<comments>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 16:31:02 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Deployment]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Twelve-Factor App]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1451</guid>
		<description><![CDATA[If you develop web apps, I encourage you to check out The Twelve-Factor App. This is an excellent resource for anyone building and deploying software-as-a-service. PHP has great support for many of the twelve-factors. I want to take a look at specifically how each factor may be applied to a PHP application. I. Codebase &#8220;One [...]]]></description>
			<content:encoded><![CDATA[<p>If you develop web apps, I encourage you to check out <a href="http://www.12factor.net/">The Twelve-Factor App</a>. This is an excellent resource for anyone building and deploying software-as-a-service. PHP has great support for many of the twelve-factors. I want to take a look at specifically how each factor may be applied to a PHP application.</p>
<h3>I. <a href="http://www.12factor.net/codebase">Codebase</a></h3>
<blockquote><p>&#8220;One codebase tracked in revision control, many deploys&#8221;</p></blockquote>
<p>There&#8217;s really not much here that would be different in PHP versus any other language. Who isn&#8217;t using some form of revision control these days?</p>
<h3>II. <a href="http://www.12factor.net/dependencies">Dependencies</a></h3>
<blockquote><p>&#8220;Explicitly declare and isolate dependencies&#8221;</p></blockquote>
<p>There are a few tools available to PHP developers to help manage dependencies. The <a href="http://pear.php.net/">PEAR</a> package manager may help here, but has its flaws. <a href="http://pear2.php.net/PEAR2_Pyrus">Pyrus</a>, the PEAR2 package manager, looks promising. There&#8217;s also <a href="http://packagist.org/about-composer">Composer</a>. I&#8217;ve heard of people using their operating system&#8217;s package manager (e.g. RPM) to deploy their PHP applications and manage dependencies. I&#8217;m not sure if there any tools in PHP to enforce <em>dependency isolation</em>.</p>
<h3>III. <a href="http://www.12factor.net/config">Config</a></h3>
<blockquote><p>&#8220;Store config in the environment&#8221;</p></blockquote>
<p>The simplest option here is to use <em>environment variables</em>. Many frameworks, including Zend Framework, allow you to have environment-specific configuration such as <code>development</code>, <code>test</code>, and <code>production</code>. This is not recommended for twelve-factor apps as it doesn&#8217;t scale as new environments are added.</p>
<h3>IV. <a href="http://www.12factor.net/backing-services">Backing Services</a></h3>
<blockquote><p>&#8220;Treat backing services as attached resources&#8221;</p></blockquote>
<p>There&#8217;s not really anything to say here that&#8217;s specific to PHP.</p>
<h3>V. <a href="http://www.12factor.net/build-release-run">Build, release, run</a></h3>
<blockquote><p>&#8220;Strictly separate build and run stages&#8221;</p></blockquote>
<p><a href="http://www.phing.info/trac/">Phing</a> or the more general-purpose <a href="http://ant.apache.org/">Ant</a> could work here. Even though it&#8217;s not written in PHP, there&#8217;s no reason why you couldn&#8217;t use <a href="https://github.com/capistrano/capistrano/wiki">Capistrano</a> for this. I don&#8217;t think the <em>run stage</em> typically applies to PHP, as it happens implicitly as part of the <em>release stage</em>. However, there are tasks such as flushing the APC cache (if <code>apc.stat=0</code>) that might be considered part of the <em>run stage</em>.</p>
<h3>VI. <a href="http://www.12factor.net/processes">Processes</a></h3>
<blockquote><p>&#8220;Execute the app as one or more stateless processes&#8221;</p></blockquote>
<p>PHP processes are already stateless and <a href="http://en.wikipedia.org/wiki/Shared_nothing_architecture">shared-nothing</a>. This makes PHP a great fit for twelve-factor apps. Memory space or the filesystem should be used as a short-lived, single-process cache. If you&#8217;re using an asset manager, such as <a href="https://github.com/kriswallsmith/assetic">Assetic</a>, then any assets should be compiled and cached during the <a href="http://www.12factor.net/build-release-run">build stage</a>.</p>
<h3>VII. <a href="http://www.12factor.net/port-binding">Port binding</a></h3>
<blockquote><p>&#8220;Export services via port binding&#8221;</p></blockquote>
<p>I don&#8217;t think port binding applies to PHP applications—at least not in the way it&#8217;s meant in twelve-factor. PHP relies on a web server and uses something like <a href="http://www.fastcgi.com/">FastCGI</a> or <a href="http://php-fpm.org/">PHP-FPM</a> to communicate with the web server. PHP 5.4 will have its own built-in web server, but this is intended for development use only. It&#8217;s really the combination of PHP and its web server that will be bound to a port. This brings up challenges when it comes to dependency management, as the web server itself is now a dependency.</p>
<h3>VIII. <a href="http://www.12factor.net/concurrency">Concurrency</a></h3>
<blockquote><p>&#8220;Scale out via the process model&#8221;</p></blockquote>
<p>I&#8217;m not sure how processes would become first-class citizens in a PHP web application. However, each individual request/response cycle is handled by its own process. In that regard, PHP already uses the process model.</p>
<h3>IX. <a href="http://www.12factor.net/disposability">Disposability</a></h3>
<blockquote><p>&#8220;Maximize robustness with fast startup and graceful shutdown&#8221;</p></blockquote>
<p>PHP processes are very disposable. Again, this is just part of how PHP works.</p>
<h3>X. <a href="http://www.12factor.net/dev-prod-parity">Dev/prod parity</a></h3>
<blockquote><p>&#8220;Keep development, staging, and production as similar as possible&#8221;</p></blockquote>
<p>Nothing specific to PHP here. Although, it&#8217;s not uncommon for PHP developers to use SQLite in development and MySQL or PostgreSQL in production. This is not recommended for a twelve-factor app—use the same software and versions of <a href="http://www.12factor.net/backing-services">backing services</a> in all environments.</p>
<h3>XI. <a href="http://www.12factor.net/logs">Logs</a></h3>
<blockquote><p>&#8220;Treat logs as event streams&#8221;</p></blockquote>
<p>There are tons of logging options in PHP. <a href="http://framework.zend.com/manual/en/zend.log.writers.html#zend.log.writers.stream"><code>Zend_Log_Writer_Stream</code></a> lets you send log data to a <a href="http://www.php.net/stream">PHP stream</a>. Alternatively, <a href="http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/">StatsD and the PHP StatsD library</a> look pretty good.</p>
<h3>XII. <a href="http://www.12factor.net/admin-processes">Admin processes</a></h3>
<blockquote><p>&#8220;Run admin/management tasks as one-off processes&#8221;</p></blockquote>
<p>This is easy enough in PHP. If you want an interactive shell with readline history, tab completion, and quick access to documentation then check out <a href="http://www.phpsh.org/">phpsh</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/11/the-twelve-factor-app-applied-to-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One Web</title>
		<link>http://bradley-holt.com/2011/03/one-web/</link>
		<comments>http://bradley-holt.com/2011/03/one-web/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 16:41:50 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Mobile Computing]]></category>
		<category><![CDATA[One Web]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/?p=1027</guid>
		<description><![CDATA[Almost two years ago, Luke Wroblewski first described a trend in web development called mobile first. The basic idea was that web applications should be designed for mobile first, as opposed to designed for the desktop first. Luke provided some compelling reasons for this including the explosive growth of mobile adoption, the fact that mobile [...]]]></description>
			<content:encoded><![CDATA[<p>Almost two years ago, Luke Wroblewski first described a trend in web development called <a href="http://www.lukew.com/ff/entry.asp?933">mobile first</a>. The basic idea was that web applications should be designed for mobile first, as opposed to designed for the desktop first. Luke provided some compelling reasons for this including the explosive growth of mobile adoption, the fact that mobile forces you to focus on key areas of your application, and that mobile extends your capabilities. Today I saw <a href="https://twitter.com/shiflett/status/52391738085605376">this tweet from Chris Shiflett</a>:</p>
<blockquote><p>The Web still trumps the Mobile Web. If you’re making a web app, don’t let “mobile first” lead you astray.</p></blockquote>
<p>Luke&#8217;s original premise is not wrong, but I think many web developers have interpreted &#8220;mobile first&#8221; as &#8220;mobile only&#8221;—often intentionally, sometimes by accident. As Chris pointed out, it&#8217;s easy to let &#8220;mobile first&#8221; lead you astray. My response to Chris was that the goal should be <a href="http://www.w3.org/TR/mobile-bp/#OneWeb"><em>One Web</em></a>, even if &#8220;mobile first&#8221;. &#8220;Mobile only&#8221; should rarely, if ever, be the goal. The concept of One Web is described in the W3C&#8217;s <a href="http://www.w3.org/TR/mobile-bp/">Mobile Web Best Practices 1.0 Basic Guidelines</a>. From the original document:</p>
<blockquote><p>The recommendations in this document are  intended to improve the experience of the Web on mobile devices. While  the recommendations are not specifically addressed at the desktop  browsing experience, it must be understood that they are made in the  context of wishing to work towards &#8220;One Web&#8221;.</p>
<p>As discussed in the Scope document <a href="http://www.w3.org/TR/mobile-bp/#Scope">[Scope]</a>, <em>One Web</em> means making, as far as is reasonable, the same information and  services available to users irrespective of the device they are using.  However, it does not mean that exactly the same information is available  in exactly the same <a href="http://www.w3.org/TR/di-gloss/#def-http-representation">representation</a> across all devices. The context of mobile use, device capability  variations, bandwidth issues and mobile network capabilities all affect  the representation. Furthermore, some services and information are more  suitable for and targeted at particular user contexts (see <a href="http://www.w3.org/TR/mobile-bp/#tc">5.1.1 Thematic Consistency of Resource Identified by a URI</a>).</p></blockquote>
<p>Let&#8217;s not let the web fragment into a &#8220;mobile web&#8221;, a &#8220;desktop web&#8221;, and a &#8220;whatever comes next&#8221; web—there&#8217;s no reason for this. The underlying technology is designed to allow for One Web, as <a href="https://twitter.com/ramsey/status/52393492273561600">Ben Ramsey added</a>:</p>
<blockquote><p>@<a href="http://twitter.com/BradleyHolt">BradleyHolt</a> @<a href="http://twitter.com/shiflett">shiflett</a> This is why we have content types, accept headers, user agent strings, and content negotiation. <img src='http://bradley-holt.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p></blockquote>
<p>If you&#8217;re considering taking a mobile first approach, please consider taking the One Web approach instead. Your main focus can be on mobile to start, but at least deliver <em>something</em> of value that is not dependent on the client being a mobile device. As Ben suggested, use content types, accept headers, user agent strings, and <a href="http://en.wikipedia.org/wiki/Content_negotiation">content negotiation</a> to deliver the best experience based on your user&#8217;s device or browser.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2011/03/one-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Phing Build Script</title>
		<link>http://bradley-holt.com/2010/01/phing-build-script/</link>
		<comments>http://bradley-holt.com/2010/01/phing-build-script/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 16:03:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Phing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Deployment]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2010/01/phing-build-script/</guid>
		<description><![CDATA[I&#8217;ve been experimenting with using Phing to automate building and deploying web applications. I want to share one of my build scripts and perhaps get some feedback from anyone with more experience using Phing. The requirements for the build script are fairly simple: It will not handle deployment. This particular web application is deployed by [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been experimenting with using <a href="http://phing.info/">Phing</a> to automate building and deploying web applications. I want to share one of my build scripts and perhaps get some feedback from anyone with more experience using Phing. The requirements for the build script are fairly simple:</p>
<ul>
<li>It will <em>not</em> handle deployment. This particular web application is deployed by the client&#8217;s IT department.</li>
<li>It <em>will</em>  create a ZIP file (it could just as easily create a tar.gz file) that the client&#8217;s IT department can extract and deploy.</li>
<li>It <em>will</em> rename the document root since the document root is a different directory name in the client&#8217;s production environment then it is in our development and testing environments.</li>
</ul>
<p>Next, an outline of what the build does:</p>
<ol>
<li>Prompt for Subversion credentials (I&#8217;d rather not store these in a file).</li>
<li>Prompt for the Subversion tag to build from.</li>
<li>Delete the source directory if it exists.</li>
<li>Export the given tag to the source directory.</li>
<li>Rename the document root.</li>
<li>Create a ZIP file, named after the version, of the source directory&#8217;s contents.</li>
<li>Clean up after itself by deleting the source directory.</li>
</ol>
<p>Both of the build files are in the project&#8217;s root directory (in my project, this is one directory above the document root). The <a href="http://gist.github.com/273555#file_build.properties">build.properties</a> file defines three properties: document root (so we can rename it to this new name), the source directory (the place to export to and then manipulate folders/files), and the URL to the repository&#8217;s tags directory.</p>
<p><script src="http://gist.github.com/273555.js?file=build.properties"></script>
<p>The <a href="http://gist.github.com/273555#file_build.xml">build.xml</a> file is the actual build script, performing the actions outlined above. I&#8217;ve obfuscated the project name to be &#8220;acme&#8221;. I could not find a way to create a prompt that hides the Subversion password as it is entered (anyone?). For renaming the document root, I used the <code>exec</code> task to execute a move (<code>mv</code>) command since the <code>move</code> task failed for me (so this script will not work as-is on Windows).</p>
<p><script src="http://gist.github.com/273555.js?file=build.xml"></script>
<p>Executing this script is as easy as running <code>phing build-tag</code> (once Phing is installed) from within the project&#8217;s root directory. Please let me know if you have any questions or see any room for improvement.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/01/phing-build-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Design and Web Development</title>
		<link>http://bradley-holt.com/2010/01/web-design-and-web-development/</link>
		<comments>http://bradley-holt.com/2010/01/web-design-and-web-development/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 21:36:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Mobile Computing]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2010/01/web-design-and-web-development/</guid>
		<description><![CDATA[Back in October, Jeffrey Zeldman tweeted something that I strongly agree with: Real web designers write code. Always have, always will. #aea This sparked many conversations including these two tweets from Chris Shiflett: According to @zeldman, real web designers write code. (I think he means HTML and CSS, not PHP, Perl, and Python.) What do [...]]]></description>
			<content:encoded><![CDATA[<p>Back in October, Jeffrey Zeldman <a href="http://twitter.com/zeldman/statuses/4818978868">tweeted</a> something that I strongly agree with:</p>
<blockquote><p>Real web designers write code. Always have, always will. <a href="http://twitter.com/search?q=%23aea">#aea</a></p>
</blockquote>
<p>This sparked many conversations including these <a href="http://twitter.com/shiflett/status/4819361797">two</a> <a href="http://twitter.com/shiflett/status/4820055234">tweets</a> from Chris Shiflett:</p>
<blockquote><p>According to @<a href="http://twitter.com/zeldman">zeldman</a>, real web designers write code. (I think he means HTML and CSS, not PHP, Perl, and Python.) What do you think?</p>
</blockquote>
<blockquote><p>I’ve now asked, separately, whether developers and designers should know HTML and CSS. In both cases, most think they should. Interesting.</p>
</blockquote>
<p>To which I <a href="http://twitter.com/BradleyHolt/status/4820141311">responded</a> (brackets added):</p>
<blockquote><p>@<a href="http://twitter.com/shiflett">shiflett</a> IMHO, the demarcation between web developers and web designers should be POSH [<a href="http://microformats.org/wiki/posh">Plain Old Semantic HTML</a>]. That&#8217;s what both need to know.</p>
</blockquote>
<p>I have a pretty strong opinion about this. You could say that I have the luxury of working with an <a href="http://foundline.com/people/jason-pelletier">excellent designer</a> who implements all of his own CSS—even tackling much of the JavaScript coding on websites we build. To be clear: he is a designer, not a developer—working in both print (which is more technical than you might think) and web.</p>
<p>The typical process is summarized well in Marco Tabini&#8217;s <a href="http://phpadvent.org/2009">PHP Advent 2009</a> post on <a href="http://phpadvent.org/2009/css-and-other-people-by-marco-tabini">CSS and Other People</a>:</p>
<blockquote><p>From a developer’s perspective, “design work” means having to deal with the often hated, sometimes impossible, and always challenging task of translating a designer’s <em>comp</em> into a combination of HTML and CSS that will render properly on browsers that are often at complete odds with one another.</p>
</blockquote>
<p>In my opinion, that process is broken. Why is it assumed that because HTML and CSS are &#8220;code&#8221; it should be a developer&#8217;s job to implement these? Any decent designer is already familiar with the concept of separating presentation and content with <a href="http://en.wikipedia.org/wiki/Style_sheet_%28desktop_publishing%29">style sheets</a> (which are supported in Adobe InDesign, QuarkXPress, and even PageMaker and Microsoft Word). Is learning HTML and CSS, both <a href="http://en.wikipedia.org/wiki/Declarative_programming">declarative languages</a>, considered too hard for designers?</p>
<p>Let&#8217;s take a look at comps and the dreaded &#8220;s&#8221; word—slicing. As Marco pointed out, trying to &#8220;slice&#8221; a comp into HTML and CSS is &#8220;sometimes impossible&#8221; and &#8220;always challenging.&#8221; If a designer is only providing a comp, and not the HTML and CSS, it is very likely that the designer does not have a solid understanding of things like <a href="http://en.wikipedia.org/wiki/Progressive_enhancement">progressive enhancement</a>, browser compatibility, and even what is possible on the web.</p>
<p>The use of a comp generally assumes that design is purely visual and that all representations of the web page should look exactly like the comp. How should the content be presented to screen readers, to mobile devices, and in print? Sure, you could provide comps for each of these scenarios but this is not scalable and you quickly risk violating the &#8220;<a href="http://www.w3.org/TR/mobile-bp/#OneWeb">One Web</a>&#8221; concept. Thinking of a web page through the lens of only one specific visual representation of that page is very limiting.</p>
<p>Do you agree that the typical process is broken? If so, what are the barriers to fixing this process? Do we need better trained web designers? Do organizations need to be educated on how to better structure their web teams? This problem will eventually self-correct. My prediction is that teams with web designers that know HTML and CSS will create better websites and web applications and be more successful than teams using the old process.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2010/01/web-design-and-web-development/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Open (local) Government</title>
		<link>http://bradley-holt.com/2009/04/open-local-government/</link>
		<comments>http://bradley-holt.com/2009/04/open-local-government/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 01:51:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[BTV]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[FOSS]]></category>
		<category><![CDATA[Open Standards]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2009/04/open-local-government/</guid>
		<description><![CDATA[Last night I went to the Burlington, Vermont City Council meeting to listen to our newly re-elected mayor, Bob Kiss, give his State of the City speech and watch the City Council attempt to elect a new council president. I said &#8220;attempt&#8221; because, after 14 rounds of voting, they were still deadlocked 7-7 for opposing [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I went to the Burlington, Vermont City Council meeting to listen to our newly re-elected mayor, Bob Kiss, give his State of the City speech and watch the City Council attempt to elect a new council president. I said &#8220;attempt&#8221; because, after 14 rounds of voting, they were still deadlocked 7-7 for opposing candidates. However, that&#8217;s not what I want to talk about. In Mayor Bob Kiss&#8217; speech he made the following statement:</p>
<blockquote><p>My administration worked closely with the Open Government Committee formed by resolution of the City Council. In response to committee recommendations, we’ve included more information about public meetings on the City web-site and the Planning Department added a new section about proposed and pending zoning amendments. During the campaign it was clear that people want to know more about the activities of each city department. Over the next year we’ll look closely at how to finance and build a more uniform, responsive and user-friendly City website that will keep you better informed about public meetings and how you can participate in the process of government.</p></blockquote>
<p>I&#8217;m all for open government and the <a href="http://www.ci.burlington.vt.us/">City of Burlington, Vermont</a> could certainly use a better website. I&#8217;d like to give the city some advice on its priorities in building a better website. This blog post is my first round of advice, but I&#8217;d like to hear reactions from other web people in and around Burlington — or anyone else who has an interest in our city having a better website! This advice is based on the goals outlined by Mayor Bob Kiss: that the website is inline with the spirit of Open Government, is responsive, and is user-friendly.</p>
<p>First, the website must be accessible and use open standards. I put these two together because by using open standards the website can be accessible. Specifically, the website should use strictly semantic XHTML. This allows for its use in the widest range of user agents (browsers) by the widest range of user abilities (as opposed to disabilities). Its presentation should be progressively enriched through CSS and its behavior should be progressively enhanced through unobtrusive JavaScript. Progressive enhancement means that the website is useful, at its core, without any CSS or JavaScript. It becomes more useful through the use of CSS and then, perhaps, even more useful through the use of JavaScript. However, neither CSS nor JavaScript should be required to access the website&#8217;s content.</p>
<p>Second, the website should be built using free (as in freedom, not cost) and open source software. It is our government&#8217;s responsibility to use non-proprietary software wherever possible. When it comes to building websites and web applications, there are no excuses for not using free and open source software. The capabilities of the open web platforms available equal, or exceed, the capabilities of proprietary web platforms. Any custom software developed for the city&#8217;s website must be licensed to the city under a free and open source license (this does not mean that the city shouldn&#8217;t pay for this software to be developed).</p>
<p>Third, the city should embrace the concept of open linked data. This means that the city should publish data, not just content. This data should be both human and machine readable. This allows third parties to access raw data and repurpose this data in new and interesting ways. To this end, data and content should be either put in the public domain (which is probably the case already) or use a Creative Commons license. Where possible, the city&#8217;s website should consume open data published by others rather than duplicating effort. There are several technical approaches to publishing and consuming open linked data including Microformats and the Semantic Web.</p>
<p>I hope these recommendations are useful. Once I&#8217;ve heard some feedback from other web people, I&#8217;ll forward these recommendations to my city councilors and the mayor. Hopefully they&#8217;ll find it helpful in improving the city&#8217;s website!</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2009/04/open-local-government/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The Web Is Not A Visual Medium</title>
		<link>http://bradley-holt.com/2009/03/the-web-is-not-a-visual-medium/</link>
		<comments>http://bradley-holt.com/2009/03/the-web-is-not-a-visual-medium/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 22:50:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Open Standards]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2009/03/the-web-is-not-a-visual-medium/</guid>
		<description><![CDATA[A claim you may have heard me make before is that the web is not a visual medium. Some of you know exactly what I mean and some of you probably think I&#8217;m nuts. For those of you who think I&#8217;m crazy, let me elaborate. You, like most people, probably experience the web visually. However, [...]]]></description>
			<content:encoded><![CDATA[<p>A claim you may have heard me make before is that the web is not a visual medium. Some of you know exactly what I mean and some of you probably think I&#8217;m nuts. For those of you who think I&#8217;m crazy, let me elaborate. You, like most people, probably experience the web visually. However, this visual aspect is only one facet of the web. Underneath the visual aspect you will find that the web is a structured, or <em>semantic</em>, medium. This means that people (or even machines) of varying capabilities (as opposed to disabilities), using all sorts of user agents (a fancy way of saying web browsers) can experience this same web non-visually. If built correctly, the same web page should be accessible to you visually as well as to visually impaired people, search engine robots, people that want to use text only web browsers, people using older versions of web browsers (backward compatibility), people using mobile devices, and user agents that weren&#8217;t even invented yet when the web page was first built (<a href="http://en.wikipedia.org/wiki/Forward_compatibility">forward compatibility</a>).</p>
<p>There&#8217;s one catch. There are <em>many</em> web sites and web applications built on the incorrect assumption that the web is a visual medium. The web designers and web developers who build these web sites and web applications <a href="http://store.mozilla.org/product.php?code=14%2013108&amp;catid=0">break the web</a>. In order to not break the web, web designers and web developers need to use open standards starting with <a href="http://bradley-holt.com/2008/03/plain-old-semantic-html-posh/">plain old semantic (X)HTML</a>. This <em>semantic</em> (X)HTML can then be <a href="http://www.alistapart.com/articles/understandingprogressiveenhancement">progressively enriched/enhanced</a> using <abbr title="Cascading Style Sheets">CSS</abbr> (for presentation) and JavaScript (for behavior). This approach works well with the concept of <a href="http://www.w3.org/TR/mobile-bp/#OneWeb">One Web</a> which &#8220;means making, as far as is reasonable, the same information and services available to users irrespective of the device they are using.&#8221;</p>
<p>Craig Cook has a good article about <a href="http://www.alistapart.com/articles/grokwebstandards">How to Grok Web Standards</a> in which he addresses many of these ideas and more. If you still think I&#8217;m crazy, hopefully it&#8217;s not because you think I&#8217;m wrong about the web not being a visual medium. If you don&#8217;t think I&#8217;m crazy then maybe in another blog post I&#8217;ll talk about why I think that content management systems (CMSs) in general, and WYSIWYG editors specifically, break the web.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2009/03/the-web-is-not-a-visual-medium/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS for Web Developers</title>
		<link>http://bradley-holt.com/2009/01/css-for-web-developers/</link>
		<comments>http://bradley-holt.com/2009/01/css-for-web-developers/#comments</comments>
		<pubDate>Sat, 17 Jan 2009 20:37:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[btvphpug]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Open Standards]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Vermont]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2009/01/css-for-web-developers/</guid>
		<description><![CDATA[The Burlington, VT PHP Users Group will be meeting Thursday January 22nd from from 6:00 pm to 8:00 pm. Since we (Found Line) recently had some demolition &#8211; I mean renovations &#8211; done we&#8217;ve got a bit more space so thought we&#8217;d finally host the meeting. Here&#8217;s a description of the presentation, &#8220;CSS for Web [...]]]></description>
			<content:encoded><![CDATA[<p>The Burlington, VT PHP Users Group will be <a href="http://groups.google.com/group/Burlington-VT-PHP/web/meeting-2009-01-22">meeting</a> Thursday January 22nd from from 6:00 pm to 8:00 pm. Since we (<a href="http://www.foundline.com/">Found Line</a>) recently had some demolition &#8211; I mean <a href="http://picasaweb.google.com/jason.pelletier/StudioConstruction#">renovations</a> &#8211; done we&#8217;ve got a bit more space so thought we&#8217;d finally host the meeting. Here&#8217;s a description of the presentation, &#8220;CSS for Web Developers&#8221;, that Jason will be giving:</p>
<blockquote><p>Most web developers don&#8217;t consider themselves designers—and shouldn&#8217;t. The reality of working on a website or web app, however, is that developers must either wear the designer hat or must interface with a designer/design team. Having a solid understanding of design best practices makes for a more efficient process and a higher quality product. Come hear more about web design and CSS from a designer&#8217;s perspective. We&#8217;ll cover semantic markup and its influence on CSS implementation, reset and debug stylesheets, tools for creating and debugging CSS, coding standards, and maybe even microformats if time allows. The goal isn&#8217;t to convert developers into design experts, but rather to give an overview of an effective design process that works for designers and developers alike.</p>
<p>Jason Pelletier is Creative Director and Web Designer for Found Line. The Burlington-based creative firm develops standards-based websites, product packaging and marketing strategies for growing businesses. Clients include Seventh Generation, Vermont Public Radio, EatingWell and True Body Products. Prior to co-founding Found Line, he managed creative resources for Seventh Generation, and was a designer for Stonyfield Farm.</p></blockquote>
<p>More details <a href="http://groups.google.com/group/Burlington-VT-PHP/web/meeting-2009-01-22">here</a>. Please pass this on to others you think might be interested. Pizza will be provided and we will be giving away a &#8220;<a href="http://store.mozilla.org/product.php?code=14%2013108&amp;catid=0">please don&#8217;t hurt the web &#8211; use open standards</a>&#8221; t-shirt as well as a copy of Jeffrey Zeldman&#8217;s book &#8220;<a href="http://www.zeldman.com/dwws/">Designing With Web Standards</a>&#8220;. Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2009/01/css-for-web-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing Requirements with Unit Tests</title>
		<link>http://bradley-holt.com/2008/09/testing-requirements-with-unit-tests/</link>
		<comments>http://bradley-holt.com/2008/09/testing-requirements-with-unit-tests/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 14:21:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2008/09/testing-requirements-with-unit-tests/</guid>
		<description><![CDATA[I&#8217;m currently working on a project where the client is running their own web server that I will not have direct access to. This is actually a good thing in that it is a nice way to enforce the separation of the development and integration environments from the staging and production environments. However, how do [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on a project where the client is running their own web server that I will not have direct access to. This is actually a good thing in that it is a nice way to enforce the <a href="http://bradley-holt.blogspot.com/2008/07/developmentintegrationstagingproduction.html">separation of the development and integration environments from the staging and production environments</a>. However, how do I be sure that all of the system requirements will be met so that I can address any potential problems early on in the project? Sure, I could just give them a file with phpinfo() in it and have them send me the results. However, I plan on also shipping them unit tests for the application so why not have the requirements tested through unit tests as well?</p>
<p>My first thought was, since the application is being built in Zend Framework, just ship them the Zend Framework unit tests. It turns out there are a <em>lot</em> of unit tests and they have some heavy memory requirements. So, I decided on a simpler approach. I would run unit tests that simply tested for the <a href="http://framework.zend.com/manual/en/requirements.html">requirements</a> outlined in the Zend Framework documentation. Here are the tests:</p>
<pre><code>/**
 * The Requirements test case.
 *
 * @category   Requirements
 * @package    Requirements
 * @copyright  Copyright (c) 2005-2008 Found Line, Inc. (http://www.foundline.com/)
 * @license    http://www.foundline.com/legal/software-license/ New BSD License
 */
class Requirements extends PHPUnit_Framework_TestCase
{

    public function testVersionOfPhpIs5Dot1Dot4OrLater()
    {
        $this-&gt;assertTrue(version_compare(PHP_VERSION, '5.1.4', '&gt;='));
    }

    public function testVersionOfPhpIs5Dot2Dot3OrLater()
    {
        $this-&gt;assertTrue(version_compare(PHP_VERSION, '5.2.3', '&gt;='));    }

    /**
     * @dataProvider requiredExtensions
     * @param string $extensionName the name of the extension for which to test
     */
    public function testExtensionLoaded($extensionName)
    {
        $this-&gt;assertTrue(extension_loaded($extensionName));
    }

    public static function requiredExtensions()
    {
        return array(
            'apc'           =&gt; array('apc'),
            'bcmath'        =&gt; array('bcmath'),
            'bitset'        =&gt; array('bitset'),
            'ctype'         =&gt; array('ctype'),
            'curl'          =&gt; array('curl'),
            'dom'           =&gt; array('dom'),
            'gd'            =&gt; array('gd'),
            'hash'          =&gt; array('hash'),
            'ibm_db2'       =&gt; array('ibm_db2'),
            'iconv'         =&gt; array('iconv'),
            'interbase'     =&gt; array('interbase'),
            'json'          =&gt; array('json'),
            'libxml'        =&gt; array('libxml'),
            'mbstring'      =&gt; array('mbstring'),
            'memcache'      =&gt; array('memcache'),
            'mime_magic'    =&gt; array('mime_magic'),
            'mysqli'        =&gt; array('mysqli'),
            'oci8'          =&gt; array('oci8'),
            'pcre'          =&gt; array('pcre'),
            'pdo'           =&gt; array('pdo'),
            'pdo_mssql'     =&gt; array('pdo_mssql'),
            'pdo_mysql'     =&gt; array('pdo_mysql'),
            'pdo_oci'       =&gt; array('pdo_oci'),
            'pdo_pgsql'     =&gt; array('pdo_pgsql'),
            'pdo_sqlite'    =&gt; array('pdo_sqlite'),
            'posix'         =&gt; array('posix'),
            'reflection'    =&gt; array('Reflection'),
            'session'       =&gt; array('session'),
            'simpleXml'     =&gt; array('SimpleXML'),
            'soap'          =&gt; array('soap'),
            'spl'           =&gt; array('SPL'),
            'sqlite'        =&gt; array('SQLite'),
            'standard'      =&gt; array('standard'),
            'xml'           =&gt; array('xml'),
            'zlib'          =&gt; array('zlib'),
        );
    }

}</code></pre>
<p>Note that I&#8217;ve checked for both the recommended PHP version 5.2.3 and the required PHP version 5.1.4. Also, I&#8217;ve tested for both hard and soft dependencies for all components. This means that many of these tests could fail and my application could still be OK. I wanted as much information as possible so that I can detect any potential problems before I write too much code. As the specific requirements for this application become clearer, I will update the test to add or remove requirements. Of course, once there is real code and unit tests these requirements tests will become irrelevant. The point is to test for the presence of these requirements <em>before</em> I write the code.</p>
<p>Running these tests with the command <code> phpunit --testdox Requirements.php</code> (I&#8217;ve actually wrapped this into a bigger test suite, but that&#8217;s outside the scope of this blog post) gives me the following output on one of my development machines:</p>
<pre><code>PHPUnit 3.3.1 by Sebastian Bergmann.

Requirements
 [x] Version of php is 5 dot 1 dot 4 or later
 [x] Version of php is 5 dot 2 dot 3 or later
 [x] Extension loaded with data set "apc"
 [x] Extension loaded with data set "bcmath"
 [x] Extension loaded with data set "bitset"
 [x] Extension loaded with data set "ctype"
 [x] Extension loaded with data set "curl"
 [x] Extension loaded with data set "dom"
 [x] Extension loaded with data set "gd"
 [x] Extension loaded with data set "hash"
 [ ] Extension loaded with data set "ibm_db 2"
 [x] Extension loaded with data set "iconv"
 [x] Extension loaded with data set "interbase"
 [x] Extension loaded with data set "json"
 [x] Extension loaded with data set "libxml"
 [x] Extension loaded with data set "mbstring"
 [x] Extension loaded with data set "memcache"
 [x] Extension loaded with data set "mime_magic"
 [x] Extension loaded with data set "mysqli"
 [ ] Extension loaded with data set "oci 8"
 [x] Extension loaded with data set "pcre"
 [x] Extension loaded with data set "pdo"
 [ ] Extension loaded with data set "pdo_mssql"
 [x] Extension loaded with data set "pdo_mysql"
 [ ] Extension loaded with data set "pdo_oci"
 [ ] Extension loaded with data set "pdo_pgsql"
 [x] Extension loaded with data set "pdo_sqlite"
 [x] Extension loaded with data set "posix"
 [x] Extension loaded with data set "reflection"
 [x] Extension loaded with data set "session"
 [x] Extension loaded with data set "simple xml"
 [x] Extension loaded with data set "soap"
 [x] Extension loaded with data set "spl"
 [x] Extension loaded with data set "sqlite"
 [x] Extension loaded with data set "standard"
 [x] Extension loaded with data set "xml"
 [x] Extension loaded with data set "zlib"
</code></pre>
<p>There are a couple of potential problems to be aware of. First, PHPUnit will have to be installed on the machine that this will be tested on. This should probably only be done on the staging machine, not the production machine. Second, the CLI version of PHP often uses a different php.ini file then the CGI or ISAPI version. This means that some requirements may actually be available to your web application but they will fail the test when run at the command line.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2008/09/testing-requirements-with-unit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZendCon 2008</title>
		<link>http://bradley-holt.com/2008/09/zendcon-2008/</link>
		<comments>http://bradley-holt.com/2008/09/zendcon-2008/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 16:18:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[ZendCon]]></category>
		<category><![CDATA[ZendCon08]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2008/09/zendcon-2008/</guid>
		<description><![CDATA[ZendCon 2008 wrapped up last week. This was my first time going to ZendCon and it was definitely worth it. There were over 650 people and over 60 sessions at the Santa Clara conference. I&#8217;ll try to post summaries and highlights from the sessions I attended. It was a great opportunity to attended presentations from [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zendcon.com/">ZendCon</a> 2008 wrapped up last week. This was my first time going to ZendCon and it was definitely worth it. There were over 650 people and over 60 sessions at the Santa Clara conference. I&#8217;ll try to post summaries and highlights from the sessions I attended.  It was a great opportunity to attended presentations from some of the most well respected people in the PHP community including Vermont&#8217;s own <a href="http://weierophinney.net/matthew/">Matthew Weier O&#8217;Phinney</a> (Zend Technologies), <a href="http://mikenaberezny.com/">Mike Naberezny</a> (Maintainable Software), <a href="http://sebastian-bergmann.de/">Sebastian Bergmann</a> (eZ Systems), <a href="http://www.derickrethans.nl/">Derick Rethans</a> (eZ Systems),  <a href="http://galbraiths.org/blog/">Ben Galbraith</a> (<a href="http://ajaxian.com/">Ajaxian.com</a>) , <a href="http://marcus-boerger.de/">Marcus Boerger</a> (Google), and <a href="http://benramsey.com/">Ben Ramsey</a> (Schematic).</p>
<p><a href="http://www.zend.com/zce.php?c=ZEND008969&#038;r=227171017"><img style="margin: 0pt 10px 10px 0pt; float: left;" src="http://2.bp.blogspot.com/_OLV-zodnLDg/SNfDyU5TGmI/AAAAAAAAAlc/xofhIR7fuVQ/s400/zf-zce-logo.gif" alt="Zend Certified Engineer (ZCE) in Zend Framework" id="BLOGGER_PHOTO_ID_5248879160093514338" border="0" /></a>Last Tuesday during the opening keynote Zend announced the new Zend Framework certification. I was fortunate enough to get a testing slot on Thursday morning. After reading the 214 page study guide on Wednesday I passed the test, so am now a Zend Certified Engineer (ZCE) in Zend Framework! If you plan on taking the test, I definitely recommend reading the study guide. I&#8217;ve been using Zend Framework since 1.0 and I&#8217;m not sure I would have passed if I hadn&#8217;t read the study guide.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2008/09/zendcon-2008/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Development/Integration/Staging/Production</title>
		<link>http://bradley-holt.com/2008/07/developmentintegrationstagingproduction/</link>
		<comments>http://bradley-holt.com/2008/07/developmentintegrationstagingproduction/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 23:53:00 +0000</pubDate>
		<dc:creator>Bradley Holt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Best Practices]]></category>

		<guid isPermaLink="false">http://bradley-holt.com/2008/07/developmentintegrationstagingproduction/</guid>
		<description><![CDATA[I am surprised by how many developers think it&#8217;s OK to do work directly in a production environment or to deploy to production directly from their development environment. I found a good article today that explains the traditional Development/Integration/Staging/Production practice. The specific setup may be different depending on your environment, but the basic ideas are [...]]]></description>
			<content:encoded><![CDATA[<p>I am surprised by how many developers think it&#8217;s OK to do work directly in a production environment or to deploy to production directly from their development environment. I found a good article today that explains the traditional <a href="http://dltj.org/article/software-development-practice/">Development/Integration/Staging/Production practice</a>. The specific setup may be different depending on your environment, but the basic ideas are the same.</p>
]]></content:encoded>
			<wfw:commentRss>http://bradley-holt.com/2008/07/developmentintegrationstagingproduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

