<?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>Robert Speer Web Development</title>
	<atom:link href="http://www.robertspeer.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.robertspeer.com/blog</link>
	<description>Symfony,  PHP, Wordpress, Business Analysis</description>
	<lastBuildDate>Sat, 07 Jan 2012 22:29:55 +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>No degree? No Problem  (some hard knocks may apply)</title>
		<link>http://www.robertspeer.com/blog/no-degree-no-problem-some-hard-knocks-may-apply/</link>
		<comments>http://www.robertspeer.com/blog/no-degree-no-problem-some-hard-knocks-may-apply/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 20:11:20 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=233</guid>
		<description><![CDATA[How to get into Web Development with NO degree and NO debt. I woke up this morning listening to MPR reporting on 800 newly unemployed workers from the now former Ford Ranger Plant. In that report a couple lamented the end of a time when someone could get a good job, work hard, and achieve the [...]]]></description>
			<content:encoded><![CDATA[<h2>How to get into Web Development with NO degree and NO debt.</h2>
<p>I woke up this morning listening to <a title="Fort Plant Closing" href="http://minnesota.publicradio.org/display/web/2011/12/16/ford-plant-closing-last-ranger/" target="_blank">MPR reporting on 800 newly unemployed workers from the now former Ford Ranger Plant</a>. In that report a couple lamented the end of a time when someone could get a good job, work hard, and achieve the American dream of a nice home, &amp; enough money to raise kids and retire.</p>
<p>Fortunately it&#8217;s still possible to get a good job making websites, it&#8217;s just not easy, but neither is working on an assembly line so lets suck it up and talk about a plan.</p>
<h3>Is Web Development The Right Job For You?</h3>
<p>The best advise I can give you here comes from a conversation with <a title="Robert Nelson" href="http://www.linkedin.com/in/nelsonrobert" target="_blank">Robert Nelson</a> about advise he&#8217;d give to a new developer.  It went something like this:</p>
<blockquote>
<p style="text-align: center;"><em>There are two parts of this job, the really stressful part, and the really hard part.  So you better really love programming or it&#8217;s going to be bad.</em></p>
</blockquote>
<p style="text-align: left;">I can&#8217;t recommend enough to that you start playing around making websites as soon as possible.  If you&#8217;re not fascinated with it, enjoy the complexity, and the terrifying quantity of things to learn, find something else to do.  Programming is just not a job you can do and hate it.</p>
<p style="text-align: left;">I have talked to people who spent 2 years in a Web Development program, got all A&#8217;s, learned they did not like programming, and could not do it for a living.</p>
<h3>Where To Start</h3>
<p>Nobody, other than the Military, is going give you on the job training.  You can get a job in Software or Web Quality Assurance (QA) that will give you exposure to people who can answer your questions, point you in the right direction, and get some relevant experience.</p>
<p>You&#8217;ll need to be able to follow directions, write well, &amp; use a computer.  Your job will be to use a computer to review websites &amp; software to make sure it works &amp; looks correctly.  To be effective at the job you&#8217;ll need to learn about common mistakes, differences in web browsers, security issues to test for, and environmental factors that effect the user experience.  To be good at it you&#8217;ll need to write bug reports that take less time to understand than they do to fix and use automated testing tools like <a title="Selenium Automated Testing Tools" href="http://seleniumhq.org/" target="_blank">Selenium</a> to make yourself more efficient and valuable to your team.</p>
<p>The skills you learn in QA will make you a better Web Developer.  You will use them all to write software, and I&#8217;ve never heard about them being taught in school so you&#8217;re not at a major disadvantage.</p>
<p>This is going to be a hard job to get if you&#8217;ve never done it before.  If you can&#8217;t find a paying gig try for an unpaid internship.  Everybody needs more testing of their applications and everybody is cheap.  Do it well and in a year you should be making more than $15/hr, learn the automated testing tools, well, and you can get paid as well or better than most developers.</p>
<p>One thing to keep in mind is that bugs hurt developers feelings.  Even if we don&#8217;t admit it they all sting, so be kind even when you don&#8217;t have to be.</p>
<p>Below are some QA Jobs in Minneapolis from my favorite Job site indeed.com, as I write this there are 560 job postings for QA pro&#8217;s so get after it.</p>
<p><script type="text/javascript">
<!--
indeed_jobroll_title = 'Search more Jobs';
indeed_jobroll_background_color = "#FFFFFF";
indeed_jobroll_width = "300px";
indeed_jobroll_text_font = "10px Arial, Helvetica, Sans serif";
indeed_jobroll_link_color = "#3D7283";
indeed_jobroll_border = "1px solid #000000";
//-->
</script><br />
<script type="text/javascript" src="http://www.indeed.com/jobroll?q=quality+assurance+%28web+or+software%29+-senior&#038;l=Minneapolis%2C+MN&#038;limit=5">
</script><br />
<noscript><a href="http://www.indeed.com/">Jobs</a> by Indeed</noscript></p>
<h3>Making The Transition To Development</h3>
<p>It is going to take you at least a year to get really good at QA, it&#8217;s better than digging a ditch but finding bugs usually pays less than making bugs.  Frontend Web Development like QA is one of those things that most schools ignore or do an AWFUL job of teaching so skipping the student loans and jumping right in is not a disadvantage.     Frontend Web Developers usually get a web design in the form of a layered Photoshop Document (PSD) and convert it into HTML &amp; CSS.   Photoshop is a ridiculously expensive image editing program that I avoid like the plague, and is usually used by print hacks making bad websites, but that&#8217;s the gig.</p>
<p>HTML stands for Hyper Text Markup Language, it defines roughly what goes where on a website, it&#8217;s not hard to learn, you should have the basics down in about 8 hours of messing around.    I learned HTML on W3Schools using a tutorial much like this one: <a href="http://www.w3schools.com/html/" target="_blank">http://www.w3schools.com/html</a>.   This one from Mozilla looks good as well and appears to be more current: <a href="https://developer.mozilla.org/en-US/learn/html" target="_blank">https://developer.mozilla.org/en-US/learn/html</a>.</p>
<p>CSS stands for Cascading Style Sheet, these files define what a website looks like.  CSS starts simple, but is very hard to keep that way, back in the day when I got started it was MUCH harder, but modern browsers have made cross browser CSS support more consistent.  Again W3Schools &amp; Mozilla have some great free tutorials: <a href="http://www.w3schools.com/css/" target="_blank">https://developer.mozilla.org/en-US/learn/css</a>  &amp;   <a href="http://www.w3schools.com/css/" target="_blank">http://www.w3schools.com/css/</a>.  A good resource to see the impressive flexibility of CSS is <a href="http://csszengarden.com">http://csszengarden.com</a>, it uses one HTML file but allows designers to submit their own images and CSS files to make it look drastically different.</p>
<p>CSS is one of those things that many people claim to be able to do, but very few can do well.  It&#8217;s hard but writing good CSS is much like writing good applications.  It will teach you the value of coding standards, consistency, comments, &amp; reusability.  I&#8217;m tempted to say so much about how not to write bad CSS but that&#8217;s for another blog post.</p>
<h3>Your First CMS</h3>
<p>So you can write HTML &amp; CSS, but to market those skills you will need to pair them with one or more CMS&#8217;s.   A CMS is a Content Management System, they allow users to login to a administration interface and write their own content.   I&#8217;d suggest you get your own WordPress blog and play around with it.    There are a TON of learning WordPress sites &amp; resources but start with the source and you&#8217;ll be fine <a href="http://learn.wordpress.com/">http://learn.wordpress.com</a>.  Getting really good at WordPress is hard but worth it, and you&#8217;ll definitely be able to move up the Web pay scale.</p>
<p>For this you&#8217;ll need a host to store it on, and a domain name to use to access it.  I&#8217;d suggest Dreamhost.com for both, Dreamhost is cheap and allows you to do a lot of things with out knowing much of the details.  Dreamhost.com is not very reliable, or fast, but it&#8217;s an excellent platform for learning about making websites.   Once you know WordPress you can start going out and making websites for people, do this as much as possible.  You&#8217;ll have to make several websites to get good at it.  If you can charge for them, it&#8217;s not uncommon for people to pay $2,000 for a basic wordpress site, although $500 to $1000 is much more common.</p>
<p>Again this is going to take a year or more to get good at, many people stop here and make a career of making WordPress sites, but there is more money to be made and bills to pay.</p>
<h3>Advanced Interactions with Javascript &amp; JQuery</h3>
<p>JavaScript is the first real programming language you should start tinkering around with.  Most everyone starts by copy and pasting other people&#8217;s code and then breaking stuff until they get it figured out.   It&#8217;s a good first step, but expect things to get increasingly harder as you&#8217;ll getting into the world of programming.   Mozilla is again here to help <a href="https://developer.mozilla.org/en-US/learn/javascript">https://developer.mozilla.org/en-US/learn/javascript</a> with the basics.</p>
<p>Once you know the basics <a href="http://jquery.com/" target="_blank">JQuery </a>&amp; <a href="http://jqueryui.com/" target="_blank">JQuery UI</a> will make fancy interactions fun.  <a href="http://jquery.com/" target="_blank">JQuery</a> is probably the most fun part of web development, and there&#8217;s definitely money in getting really good at <a href="http://jquery.com/" target="_blank">JQuery</a>.</p>
<p>Once you&#8217;ve mastered QA, HTML, CSS, &amp; JavaScript/JQuery you will probably have about 5 years of industry experience and you&#8217;re a easily employable Frontend Web Developer.  Since the schools that teach these skills are few in number and of poor quality your School of Hard Knocks education is usually preferred.   However you can still move on to ever more complex skills that will make you more recession proof.</p>
<h3>Backend Development</h3>
<p>Backend Development is mostly pulling things out of a database and pushing things into them with a bunch of stuff in the middle.   There are some great self taught programmers but at this point a few classes will go a long way.    I&#8217;d strongly recommend a intro to programming class, and a intro do database design class at a technical school like <a href="http://www.rasmussen.edu/degrees/technology-design/web-programming/" target="_blank">Rasmussen</a> or <a href="http://www.hennepintech.edu/program/awards/268" target="_blank">Hennepin Tech</a>.  I got my A.A. in Web Programming from <a href="http://salina.k-state.edu/engtech/wdt.htm" target="_blank">K-State Salina</a> and I believe it was a great value.  You don&#8217;t need the full technical degree to be productive, but the introductions to programming and databases will be a big help. </p>
<p>As far as languages lets check out Indeed&#8217;s Salary Trend data:</p>
<p><!-- BEGIN INDEED SALARY GRAPH --></p>
<div style="width:196px;">
<div style="border:1px solid #ccc;padding: 1px; margin: 0 0 3px 0">
<table cellpadding="0" cellspacing="0" style="border:0;padding:0;margin:0;width:100%;">
<tr>
<td style="background-color: #eee; padding: 4px 6px; border: 0;border-right:1px solid #fff; width: 50%; text-align: right;">
<p style="color: #000; font: bold 10px/1.2 Arial, Helvetica, sans-serif;margin: 0; padding: 0; border: 0;"><a href="http://www.indeed.com/jobs?sid=salary&#038;q=php+in+Minneapolis%2C+MN" style="text-decoration:underline; color:#00c; background-color: transparent;">php in Minneapolis, MN</a> <span style="display:block;">$75,000</span></p>
</td>
<td style="width: 50%;background-color:#f8f8f8;">
<div style="height: 20px; margin: 0; margin-top: 2px; width: 71%; background-color: #ff6600;"></div>
</td>
</tr>
<tr>
<td style="background-color: #eee; padding: 4px 6px; border: 0;border-right:1px solid #fff; width: 50%; text-align: right;border-top:1px solid #fff;">
<p style="color: #000; font: bold 10px/1.2 Arial, Helvetica, sans-serif;margin: 0; padding: 0; border: 0;"><a href="http://www.indeed.com/jobs?sid=salary&#038;q=ruby+in+Minneapolis%2C+MN" style="text-decoration:underline; color:#00c; background-color: transparent;">ruby in Minneapolis, MN</a> <span style="display:block;">$83,000</span></p>
</td>
<td style="width: 50%;background-color:#f8f8f8;">
<div style="height: 20px; margin: 0; margin-top: 2px; width: 79%; background-color: #2164f3;"></div>
</td>
</tr>
<tr>
<td style="background-color: #eee; padding: 4px 6px; border: 0;border-right:1px solid #fff; width: 50%; text-align: right;border-top:1px solid #fff;">
<p style="color: #000; font: bold 10px/1.2 Arial, Helvetica, sans-serif;margin: 0; padding: 0; border: 0;"><a href="http://www.indeed.com/jobs?sid=salary&#038;q=asp+in+Minneapolis%2C+MN" style="text-decoration:underline; color:#00c; background-color: transparent;">asp in Minneapolis, MN</a> <span style="display:block;">$81,000</span></p>
</td>
<td style="width: 50%;background-color:#f8f8f8;">
<div style="height: 20px; margin: 0; margin-top: 2px; width: 77%; background-color: #3bb000;"></div>
</td>
</tr>
<tr>
<td style="background-color: #eee; padding: 4px 6px; border: 0;border-right:1px solid #fff; width: 50%; text-align: right;border-top:1px solid #fff;">
<p style="color: #000; font: bold 10px/1.2 Arial, Helvetica, sans-serif;margin: 0; padding: 0; border: 0;"><a href="http://www.indeed.com/jobs?sid=salary&#038;q=python+in+Minneapolis%2C+MN" style="text-decoration:underline; color:#00c; background-color: transparent;">python in Minneapolis, MN</a> <span style="display:block;">$85,000</span></p>
</td>
<td style="width: 50%;background-color:#f8f8f8;">
<div style="height: 20px; margin: 0; margin-top: 2px; width: 81%; background-color: #000;"></div>
</td>
</tr>
</table></div>
<p style="font: normal 10px/1.2 Arial, Helvetica, sans-serif; color: #000; margin: 0; padding: 0; border: 0; text-align: center;"><a style="text-decoration:underline; color:#00c; background-color: transparent;" href="http://www.indeed.com/salary?q1=php&#038;l1=Minneapolis%2C+MN&#038;q2=ruby&#038;l2=Minneapolis%2C+MN&#038;q3=asp&#038;l3=Minneapolis%2C+MN&#038;q4=python&#038;l4=Minneapolis%2C+MN">View Larger Salary Graph</a></p>
</p></div>
<p>	<!-- END INDEED SALARY GRAPH --></p>
<p>The salary graph makes Python &amp; Ruby look great (and they are), but the demand graph below shows ASP to be in more demand.</p>
<div style="width: 400px;"><a title="php, ruby, asp, python Job Trends" href="http://www.indeed.com/jobtrends?q=php%2C+ruby%2C+asp%2C+python"><br />
<img src="http://www.indeed.com/trendgraph/jobgraph.png?q=php%2C+ruby%2C+asp%2C+python" alt="php, ruby, asp, python Job Trends graph" width="400" border="0" /><br />
</a></p>
<table style="font-size: 80%;" width="100%" border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td><a href="http://www.indeed.com/jobtrends?q=php%2C+ruby%2C+asp%2C+python">php, ruby, asp, python Job Trends</a></td>
<td align="right"><a href="http://www.indeed.com/jobs?q=PHP">PHP jobs</a> &#8211; <a href="http://www.indeed.com/jobs?q=Ruby">Ruby jobs</a> &#8211; <a href="http://www.indeed.com/jobs?q=ASP">ASP jobs</a> &#8211; <a href="http://www.indeed.com/jobs?q=Python">Python jobs</a></td>
</tr>
</tbody>
</table>
</div>
<p>It&#8217;s been my experience that ASP.NET and Microsoft languages pay well and have better tools that the other languages. Also Microsoft has released their excellent development tools in reduced feature set <a href="http://www.microsoft.com/express">Express editions</a> that are perfect for learning.</p>
<p>I use, and like PHP, however the money is clearly not in PHP.</p>
<h3>Final Words</h3>
<p>Becoming a well paid Web Developer is well within the reach of anyone with a good mind and determination.   It&#8217;s not easy, it&#8217;s usually stressful, but if you are crazy enough to like programming it&#8217;s a good gig with a ton of jobs all over the world.</p>
<p>If you have questions, any good developer will help you.  We like to show off <img src='http://www.robertspeer.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  and we are all keenly aware that this stuff is hard, at least the first couple times you did it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/no-degree-no-problem-some-hard-knocks-may-apply/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quick Tip: using format option with sfWidgetFormJqueryDate</title>
		<link>http://www.robertspeer.com/blog/quick-tip-using-format-option-with-sfwidgetformjquerydate/</link>
		<comments>http://www.robertspeer.com/blog/quick-tip-using-format-option-with-sfwidgetformjquerydate/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 20:39:56 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=222</guid>
		<description><![CDATA[It is not well documented how to use the format option for sfWidgetFormJQueryDate in the sfFormExtrasPlugin for Symfony 1.4. However, once I learned about sfWidgetFormJQueryDate&#8217;s date_widget option it was pretty easy.  Just create a new date widget and use the format option there. The example below needs to be in your form&#8217;s configure method and [...]]]></description>
			<content:encoded><![CDATA[<p>It is not well documented how to use the format option for sfWidgetFormJQueryDate in the sfFormExtrasPlugin for Symfony 1.4.</p>
<p>However, once I learned about sfWidgetFormJQueryDate&#8217;s date_widget option it was pretty easy.  Just create a new date widget and use the format option there.</p>
<p>The example below needs to be in your form&#8217;s configure method and assumes our field is named &#8220;available&#8221;.  The format I chose gets rid of the forward slashes between the selects that were showing up to the right of the button that triggers the calendar input.  I&#8217;m also setting the button text.</p>
<p><code><br />
$this-&gt;setWidget('available',<br />
new sfWidgetFormJQueryDate(<br />
array(<br />
'config' =&gt; '{buttonText: "Choose Date"}',<br />
'date_widget' =&gt; new sfWidgetFormDate(array('format'=&gt;'%month%%day%%year%'))<br />
)<br />
)<br />
);</code></p>
<p>hopefully this will make googling this little issue a little easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/quick-tip-using-format-option-with-sfwidgetformjquerydate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I support equal rights for all families</title>
		<link>http://www.robertspeer.com/blog/equal-rights-for-all-families/</link>
		<comments>http://www.robertspeer.com/blog/equal-rights-for-all-families/#comments</comments>
		<pubDate>Sun, 22 May 2011 23:55:57 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=206</guid>
		<description><![CDATA[This is a web development blog, and I intend to keep it that way. However, I feel the issue of equal rights for all Americans is so important that I need to take advantage of the handful of hits a day I get to do my part to support marriage equality and individual rights. The [...]]]></description>
			<content:encoded><![CDATA[<p>This is a web development blog, and I intend to keep it that way.  However, I feel the issue of equal rights for all Americans is so important that I need to take advantage of the handful of hits a day I get to do my part to support marriage equality and individual rights.</p>
<p>The following video is the most influential I&#8217;ve seen, please take a moment to view it and help keep hate out of Minnesota by signing up to say informed at <a src="http://http://www.minnesotansunitedforallfamilies.com/">http://www.minnesotansunitedforallfamilies.com/</a></p>
<p><iframe src="http://blip.tv/play/hrFYgrz0UAI.html" width="480" height="390" frameborder="0" allowfullscreen></iframe><embed type="application/x-shockwave-flash" src="http://a.blip.tv/api.swf#hrFYgrz0UAI" style="display:none"></embed></p>
<p>I&#8217;ll be back soon with more technology posts, please forgive me for going off topic with my personal politics</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/equal-rights-for-all-families/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interactive Infrastructure for under $25 a month</title>
		<link>http://www.robertspeer.com/blog/interactive-infrastructure-for-under-25-a-month/</link>
		<comments>http://www.robertspeer.com/blog/interactive-infrastructure-for-under-25-a-month/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 21:06:13 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[Web Entrepreneurs]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=191</guid>
		<description><![CDATA[The hardest part of interactive projects is not the coding or ideation, its working efficiently as a collaborative team. There are ways to spend a ton of hours &#38; money on your infrastructure, and then invest hours of maintenance every month, all on tools that don&#8217;t directly make you money. Project Management, Version Control &#38; [...]]]></description>
			<content:encoded><![CDATA[<p><span>The hardest part of interactive projects is not the coding or <span>ideation</span>, its working efficiently as a collaborative team.  There are ways to spend a ton of hours &amp; money on your infrastructure, and then invest hours of maintenance every month, all on tools that don&#8217;t directly make you money.</span><br />
<span id="more-191"></span></p>
<h2>Project Management, Version Control &amp; More for $3.95 / mo</h2>
<p><a title="Source Repo" href="http://sourcerepo.com/" target="_blank">http://sourcerepo.com</a></p>
<p><span>The best value with the ugliest website on the web.  <span>SourceRepo</span>.com combines project management, version control, &amp; one click backups into a easy to use interface,  starting at $3.95 a month.</span></p>
<p>For project management you get a choice of the simple &amp; effective <a title="The Trac Project" href="http://trac.edgewall.org/" target="_blank"><span><span>Trac</span></span></a>, or the more feature rich <a title="Redmine Project Management" href="http://www.redmine.org" target="_blank"><span><span>Redmine</span></span></a> (my preference).   In comparison, <a title="Basecamp Pricing &amp; Signup" href="http://basecamphq.com/signup" target="_blank"><span>37 Signals <span>Basecamp</span></span></a><span> product is <span>oustanding</span>, &amp; free for the first project, but after that goes to $24 / mo &amp; up to $150 / mo without version control as well as many of the features offered by </span><a title="Redmine Project Management" href="http://www.RedMine.org" target="_blank"><span><span>Redmine</span></span></a>.</p>
<p><span><span>SourceRepo</span>.com can can host your version control system, <span>wich</span> choices of Git, Subversion, or Mercurial.  <span>SourceRepo</span>.com <span>automagically</span> integrates your version control system with your <span>Trac</span> or <span>Redmine</span> install.  Alternatives include </span><a title="Git Hosting " href="http://GitHub.com" target="_blank"><span><span>GitHub</span>.com</span></a>, which is free for public repositories that anyone can see an download, or $7 / mo for up to 5 private repositories.  <a title="Private SVN or Git hosting" href="http://beanstalkapp.com" target="_blank"><span><span>BeanStalkApp</span>.com</span></a> is another good choice for $15 / mo.</p>
<h2><span>Project Documentation: Scope docs, <span>Wireframes</span>, &amp; Flowcharts  $0</span></h2>
<p>Seriously $0, but there are a few limitations.</p>
<p><a title="Google Docs" href="http://docs.google.com" target="_blank">Google Docs</a> is a adequate tool for word processing, and it&#8217;s online collaboration tools are very cool.  However if you&#8217;ve got a Mac &amp; $20 bucks to spare I strongly recommend <a title="Pages Word Processing" href="http://www.apple.com/iwork/pages/" target="_blank">Pages</a> it makes creating a professional looking document more than $20 easier than Google Docs.</p>
<p><span>Wire-framing is an essential tool for getting all your stakeholders on the same page, even better are wire-frames your clients can click through. </span><a title="Go Mockingbird Wireframes" href="https://gomockingbird.com/signup/" target="_blank"><span><span>GoMockingbird</span>.com</span></a><span> delivers wire-frames with limited interactivity that can be reviewed in browser or shared in multiple formats.  Even better is the ability to collaborate online.   Pricing starts at Free for our first project then $9 for 2 and up to $85 / mo for an unlimited account, &amp; you only have to pay for the months you use the service.    There are other alternatives, </span><a title="Balsmiq Mockups" href="http://balsamiq.com/products/mockups" target="_blank"><span><span>Balsamq</span> <span>Mockups</span></span></a> has a very generous free trial, &amp; a $79 price tag.  <a title="Axure Prototype builder" href="http://www.axure.com/" target="_blank"><span><span>Axure</span></span></a> is an amazing interactive prototype builder but it runs $589.</p>
<p>Flowcharts have a bad reputation for not being actual work, but they do a great job of describing processes.  Also for free <a title="Gliffy Online charts" href="http://www.gliffy.com/prodcomparison.shtml" target="_blank"><span><span>Gliffy</span>.com</span></a> will allow you to create up to 5 flowcharts, which should get the average developer through their first year of consulting.  After your first 5 charts it&#8217;s only $5 / mo.  There are alternatives, I don&#8217;t do enough charting to recommend alternatives.</p>
<h2>Development &amp; Staging Hosting $20 / mo</h2>
<p>I&#8217;ll only be addressing PHP hosting because it is what I know best.</p>
<p>If your comfortable doing some basic server work developing your PHP web application on your own computer is ideal.  Free tools to make this easy are <a title="MAMP - Mac, Apache, MySQL, &amp; PHP" href="http://www.mamp.info/en/index.html" target="_blank">MAMP</a> &amp; <a title="*AMP made easy" href="http://www.apachefriends.org/en/index.html" target="_blank">XAMP</a>, both of these tools allow you to easily get started with developing PHP base web applications on your local machine.  If do have a team that includes anyone that does not think server maintenance is fun, a proper development environment with a <a title="amba is the standard Windows interoperability suite of programs for Linux and Unix." href="http://www.samba.org" target="_blank">Samba</a><span> share will save you time and headaches by making <span>linux</span> home directory appear as a hard drive on a local machine.</span></p>
<p><span>A staging server is where you test your teams code in a production environment prior to putting it on the production server.  It should be as similar as possible to your production environment.   My preferences, if you are comfortable working on the <span>linux</span> command line through SSH, are </span><a title="Server Grove VPS pricing" href="http://servergrove.com/vps" target="_blank"><span><span>ServerGrove</span></span></a> &amp; <a title="RackSpace Cloud Hosting" href="http://www.rackspace.com/cloud" target="_blank"><span><span>RackSpace</span> Cloud</span></a>.  However, if working on the command line is not your thing, take a look at the <a title="DreamHost VPS" href="http://www.dreamhost.com/hosting-vps.html" target="_blank"><span><span>Dreamhost</span>.<span>com&#8217;s</span> VPS</span></a><span> it uses the same great interface they have for their shared hosting.  One thing to remember about <span>Dreamhost&#8217;s</span> VPS is that you&#8217;ll need 2 $15 /mo servers, one for your web application and one for your database.</span></p>
<h2>Time Tracking &amp; Invoicing  $0</h2>
<p>I am in passionate love with <a title="Freshbooks Time Tracking &amp; Invoicing pricing" href="https://secure.freshbooks.com/pricing.php" target="_blank"><span><span>Freshbooks</span>.com</span></a><span>.  I hate tracking my time, accounting, &amp; invoicing which is what <span>Freshbooks</span>.com makes nearly  painless.  It&#8217;s free for your first 3 project, then between $19.95 &amp; $39.95 after that.  Features include the ability invoice in less than 3 minutes, mobile apps, a time that enables time tracking down to the hundredth of an hour, online payments, &amp; contractors.  The only thing it does not include is <span>Quickbooks</span> export, which is drag come tax time.  <span>Quickbooks</span> is an alternative, but it does not look fun at all.  A viable alternative that I should consider is </span><a title="Harvest Time Tracking &amp; Invoicing" href="http://www.getharvest.com/pricing" target="_blank">Harvest</a><span> which does include <span>Quickbooks</span> export, as well as some solid <span>Redmine</span> integration, it&#8217;s also cheaper at between $12 &amp; $90 a month.  On second thought I may not be in as deep of love with <span>Freshbooks</span>.com as I thought&#8230;</span></p>
<h2>What about office space?</h2>
<p><span>A home office is a great way to save money, but I&#8217;m not not half as productive as I am at the <span>CoWorking</span> space I purchase for $150 / mo at </span><a title="CoCo Coworking &amp; Collaboration in Lowertown St. Paul" href="http://CoCoMsp.com" target="_blank"><span><span>CoCoMsp</span>.com</span></a><span> in <span>lowertown</span> St. Paul, MN.  Most major metropolitan areas have at least one.  In the Twin Cities we have 3, <span>CoCo</span>, </span><a title="The 3rd Place" href="http://the3rdplace.ning.com/" target="_blank">The 3rd Place</a><span> in the <span>MidTown</span> / Como area, and </span><a title="CoJoule CoWorking Space" href="http://cojoule.com/" target="_blank"><span><span>CoJoule</span></span></a> in Minneapolis.</p>
<h2>Scaling</h2>
<p>All the options I&#8217;ve suggested have pricing structures that increase the more you use them, but they&#8217;re all reasonable.  So if you grow to be big enough to need them, your infrastructure costs will scale at a lower pace.</p>
<h2>Conclusion</h2>
<p>Truth be told I&#8217;m spending more like $200 a month for my infrastructure, but I could easily scale it down to $25 a month if I made some sacrifices.</p>
<p><span>With all these solutions your mileage may vary.  These work for me and my little Web Development consultancy.  If you have better options, comments, or corrections let me know in the comments below <img src='http://www.robertspeer.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/interactive-infrastructure-for-under-25-a-month/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Apostrophe: An outstanding Symfony CMS with no backend</title>
		<link>http://www.robertspeer.com/blog/apostrophenow-a-cms-so-easy-even-your-mom-could-use-it/</link>
		<comments>http://www.robertspeer.com/blog/apostrophenow-a-cms-so-easy-even-your-mom-could-use-it/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 17:43:14 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[ApostropheNow]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=94</guid>
		<description><![CDATA[ApostropheNow is the easiest to use OS content management system with an outstanding ROI, and it's build on the outstanding Symfony framework.]]></description>
			<content:encoded><![CDATA[<p><em>Update: January 7 2012 &#8211; @dandyMedia did a <a href="http://dandydev.net/blog/diem-cms-seize-it-or-leave-it" target="_new">companion post reviewing the Diem CMS.</a></em></p>
<p><em>Update: December 16 2011 &#8211; The demo links no longer work for this post it was pretty old anyway.</em></p>
<p><em>Update: this review refers to the 1.0 version, as of Jan 2010 the new 1.5 version is available: <a href="http://window.punkave.com/2011/01/18/apostrophe-1-5-released/">http://window.punkave.com/2011/01/18/apostrophe-1-5-released/</a></em></p>
<h3>Why do I care and where is the  demo:</h3>
<p><strong>Live demo</strong></p>
<p style="padding-left: 30px;"><strong><span style="font-weight: normal;">Link:<a href=" http://bit.ly/An_live_demo" target="_blank"> http://bit.ly/An_live_demo<br />
</a>Username: admin<br />
Password: demo<br />
<em>* login info is prepopulated in the login form so you can just press the login button<br />
** The database and media are  reset at the top each hour.</em></span></strong></p>
<p><strong>Why you care</strong></p>
<ul>
<li>The <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> CMS is easier to use, and easier to write templates for than <a href="http://wordpress.org/" target="_blank">WordPress</a>, <a href="http://drupal.org/" target="_blank">Drupal</a>, or <a href="http://www.joomla.com" target="_blank">Joomla</a>.</li>
<li>It&#8217;s well integrated into the enterprise ready <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> framework.</li>
<li><a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> still allows developers to use almost all the features built into <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> as well as the <a href="http://framework.zend.com" target="_blank">Zend Framework</a>.</li>
<li>Expensive features are baked in like:
<ul>
<li><a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide#RevisingHistory" target="_blank">Content version control</a></li>
<li><a href="http://trac.apostrophenow.org/wiki/ManualDevelopersGuide#Internationalization" target="_blank">Multiple language support or Internationalization</a></li>
<li><a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide#EditingMedia" target="_blank">Media library for images, videos, &amp; PDFs</a></li>
<li><a href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin" target="_blank">User management with permissions and groups</a></li>
</ul>
</li>
<li>It&#8217;s open source and easy to customize so it&#8217;s ROI is outstanding</li>
</ul>
<p><span id="more-94"></span></p>
<h3>How is this going to make me money?</h3>
<p><a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> is the easiest to use <a href="http://en.wikipedia.org/wiki/Content_management_system" target="_blank">content management system (CMS)</a> available to the open source community. An easy CMS means that content managers are more likely to use it, which means consumers will get better information and be more likely to follow the sites profit funnel.</p>
<p>For web solutions providers <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> is a CMS solution that bypasses the <a href="http://www.ftpress.com/articles/article.aspx?p=777370" target="_blank">commodity hell</a> of <a href="http://wordpress.org/" target="_blank">WordPress</a>, <a href="http://drupal.org/" target="_blank">Drupal</a>, and <a href="http://www.joomla.com" target="_blank">Joomla</a> by providing a unique value differentiation. <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> also has the advantage of being built on an enterprise grade web framework used by sites like <a href="http://www.symfony-project.org/blog/2007/10/02/delicious-preview-built-with-symfony" target="_blank">Delicious</a>, <a href="http://www.symfony-project.org/blog/2009/02/18/dailymotion-powered-by-symfony" target="_blank">Dailymotion</a>, <a href="http://www.symfony-project.org/blog/2008/05/08/yahoo-answers-powered-by-symfony" target="_blank">Yahoo! Answers</a>, and <a href="http://www.symfony-project.org/blog/2006/10/28/yahoo-bookmarks-uses-symfony" target="_blank">Yahoo! Bookmarks</a>. <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> provides a consistent structure that encourages collaboration, and the <a href="http://symfonians.net/people" target="_blank">large community of developers</a> already familiar with <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> mean help is available.</p>
<h3>So what makes Apostrophe so special?</h3>
<p>Contextual content management is what. Traditional content management systems have a backend admin interface that users log into to maintain the site. The editing interface has nothing to do with the interface the content will be viewed on. Admin interfaces are also full of features that don&#8217;t make a lot of sense to someone not working with web technology every day. Contextual content management mitigates these issues by allowing content to be edited in the same place the content is consumed.  To manage menus content editors simply drag and drop menu items where they need to go.  Content editors can add and edit content in multiple formats: rich text with a <a href="http://en.wikipedia.org/wiki/WYSIWYG" target="_blank">WYSIWYG</a>, plain text, <a href="http://en.wikipedia.org/wiki/RSS" target="_blank">RSS feed</a>, image, slideshow, button, video, pdf, or raw html. These content formats are called <a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide#EditingSlots" target="_blank">slots</a> and are highly configurable in the templates during development. <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> allows developers to control where <a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide#EditingSlots" target="_blank">slots</a> are available as well as modify there behavior. Developers can <a href="http://trac.apostrophenow.org/wiki/ManualDesignersGuide#SlotVariants:MoreMileageFromYourTemplates" target="_blank">add options</a> for users to choose from, for example the dev team can specify image sizes of small, medium, and large that content editors can choose from when they add an image slot. Media files are managed through a built in media repository with categories, tagging, filtering by type, and text search. A unique feature of all the <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> admin interfaces is that they use the same stylesheet as the rest of the site so they are visually integrated with the rest of the site.</p>
<h3>What if someone makes a mistake?</h3>
<p><a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> comes with content version control baked into contextual editing interface. At the top of each content area, Area is <a href="http://www.apostrophenow.com/">Apostrophe</a> jargon, is a <a href="http://trac.apostrophenow.org/wiki/ManualEditorsGuide#RevisingHistory" target="_blank">History</a> button. Click that and a dialog comes up showing who did what, and when, as well as allowing content editors to click on a revision to quickly review it. To revert to that version simply click the new “Save As Current Revision”.  I&#8217;ve build content version control, and the user interface has been a problem for me, I never had the budget to do one right, but <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> nails it for free.</p>
<h3>How are multiple languages supported?</h3>
<p><a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> uses <a href="http://www.symfony-project.org/jobeet/1_4/Doctrine/en/19" target="_blank">Symfony&#8217;s Multi-Lingual architecture</a>. To add or edit a translation a developer needs to add a language switcher to tell <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> what language is being requested. Then the content editor can switch languages and make the translation just like if the site were a single language. A key benefit of contextual content management is that the translator can see how the size of the translation is effecting the page&#8217;s layout.</p>
<h3>What about user management?</h3>
<p>The very popular <a href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin" target="_blank">sfDoctrineGuardPlugin</a> is utilized to provide user management features like: login, logout, a user <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank">CRUD</a>, groups, and permissions. The<a href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin" target="_blank"> sfDoctrineGuardPlugin</a> is well tested, widely used and actively maintained. <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> does a very nice job of integrating the plugin into the CMS and it automaticly adopts the design of the rest of the site.</p>
<h3>What kind of problems can I expect?</h3>
<p>Installation is a little complicated, an experienced <a href="http://www.symfony-project.org/" target="_blank">Symfony</a> developer will come in handy here. <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> suggests using <a href="http://sourceforge.net/projects/svnforeigncopy/" target="_blank">svnforeigncopy</a> to clone their <a href="http://trac.apostrophenow.org/wiki/ManualInstallation#WaystoDownloadtheApostropheSandboxProject" target="_blank">sandbox project</a>, but I could never get it to work. I suspect that <a href="http://git-scm.com/" target="_blank">Git</a> might be a better version control system for this application.</p>
<p>I had trouble with the server requirements, specifically missing <a href="http://netpbm.sourceforge.net/" target="_blank">Netpbm</a> for image manipulation caused the media repository to hang in my <a href="http://www.wampserver.com/en/" target="_blank">WAMP</a> setup. This could have been handled better, but <a href="http://netpbm.sourceforge.net/" target="_blank">Netpbm</a> just had to be turned off.  At the suggestion of the <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> authors I got a <a href="http://servergrove.com/vps/pricing" target="_blank">$20/mo VPS</a> from <a href="http://servergrove.com/" target="_blank">ServerGrove</a> and all my (server) problems went away.</p>
<p>Having the admin interface integrated into the frontend means that it&#8217;s sometimes in the way. This is easily solved by adjusting the CSS to position the admin buttons.</p>
<p>Another issue with having the admin interfaces embedded in the page is the requirement for additional wrapping &lt;div&gt; tags. This will look like <a href="http://www.tyssendesign.com.au/articles/faqs/what-is-divitis/" target="_blank">divitis</a>, and make your CSS rules more complicated.</p>
<p>I ran into a couple bugs that I attribute to the CMS being fairly new. I&#8217;ve noticed the that the project is updated fairly frequently so I expect the stability to increase quickly.</p>
<p>Lastly, I&#8217;m a little concerned that my clients are going to ask me for ways to edit meta tags, like title, description, &amp; keywords. I&#8217;ve seen no easy way of accomplishing this, however it seems like a easy feature so I suspect it to be added in the near future. If a client needs it I&#8217;m sure I could make this happen without too much effort.</p>
<h3>So what do I do when I run into a problem?</h3>
<p>The <a href="http://www.punkave.com/" target="_blank">PunkAve</a> crew that authored <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> are very helpful on the <a href="http://groups.google.com/group/apostrophenow" target="_blank">Google Group</a>. I usually got responses in under an hour. Before asking for help make sure to go through the <a href="http://trac.apostrophenow.org/wiki/ManualInstallation#ApostropheManual" target="_blank">Manual</a>, <a href="http://trac.apostrophenow.org/wiki" target="_blank">Wiki</a>, <a href="http://trac.apostrophenow.org/query" target="_blank">Trac bug list</a>, and search the existing Google Group messages.</p>
<h3>Closing thoughts.</h3>
<p><a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> is my new favorite CMS, well actually it&#8217;s the only CMS I would choose to use. I really do not enjoy working with <a href="http://wordpress.org/" target="_blank">WordPress</a> &amp; <a href="http://drupal.org/" target="_blank">Drupal</a>, and <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> is an outstanding alternative. I&#8217;m very excited about the new <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> plugins for a <a href="http://www.symfony-project.org/plugins/apostropheBlogPlugin" target="_blank">blog</a> and a <a href="http://www.symfony-project.org/plugins/apostropheFormBuilderPlugin" target="_blank">form builder</a>. I&#8217;m actually looking for excuses to use them, maybe <a href="http://www.robertspeer.com" target="_blank">robertspeer.com</a> is due for a rebuild. A little bird told me about some exciting developments in the <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> world, follow <a href="http://twitter.com/apostrophenow" target="_blank">@apostrophenow</a> to be the first to know.</p>
<h3>About the author:</h3>
<p>Hello, I&#8217;m <a href="http://www.robertspeer.com/blog/symfony-development/" target="_blank">Robert Speer</a> a web professional experienced in leading the development of large web applications. Currently I&#8217;m working on a property marketing web application that I plan on integrating <a href="http://www.apostrophenow.com/" target="_blank">Apostrophe</a> into. I&#8217;m also accepting project work to fund my bootstrapping efforts, <a title="Contact me for symfony development" href="http://www.robertspeer.com/blog/symfony-development/">contact me</a> for more information.</p>
<p><strong>My Links: </strong> <strong> </strong> <strong> </strong> <strong> </strong></p>
<ul>
<li><span style="font-weight: normal;"><strong><span style="font-weight: normal;"><a href="http://www.linkedin.com/in/roberthspeer" target="_blank">http://www.linkedin.com/in/roberthspeer</a></span></strong></span></li>
<li><span style="font-weight: normal;"><a href="http://www.twitter.com/robert_speer" target="_blank">http://www.twitter.com/robert_speer</a></span></li>
<li><span style="font-weight: normal;"><a href="http://www.google.com/profiles/rhspeer" target="_blank">http://www.google.com/profiles/rhspeer</a></span></li>
</ul>
<p style="text-align: center;"><a class="aligncenter" href="http://www.dzone.com/links/apostrophenow_a_cms_so_easy_even_your_mom_could_u.html" target="_blank"><strong><span style="color: #003366;">If you found this review valuable please click here to vote it up on DZone </span></strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/apostrophenow-a-cms-so-easy-even-your-mom-could-use-it/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>5 tips for Cheaper Web Development</title>
		<link>http://www.robertspeer.com/blog/5-tips-for-cheaper-web-development/</link>
		<comments>http://www.robertspeer.com/blog/5-tips-for-cheaper-web-development/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 13:58:49 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=148</guid>
		<description><![CDATA[1. Requests for Proposals pay for themselves The RFP document will be how the development team provides an estimate on both the work described in the document and the risk you represent as a client. Better RFP documents will result in a higher response rate, more accurate estimates, less time in meetings talking about the [...]]]></description>
			<content:encoded><![CDATA[<div id="great-requests-for-proposal-rfp-pay-for-themselves" class="section">
<h2>1. Requests for Proposals pay for themselves</h2>
<p>The RFP document will be how the development team provides an estimate on both the work described in the document and the risk you represent as a client.  Better RFP documents will result in a higher response rate, more accurate estimates, less time in meetings talking about the RFP, and less padding to account for risk.</p>
<p>The customer acquisition process is the most expensive operation for a custom development shop.  Every lead that comes in the door represents a mix of opportunity, risk, and expense that development teams work very hard to mitigate.  The good news is that you are the one with the money to spend, but to get the most for your money, you need to maximize your vendors&#8217; opportunity and minimize their risk and expense.</p>
<p>Start your RFP with the the project working name, who to contact with questions, and how and where to submit the RFP to. Next, write a short, high-level project summary that includes what you want to do and how you will define success.  Follow the project summary with a project timeline with a deadline for submitting proposals, a start time, and when you need the project completed.  If you have any specific technical requirements, include them.  If parts of the project are already completed or will be sourced to other vendors, make that clear as well.</p>
<p>Make sure each page of the RFP has a page number; this will save you time when going over the document in phone calls.  Section headings also help to quickly steer conversations to the relevant portion of the document.</p>
<p>Focus the RFP on what needs to be done and avoid how it is going to get done.  Sometime there is a temptation to get into details, but a decent web development team will quickly figure that out on their own.  There are exceptions, but focusing on what to do and not how to do it is a good rule of thumb.</p>
<blockquote><p>Pro Tip: A good RFP document can replace about half of the scope of work document your development team will write, which translates to even more cost savings for you.</p></blockquote>
</div>
<p><span id="more-148"></span></p>
<div id="start-with-a-minimum-viable-product-mvp" class="section">
<h2>2. Start with a Minimum Viable Product</h2>
<p>A <a class="reference external" href="http://en.wikipedia.org/wiki/Minimum_viable_product">Minimum Viable Product</a> has just the features necessary to be deployed with a focus on the early adopters in your target demographic.</p>
<p>It is painful to cut away at a product you are passionate about; however, fewer features will result in a product that is easier for customers to use, an RFP that is easier to estimate, and a quicker time to market.  Fortunately, web applications built by skilled professionals are generally easy to add on to.  To communicate any features that you don&#8217;t want to be part of the current estimate but are likely to be in future releases, add a section for future considerations to make sure the estimated architecture will work with your future plans.</p>
<p>An example of a feature that is usually not needed for an MVP but will require architecture changes is Internationalization, or support for multiple languages.  Internationalization requires a different database structure as well as a modifications to every place internationalized text is displayed.</p>
<blockquote><p>Pro Tip: Carefully and realistically evaluating the priority of your required features will help the team meet your needs more efficiently.</p></blockquote>
</div>
<div id="flowcharts-clearly-describe-processes" class="section">
<h2>3. Flowcharts Clearly Describe Processes</h2>
<p>Every organization has a set of processes that are used to accomplish common goals.  These processes can be broken down into tasks and decisions that result in a set number of outcomes.  The most effective way of communicate processes is through a combination of ordered lists of text describing each step in the process and flowcharts.</p>
<p>If you don&#8217;t have Microsoft Visio to make your flowcharts, there are some excellent free alternatives available online:</p>
<ul class="simple">
<li><a class="reference external" href="http://www.gliffy.com">gliffy.com</a> (our preference)</li>
<li><a class="reference external" href="http://www.lovelycharts.com/">lovelycharts.com</a></li>
<li><a class="reference external" href="http://www.creately.com/">creately</a></li>
</ul>
<p>When defining your processes, make sure to point out <a class="reference external" href="http://en.wikipedia.org/wiki/Critical_path_method">critical paths</a> or parallel processes: Tasks that don&#8217;t depend on each other, so they can be done at the same time.</p>
<p>Flowcharts are only useful for describing processes and sometimes a sitemap.  To describe what your product will actually do you&#8217;ll need to write some functional specifications.</p>
</div>
<div id="use-wireframes-to-describe-your-features" class="section">
<h2>4. Use Wireframes to describe your features</h2>
<p>Wireframes are very simple drawings that define layout, features, &amp; navigation.  Wireframes do not define color schemes, typography, or other look &amp; feel aspects of the site.</p>
<p>While a printed wireframe is needed for the RFP document if you can supplement this with an interactive wireframe with integrated notes you will have better results.  My favorite tool for this is <a class="reference external" href="http://www.axure.com/">Axure</a>.  At $589, it&#8217;s not cheap, but there is a <a class="reference external" href="http://www.axure.com/downloads.aspx">30 day free trial</a> that may suffice for one project.  If you&#8217;d like some free online options, there are good ones, but you sacrifice features:</p>
<ul class="simple">
<li><a class="reference external" href="http://www.gomockingbird.com">gomockingbird.com</a></li>
<li><a class="reference external" href="http://www.balsamiq.com/products/mockups">balsamiq.com</a></li>
</ul>
<p>Smashing Magazine also did a excellent post on wireframe tools: <a class="reference external" href="http://www.smashingmagazine.com/2010/02/05/50-free-ui-and-web-design-wireframing-kits-resources-and-source-files/">50 Free UI and Web Design Wireframing Kits, Resources and Source Files</a>.</p>
<p>Functional specifications and wireframes are where the jump is made from a pure business or product management skillset to a task that requires specialized skills.  If you don&#8217;t feel comfortable creating your own wireframes, it&#8217;s time to seek the help of a professional <a class="reference external" href="http://en.wikipedia.org/wiki/Information_architecture">information architect</a>.</p>
<p>To get the most from your wireframes add page numbers, notes, and a separate page to list any difference in the feature set in the wireframes and in any other planning document.  Wireframes are a great tool for determining what features will be included and where they will live, but it&#8217;s easy to forget the project is on a budget.  So once you&#8217;re done make sure the project in the wireframes is still the project in your budget.  Page numbers are a really simple tool for keeping everyone on the same page.  They are often forgotten, but make meetings go much smoother.  Adding notes to the side of the page allows features to be better explained,  reducing assumptions and rework.</p>
<blockquote><p>Pro Tip: The professionalism of the documents you generate will strongly influence the way your business is perceived.</p></blockquote>
</div>
<div id="evaluating-the-proposals" class="section">
<h2>5. Evaluating The proposals</h2>
<p>After submitting your request for proposal to a development team, expect a response within the same business day.  The response will generally contain an introduction to the development team and a request for a question and answer session sometime within the next 24 to 48 hours.</p>
<p>Depending on how busy the team is, they should get a proposal to you within 5 days.  The proposal will be the development team&#8217;s paraphrased understanding of your RFP and Q&amp;A session.  Developers will need to convert your functional specifications into a system-level feature list for the purpose of estimation.  This is because several software systems are involved in any one page of a website.</p>
<p>After the features list, you will find an itemized hourly estimate. This will be grouped so that all dependencies for a given system are grouped into one line item.  If you find the need to negotiate down any of these items, request more information on them and try to cut out minor features or clarify existing features.  Generally, negotiating price is easiest if you are also cutting features.</p>
<p>The proposal should also contain a list of assumptions that describe dependencies and expectations that the development team has that you may or may not share.  A common one is that IE6 is not supported; however, if you will depend on large corporate clients still using IE6, this may not be a good idea.</p>
<p>The customer really can benefit from input from an experienced web development professional.  When you&#8217;re contracting professionals in an industry outside of your own, you need a team that&#8217;s going to keep you out of trouble by understanding the technical implications of your requirements and pro-actively pointing out new features or better ways of doing things.</p>
</div>
<p>Updates:</p>
<ul>
<li>May 26 2010 &#8211; cleaned up markup, added some more tips for the wireframe section</li>
</ul>
<p><small><br />
Note: I originally published this post on another blog.  It&#8217;s archived here because I think it&#8217;s useful, and I wanted to keep it updated with new tools and techniques.  It is an original work created &amp; owned by Robert Speer.<br />
</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/5-tips-for-cheaper-web-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfony 1.3 Book by Tim Bowler &amp; Wojciech Bancer</title>
		<link>http://www.robertspeer.com/blog/symfony-1-3-book/</link>
		<comments>http://www.robertspeer.com/blog/symfony-1-3-book/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 04:08:55 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=87</guid>
		<description><![CDATA[Symfony 1.3 Web Application Development is the latest book on the symfony PHP web framework and the first not written by the authors of the framework. This allows the authors to adopt a more pragmatic style that favors 3rd party plugins.  This is a good thing because IMHO the most important thing about a framework [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.packtpub.com/symfony-1-3-web-application-development/book" target="_blank">Symfony 1.3 Web Application Development</a> is the latest book on the <a href="http://www.symfony-project.org" target="_blank">symfony </a>PHP web framework and the first not written by the authors of the framework.</p>
<p>This allows the authors to adopt a more pragmatic style that favors <a href="http://www.symfony-project.org/plugins/" target="_blank">3rd party plugins</a>.  This is a good thing because IMHO the most important thing about a framework is it&#8217;s library of extensions.<span id="more-87"></span></p>
<p>The book also has a nice blend of information available in the already available <a href="http://www.symfony-project.org">symfony</a> <a href="http://www.symfony-project.org/book/1_2/" target="_blank">book</a>, <a href="http://www.symfony-project.org/cookbook/1_2/en/">cookbook</a>, and <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/" target="_blank">book length tutorials</a> using the techniques that a actual development team would use.</p>
<p>Unfortunately this book was pushed out before <a href="http://www.symfony-project.org/installation/1_3">symfony 1.3</a> was finished, and apparently before a sufficiently detail oriented proofer could go through the book.  Luckily the issues are primarily non-technical and mostly limited to the first few chapters and should not deter you from purchasing the book.</p>
<p>The most notable technical issue I have with the book is the use of a <a href="http://en.wikipedia.org/wiki/XML" target="_blank">XML</a> schema instead of a <a href="http://en.wikipedia.org/wiki/YAML">YAML</a> one, this actually works fine, it&#8217;s just a non-standard way of doing it.  Also sometimes it feels like the authors did a search for <a href="http://www.symfony-project.org/installation/1_2" target="_blank">1.2</a> and replaced it with <a href="http://www.symfony-project.org/installation/1_3" target="_blank">1.3</a>, again this is not that big a deal because the differences between the versions are mostly not relevant to beginner or intermediate<a href="http://trac.symfony-project.org/wiki/DevelopersForHire" target="_blank"> symfony developers</a>.</p>
<p>So would I recommend this book?  Yes, especially if <a href="http://www.packtpub.com/symfony-1-3-web-application-development/book" target="_blank">PAKT</a> comes out with a second revision with better editing.  This book provides valuable real world examples and accessible detail that eases the difficult learning curve of <a href="http://www.symfony-project.org/" target="_blank">symfony</a> development.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/symfony-1-3-book/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Internationalized (i18n) Admin Generator CRUD&#8217;s in Symfony 1.2.9 + Doctrine</title>
		<link>http://www.robertspeer.com/blog/i18nadmingenerator/</link>
		<comments>http://www.robertspeer.com/blog/i18nadmingenerator/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 22:50:43 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=64</guid>
		<description><![CDATA[I was having some trouble finding documentation on how to i18n generated CRUD&#8217;s, so once I figured (most) of it out I thought I&#8217;d share it The Example Application Since I have to create a feature in my one of my current work projects to store random bits of content, like privacy policies and such, [...]]]></description>
			<content:encoded><![CDATA[<p>I was having some trouble finding documentation on how to i18n generated CRUD&#8217;s, so once I figured (most) of it out I thought I&#8217;d share it</p>
<h2><span style="font-weight: normal;">The Example Application</span></h2>
<p><a href="http://www.robertspeer.com/i18n CRUD edit view.jpg" target="_blank"><img class="size-medium wp-image-69 alignright" title="i18n CRUD edit view" src="http://www.robertspeer.com/blog/wp-content/uploads/2009/10/i18n-CRUD-edit-view-168x300.jpg" alt="Content Block CRUD with French langage selected" width="168" height="300" /></a></p>
<p>Since I have to create a feature in my one of my current work projects to store random bits of content, like privacy policies and such, in multiple languages. I thought I&#8217;d double dip and use that for this example.  I&#8217;m calling the feature content blocks.  It will have a backend CRUD that will facilitate translations.  The UI I needed was to have the default language show up as well as one of the many languages this information would be translated into.  My app has the possibility of having more than 20 language options so putting them all in the CRUD at once was unreasonable.<span id="more-64"></span></p>
<p>The example to the left shows what the CRUD looks like when French is set as the user&#8217;s culture.  If the default language is chosen a second language form does not show up.</p>
<p>On the frontend I&#8217;m just going to do a simple data pull for this example.  Both the frontend and the backend app will have very simple language switchers  to demonstrate how that works.<br />
Now that I now how this works it&#8217;s actually pretty darn simple, however figuring it out took longer than I&#8217;d like.  Hopefully this tutorial will save you some time.</p>
<p>I&#8217;m going to skip the application setup, if you don&#8217;t know how to do that I used the same steps that are in the Doctrine version of the <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/01">Jobeet tutorial</a>.</p>
<p><a href="http://www.robertspeer.com/i18n_demo.zip" target="_self">Download the example app zip file here, includes Symfony 1.2.9</a></p>
<h2>Doctrine schema.yml</h2>
<p>The database schema.yml was by a little tricky at first.  I did not realize that Doctrine handles I18n tables so much differently from Propel.  With Propel I would have defined a second table named content_block_i18n and put the translated fields there.  For Doctrine they simply go in under the actAs and I18n.  This is less typing and I suspect more intuitive for those who don&#8217;t already know Propel.</p>
<p>Also remember to put columns: before your field definitions, and leave out the connection at the top of the file.  Timestammable adds the created_at &amp; updated_at fields.  Also notice that the data types are different from Propel&#8217;s.</p>
<p>I think I&#8217;m going to like these changes, but they are different so be careful if you are used to Propel.<br />
<code><br />
content_block:<br />
actAs:<br />
Timestampable: ~<br />
I18n:<br />
fields: [short_title, title, extract, content]<br />
columns:<br />
weight: integer<br />
active: boolean<br />
short_title: string(50)<br />
title:       string<br />
extract:     string<br />
content:     string(4000)<br />
</code><br />
Once you&#8217;re done: create your database, edit databases.yml, build-all, and clear you cache.  Details are in the Jobeet tutoral in <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/03" target="_blank">Day 3: The Data Model</a>.</p>
<h2>Adding embedI18n() to the form class a.k.a: where the magic happens</h2>
<p>This part took some serious research, I was just sure all I had to do was edit something in the generator.yml, but that turned out not to be the case.</p>
<p>I finally found  embedI18n() in the Forms in Action book in the i18n chapter under <a href="http://www.symfony-project.org/forms/1_2/en/08-Internationalisation-and-Localisation#chapter_08_propel_objects_internationalization">Propel Objects Internationalization</a>.  It does use the much maligned sfContext, and if you know a better way write a comment.</p>
<p>You&#8217;ll want to generate forms(php symfony doctrine:generate-forms) &amp; then the contend block CRUD (php symfony doctrine:generate-admin backend ContentBlock), as well as turn I18n on in the backend settings.yml.</p>
<p>This is in: lib/form/content_blockForm.class in the example application.<br />
<code><br />
/**<br />
* content_block form.<br />
*<br />
* @package    form<br />
* @subpackage content_block<br />
*/<br />
class content_blockForm extends Basecontent_blockForm<br />
{<br />
/**<br />
* Form configuration settings<br />
*<br />
* @author Robert H. Speer<br />
*/<br />
public function configure()<br />
{<br />
$this-&gt;embedI18n(array(sfConfig::get('sf_default_culture', 'en'),<br />
$this-&gt;getCurrentCulture())<br />
);<br />
}<br />
</code><br />
<code><br />
/**<br />
* pulls the current culture from the user object<br />
*<br />
* @return string<br />
* @author Robert H. Speer<br />
*<br />
* Notes:<br />
*  RHS 10/2/09 - sfContext::getInstance() violates MVC but I don't know a way<br />
*                around it ATM.<br />
*/<br />
public function getCurrentCulture()<br />
{<br />
$culture = sfContext::getInstance()-&gt;getUser()-&gt;getCulture();</code></p>
<p><code>if (strlen($culture)&gt;0) { // return user selected language<br />
return $culture;<br />
}else{ // return default culture, or defaults to english<br />
return sfConfig::get('sf_default_culture', 'en');<br />
}<br />
}</code></p>
<p><code>}</code></p>
<p><code> </code></p>
<h2>A simple language switcher component</h2>
<p>I&#8217;ve included a very simple language switching component in the example application.  Assuming you know <a href="http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer#chapter_07_sub_components" target="_self">how to write a component</a>, it&#8217;s not a big deal.</p>
<p>The actual language setter is in both apps (i know wet is bad) under language_switcher/actions/action.class.php &amp; looks like this:<br />
<code><br />
/**<br />
* changes the users culture and redirects them back the their previous page<br />
*<br />
* @author Robert H. Speer<br />
*/<br />
public function executeLanguage() {<br />
$this-&gt;getUser()-&gt;setCulture($this-&gt;getRequestParameter('culture'));</code></p>
<p><code> </code><code> $url = $this-&gt;getRequest()-&gt;getReferer() != '' ? $this-&gt;getRequest()-&gt;getReferer() : '@homepage';<br />
$this-&gt;redirect($url);<br />
}<br />
</code><br />
It&#8217;s going to take the user&#8217;s selected culture set that to the user object, and then redirect causing a refresh.</p>
<h2>How to get at that translated content</h2>
<p>This is the easy part, you actually don&#8217;t have to do anything special to grab content in the language set in the user object, just get the object and call the getter.</p>
<p>Grab the object(s) with something like this, but preferably in the model layer instead of apps/frontend/homepage/actions/action.class.php:<br />
<code><br />
/**<br />
* Executes index action<br />
*<br />
* @param sfRequest $request A request object<br />
*/<br />
public function executeIndex(sfWebRequest $request)<br />
{<br />
$this-&gt;block = Doctrine::getTable('content_block')-&gt;createQuery('a')-&gt;execute();<br />
}<br />
</code><br />
Then in your template you can access all the fields just like if they were in the same table (this is really cool):<br />
<code><br />
/**<br />
* Very simple homepage for demo purposes only<br />
*<br />
* @author Robert H. Speer<br />
*/<br />
foreach ($block as $key=&gt;$row)<br />
{<br />
echo 'id: '.$row-&gt;getId().'&lt;br&gt;';<br />
echo 'weight: '.$row-&gt;getWeight().'&lt;br&gt;';<br />
echo 'short title: '.$row-&gt;getShortTitle().'&lt;br&gt;';<br />
echo 'title: '.$row-&gt;getTitle().'&lt;br&gt;';<br />
echo 'extract: '.$row-&gt;getExtract().'&lt;br&gt;';<br />
echo 'content: '.$row-&gt;getContent().'&lt;br&gt;';<br />
echo 'created at: '.$row-&gt;getCreatedAt().'&lt;br&gt;';<br />
echo 'updated at: '.$row-&gt;getUpdatedAt().'&lt;br&gt;';<br />
echo 'lang: '.$row-&gt;getLang().'&lt;br&gt;';<br />
echo '&lt;hr&gt;';<br />
}</code></p>
<p>If you get the example app going on your own machine add a few records with some translations, then change the language with the language drop down and it will just work automagicaly.  For your own apps remember to turn I18n on in your applications settings.yml.</p>
<h2>Reference Links</h2>
<ul>
<li>As always the Symfony&#8217;s sweet <a href="http://www.symfony-project.org/doc/1_2/">documentation</a></li>
<li>Sandbox Web Solutions does a great job of explaining a <a href="http://sandbox-ws.com/frameworks/symfony-frameworks/how-to-embed-forms-in-symfony-12-admin-generator-part-3" target="_blank">different way to embed i18n forms in a generated CRUD</a></li>
</ul>
<h2>What I have not figured out yet</h2>
<ul>
<li>I have got the file upload widget to show up in the Admin generator but I it does not work automagicaly, like I think it should, I think I&#8217;m going to have to write the file handler myself.
<ul>
<li><em>edit 10/04/09 10:42PM</em> -&gt; <a href="http://stereointeractive.com/blog/2008/12/23/symfony-12-upload-a-file-inside-an-embedded-form/" target="_blank">Stereo Interactive has a work around for this</a></li>
</ul>
</li>
<li>Getting at the embedded fields in the generator.yml is elusive as well.</li>
</ul>
<p>I&#8217;ll be working on both of these problems as soon as I get back to work, so hopefully I&#8217;ll have an update soon.  If you figure it out first please write a comment.</p>
<h3><em>Disclaimer:</em></h3>
<p><em>By the time I was done writing this tutorial I was very ready to not be at my computer anymore, there are going to be some grammatical mistakes and maybe some code ones as well.  I through this together on WAMP, on my home desktop, so you may have to change the slashes on your path, and update your apache conf &amp;/or your .htaccess file to get it to work.  The application I&#8217;ve uploaded does work, but it is just a demo so don&#8217;t trust it too much <img src='http://www.robertspeer.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/i18nadmingenerator/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Symfony Plugin Review: sfEasyGMapPlugin</title>
		<link>http://www.robertspeer.com/blog/sfeasygmapplugin/</link>
		<comments>http://www.robertspeer.com/blog/sfeasygmapplugin/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 23:20:10 +0000</pubDate>
		<dc:creator>Robert Speer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=55</guid>
		<description><![CDATA[Symfony Plugin Review: sfEasyGMapPlugin The sfEasyGmapPlugin seeks to encapsulate much many of the features in the Google Maps API and make them easily available in the Symfony PHP 5 Framework. The Test: I set up a very basic Symfony 1.2.9 project and installed the plugin.  Installation of the plugin was a breeze the command line [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dzone.com/links/symfony_plugin_review_sfeasygmapplugin.html" target="_Dzone"><br />
<img src="http://widgets.dzone.com/links/images/std/vwidget3/vwidget_logo.gif" alt="Dzone" /><br />
</a></p>
<h2>Symfony Plugin Review: <a title="sfEasyGmapPlugin for Symfony" href="http://www.symfony-project.org/plugins/sfEasyGMapPlugin" target="_blank">sfEasyGMapPlugin</a></h2>
<p>The <a href="http://www.symfony-project.org/plugins/sfEasyGMapPlugin" target="_blank">sfEasyGmapPlugin</a> seeks to encapsulate much many of the features in the <a href="http://code.google.com/apis/maps/" target="_blank">Google Maps API</a> and make them easily available in the <a href="http://www.symfony-project.com" target="_blank">Symfony PHP 5 Framework</a>.<span id="more-55"></span></p>
<h3>The Test:</h3>
<p>I set up a very basic <a href="http://www.symfony-project.org/installation/1_2" target="_blank">Symfony 1.2.9</a> project and installed the plugin.  Installation of the plugin was a breeze the command line install worked flawlesly. Which is very nice, and unexpected, as many plugins work better if you install them manually.</p>
<p>The sample module worked exactly as advertised, after I corrected my Google Maps API key.</p>
<p>Pretty soon I had an example module created and was inputting my own locations, geocoding addresses, re centering, and using some nice syntactic sugar like the <a href="http://trac.symfony-project.org/browser/plugins/sfEasyGMapPlugin/trunk/lib/GMap.class.php#L682" target="_blank">centerAndZoomOnMarkers</a> method that does exactly what it says it does.</p>
<p>The example module covers the basics, but I&#8217;d also encourage you to browse through the <a href="http://trac.symfony-project.org/browser/plugins/sfEasyGMapPlugin/trunk/lib" target="_blank">classes </a>to get a sense of that this plugin will do.</p>
<p>My testing was fairly simplistic and I don&#8217;t have any experience with this app on a large application, however it would be my first choice if I had a project requiring mapping.</p>
<h3>The Results:</h3>
<p>The code is well done, object oriented, intuitive, &amp; very easy to use.</p>
<p>My only criticism is that it could do with a <a href="http://trac.symfony-project.org/browser/plugins/sfEasyGMapPlugin/trunk/lib/GMapMarker.class.php#L118" target="_blank">little more content</a> in it&#8217;s PHP docs, but that&#8217;s pretty minor.</p>
<p>I would strongly reccommend this plugin, and look forward to an excuse to use it, and I&#8217;d like to thank the authors for providing the community with such great code.</p>
<p>Thanks to:</p>
<ul>
<li><a href="http://www.symfony-project.org/plugins/developer/fabrice-bernhard">Fabrice Bernhard</a></li>
<li><a href="http://www.symfony-project.org/plugins/developer/laurent-bachelier">Laurent Bachelier</a></li>
<li><a href="http://www.symfony-project.org/plugins/developer/tom-haskins-vaughan">Tom Haskins-Vaughan</a></li>
<li><a href="http://www.symfony-project.org/plugins/developer/vincent-guillon">Vincent Guillon</a></li>
</ul>
<p>The authors come mostly from <a href="http://www.allomatch.com" target="_blank">Allomatch</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/sfeasygmapplugin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Symfony refactor of the Zend Quick Start Tutorial</title>
		<link>http://www.robertspeer.com/blog/symfony-refactor-of-the-zend-quick-start-tutorial/</link>
		<comments>http://www.robertspeer.com/blog/symfony-refactor-of-the-zend-quick-start-tutorial/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 20:21:55 +0000</pubDate>
		<dc:creator>robert_speer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=24</guid>
		<description><![CDATA[Learning Zend Framework and getting a repetitive stress injury doing it Edit: please see Matthew Weier O&#8217;Phinney&#8217;s (the current project lead for Zend Framework) response in the comments, there are some exciting things comming for ZF My friends &#38; colleagues have used Zend Framework (ZF) for a while, and I do my best to avoid it [...]]]></description>
			<content:encoded><![CDATA[<p><a style="text-decoration: none;" href="http://digg.com/programming/Symfony_Zend_PHP_Frameworks_compared" target="_DIGG"><br />
<img src="http://digg.com/img/badges/100x20-digg-button.gif" alt="Digg!" width="100" height="20" /></a> <a href="http://www.dzone.com/links/symfony_zend_php_frameworks_compared.html" target="_Dzone"><img src="http://widgets.dzone.com/links/images/std/vwidget3/vwidget_logo.gif" alt="Dzone" /><br />
</a></p>
<h2>Learning Zend Framework and getting a repetitive stress injury doing it</h2>
<p><em>Edit: please see Matthew Weier O&#8217;Phinney&#8217;s (the current project lead for Zend Framework) response in the comments, there are some exciting things comming for ZF</em></p>
<p><span style="font-family: Tahoma; line-height: 16px; color: #584d40;"> </span></p>
<h5 style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font: normal normal normal 180%/normal Tahoma, Verdana, Arial, Helvetica, sans-serif; color: #362f2c; padding: 0px;"><span style="color: #000000; font-family: Georgia; font-size: 13px; line-height: 19px;">My friends &amp; colleagues have used <a href="http://framework.zend.com/" target="_blank">Zend Framework (ZF)</a> for a while, and I do my best to avoid it and use the <a href="http://www.symfony-project.org/">Symfony PHP framework</a>.  Initially I was open to learning ZF, I was just curious why people liked it.  The more questions I asked, the more I realized there were no good answers other than standards for standards sake, and variations on the <a href="http://en.wikipedia.org/wiki/Sunk_costs#Loss_aversion_and_the_sunk_cost_fallacy">Sunk Cost Fallacy</a>.  If pressed I was told that I had to give <a href="http://framework.zend.com/">Zend Framework</a> a chance because it is a younger framework than <a href="http://www.symfony-project.org/">Symfony</a>, (um no).  Some of the developers had even written a library to add on to<a href="http://framework.zend.com/"> Zend Framework</a> to make it more usable, it contained features that were already in <a href="http://www.symfony-project.org/">Symfony</a>.  IMHO, writing code to help a framework catch up is an excellent reason to switch to another framework.</span></h5>
<p>This last week I was finally forced to use <a href="http://framework.zend.com/">ZF</a>, my rebellious use of <a href="http://www.symfony-project.org/">Symfony</a> only served to annoy the other developers, and had the potential to increase maintenance costs.  It seemed like a reasonable request, and all those developers couldn&#8217;t be wrong could they?<span id="more-24"></span></p>
<p>Well yes they are.  I work with some great people whose feelings I don&#8217;t wish to hurt, but I would estimate that <strong><a href="http://framework.zend.com/">Zend Framework</a></strong><strong> projects cost between 20 to 40 hours more for projects that run around ~400 hour plus. </strong><strong> With agency rates what they are that could turn in to 6 or 7 thousand dollars of added costs. </strong>Assuming requirements for user authentication and backend CRUD&#8217;s.  These numbers will vary widely from project to project.</p>
<p>From a quick comparison of the <a href="http://www.symfony-project.org/blog/category/Case+studies" target="_blank">Symfony Case Studies</a> and the <a href="http://framework.zend.com/about/casestudies" target="_blank">Zend Framework Case studies</a> I would expect this efficiency gap to continue to increase.  A couple of <a href="http://framework.zend.com/">Zend Framework</a>&#8216;s case study subjects have already failed: <a href="http://services.alphaworks.ibm.com/graduated/qedwiki.html">QEDWiki</a> &amp; <a href="http://www.pokerroom.com/community/forum/msg-220313-0#53">PokerRoom.com</a>, and anyone who&#8217;s been unfortunate enough to have to customize <a href="http://www.magentocommerce.com/">Magento</a> likely regrets the experience.   Symfony&#8217;s case studies are large successful projects you may have heard of:  <a href="http://www.symfony-project.org/blog/2009/02/18/dailymotion-powered-by-symfony">DailyMotion</a>, <a href="http://www.symfony-project.org/blog/2008/05/08/yahoo-answers-powered-by-symfony">Yahoo! Answers</a>, <a href="http://www.symfony-project.org/blog/2007/10/02/delicious-preview-built-with-symfony">Delicious</a>, &amp; <a href="http://www.symfony-project.org/blog/2006/10/28/yahoo-bookmarks-uses-symfony">Yahoo! Bookmarks</a>.  To be fair I&#8217;ve seen some really nice <a href="http://framework.zend.com/">Zend Framework</a> apps, I&#8217;ve just seen more interesting and larger <a href="http://www.symfony-project.org/">Symfony</a> projects.</p>
<h2>A Quick Comparison</h2>
<p>To present as fair a comparison as possible I have rewritten the <a href="http://framework.zend.com/docs/quickstart" target="_blank">Zend Framework Quick Start</a> as a <a href="http://www.symfony-project.org/">Symfony</a> app. I also used <a href="http://www.symfony-project.org/">Symfony</a> 1.2 with the Doctrine ORM, both of which I&#8217;ve not used before, as my projects have been in <a href="http://www.symfony-project.org/">Symfony</a> 1 or 1.1 and the Propel ORM so far.</p>
<p>I&#8217;ve formatted this more as a timeline of events rather than a tutorial, however the full <a href="http://www.symfony-project.org/">Symfony</a> app source is available <a href="http://www.robertspeer.com/sfZendQuickStart.zip" target="_self">HERE</a>.  To drop it on your web server you will have to change the path to <a href="http://www.symfony-project.org/">Symfony</a> in config/ProjectConfiguration.class.php, I had it running through <a href="http://www.wampserver.com/en/">WAMP</a> on my local machine.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">sfZendQuickStart Post</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>9:15am &#8211; 9:30am set up symfony app</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>9:30am -9:38am skip a bunch of Zend configs and translate layout to sf</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>9:40am &#8211; 9:43am generated controller &amp; view, skipping autoloading in the bootstrap file</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>9:43am &#8211; 10:06am set up database</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>wrote schema.yml to define guestbook table</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>setup database connection string:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>php symfony configure:database &#8211;name=doctrine &#8211;class=sfDoctrineDatabase &#8220;mysql:host=localhost;dbname=guestbook&#8221; username password</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> building model  (10:06am &#8211; 10:20am)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>php symfony doctrine:build-model (GSS)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>php symfony doctrine:build-sql   (generates the sql)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>php symfony doctrine:insert-sql  (putst the sql in the db)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>skipping the build database stuff, symfony does that for us</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Listing out all guestbook entries in view 10:20am &#8211; 10:35am (got distraced with doctrine, I usually use propel)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Generating form classes (10:48am)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>configuring to remove created at from view</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>unset( $this['created_at'], $this['updated_at'] );</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>random interruptions by wife&#8230;.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>writing view layer (11 am)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>writing controller for saving  (11:15am)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Setting up captcha</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>installing form extra plugin:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>php symfony plugin:install sfFormExtraPlugin</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>apparently I can&#8217;t type, kept putting the api keys in wrong , fancy reCaPTCHA complete (11:51am)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Double checked ZF Quick Start to make sure I did not forget anything</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>done (11:54am),</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> ~2hrs 39 min</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>with distractions, a mySQL db, and a decent captcha</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> under 150 lines of me-written code code, including html I C&amp;P&#8217;d from the zend tutorial</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>this means much less fumble finger type mistakes</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>The only config files I touched were</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>config/ProjectConfiguration.class.php to use Doctrine instead of propel automagically</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>config/doctrine/schema.yml to define the db tables</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>config databases.yml was set up from the command line so you be the judge on that one</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Zend</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>Bootstrap file configuration</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>appliation.ini configuration</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>the zf tutorial expects you to write around 515 lines of code to do the same thing</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 567px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span>that&#8217;s from the tutorial text not the well commented source code.</div>
<p>This also serves to document how I wasted a perfectly wonderful summer morning, *sigh*.</p>
<p>I did change some things around, I used MySQL because I&#8217;m not familiar with sqLite and, I used reCaptcha instead of a captcha similar to the tutorials.  I think these add difficulty, and are fair changes.</p>
<ol>
<li><span style="white-space: pre;"> </span>9:15am &#8211; 9:30am set up symfony app</li>
<li>9:30am -9:38am skip a bunch of Zend configs and translating layout to sf</li>
<li>9:40am &#8211; 9:43am generated controller &amp; view, skipping autoloading in the bootstrap file</li>
<li>9:43am &#8211; 10:06am set up database
<ol>
<li>wrote schema.yml to define guestbook table</li>
</ol>
<ol>
<li>setup database connection string:
<ol>
<li>php symfony configure:database &#8211;name=doctrine &#8211;class=sfDoctrineDatabase &#8220;mysql:host=localhost;dbname=guestbook&#8221; username password</li>
</ol>
</li>
</ol>
<ol>
<li>10:06am &#8211; 10:20am building model
<ol>
<li>php symfony doctrine:build-model (Getters, Setters &amp; Stuff or GSS)</li>
<li>php symfony doctrine:build-sql   (generates the sql)</li>
<li>php symfony doctrine:insert-sql  (inserts the sql into the db)</li>
<li>skipping the build database script, symfony does that for us</li>
</ol>
</li>
</ol>
</li>
<li>10:20am &#8211; 10:35am Listing out all guestbook entries in view  (got distracted with <a href="http://www.doctrine-project.org/" target="_blank">doctrine</a>, I usually use <a href="http://propel.phpdb.org/trac/" target="_blank">propel</a>)</li>
<li>10:48 am Generating form classes
<ol>
<li>configuring to remove created at from view
<ol>
<li>unset( $this['created_at'], $this['updated_at'] );</li>
</ol>
</li>
</ol>
</li>
<li>random interruptions by wife&#8230;.</li>
<li>11 am writing view layer</li>
<li>11:15am writing controller for saving</li>
<li>Setting up captcha
<ol>
<li>installing form extra plugin
<ol>
<li>php symfony plugin:install <a href="http://www.symfony-project.org/plugins/sfFormExtraPlugin" target="_blank">sfFormExtraPlugin</a></li>
<li><a href="http://www.symfony-project.org/plugins/sfFormExtraPlugin" target="_blank"></a>I can&#8217;t type, kept putting the api keys in wrong , fancy <a href="http://recaptcha.net/" target="_blank">reCaPTCHA</a> complete (11:51am)</li>
</ol>
</li>
</ol>
</li>
<li>Double checked <a href="http://framework.zend.com/docs/quickstart">ZF Quick Start</a> to make sure I did not forget anything</li>
<li>11:54am done</li>
</ol>
<h3>Development Highlights:</h3>
<h4>Symfony:</h4>
<ul>
<li><strong>under 150 lines of me-written code</strong>, including html I C&amp;P&#8217;d from the zend tutorial
<ul>
<li>this means much less fumble finger type mistakes</li>
</ul>
</li>
<li>~2hrs 39 min to complete from httpd.conf setup to form submission.
<ul>
<li>with distractions, a mySQL db, and a reCaptcha</li>
<li>I&#8217;ve clearly spent more time complaining about Zend Framework than it would take to complete the mini app in Symfony</li>
</ul>
</li>
<li>The only config files I touched were
<ul>
<li>config/ProjectConfiguration.class.php to use Doctrine instead of propel auto-magically</li>
</ul>
<ul>
<li>config/doctrine/schema.yml to define the db tables</li>
</ul>
<ul>
<li>config databases.yml was set up from the command line so you be the judge on that one</li>
</ul>
</li>
</ul>
<h4>Zend:</h4>
<ul>
<li>Configuration done in:
<ul>
<li>Bootstrap file configuration</li>
</ul>
<ul>
<li>appliation.ini configuration</li>
</ul>
</li>
<li>the zf tutorial expects you to write around<strong> 515 lines of code</strong> to do the same thing as Symfony
<ul>
<li>that&#8217;s from the tutorial text not the well commented source code.</li>
</ul>
</li>
<li>Also there promise of a &#8220;30-minute tour&#8221; can&#8217;t mean that you can program it in 30 minutes</li>
</ul>
<h2>Conclusions</h2>
<p><a href="http://framework.zend.com/" target="_blank">Zend Framework</a> is not bad, compared to using plain PHP there are some significant efficiency gains to be made.  However, when compared with <a href="http://www.symfony-project.org/">Symfony</a> and other frameworks, like <a href="http://www.djangoproject.com/" target="_blank">Django</a> &amp; <a href="http://rubyonrails.org/">Rails</a>,  it&#8217;s missing key features found in modern Web Development frameworks.  The tutorial I described here demonstrated the efficiency issues of not having code generation for the Model layer.  Two other key features are generated CRUD&#8217;s for backend site management, and a full MVC plugins like <a href="http://www.symfony-project.org/">Symfony</a>, <a href="http://rubyonrails.org/">Rails</a>, &amp; <a href="http://www.djangoproject.com/" target="_blank">Django</a> all have.</p>
<p>The long term ramifications of not having plugins and generated code accelerating your project are corners cut on quality, reduced features, scaling problems, and less competitive bids.  The lack of robust plugins in Zend also means that it will never be able have as many features as frameworks that do have Plugins.  Not having code generation means that developers are spending too much time writing mindless getter&#8217;s, setter&#8217;s, &amp; data grids and not enough time focusing on the core features of the project, or worse they are making compromises in quality to make deadlines.</p>
<p>I don&#8217;t believe that the <a href="http://framework.zend.com/" target="_blank">Zend Framework</a> is so far behind that it can&#8217;t catch up.  In certain areas it&#8217;s actually ahead of the game, however those areas tend to not be fascinating edge cases I get to use every so often, and not features I use on every site every day.  My suggestion for Zend is use the Model layer examples available (<a href="http://ar.rubyonrails.org/" target="_blank">Active Record</a>,  <a href="http://www.sqlalchemy.org/" target="_blank">SQLAlchemy</a>, <a href="http://www.doctrine-project.org/">Doctrine</a>) and  do something like that.  <a href="http://ruben.savanne.be/articles/integrating-zend-framework-and-doctrine" target="_blank">Doctrine already integrates well with Zend</a>, maybe that would be a good option.  Then start generating admin interfaces or <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank">CRUD</a>&#8216;s, this is huge, I find all kinds of ways to use these things to add value to my projects with a little typing on the command line.  Finally Plugins, the most important consideration when reviewing a framework or <a href="http://en.wikipedia.org/wiki/Content_management_system">CMS</a>.  The quantity and quality of plugins demonstrates the quality of the development tool.  It also means that there are developers out there that care about the tool outside of the core team.</p>
<p>If you are interested in learning more about Symfony there are excellent tutorials like the <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/">Jobeet example app</a>, a<a href="http://www.symfony-project.org/cookbook/1_2/en/"> cookbook</a>, a <a href="http://www.symfony-project.org/book/1_2/">guide book</a>, a <a href="http://www.symfony-project.org/cookbook/1_2/en/">reference book</a>, an <a href="http://www.symfony-project.org/api/1_2/">API</a>, and more on the <a href="http://www.symfony-project.org/doc/1_2/" target="_blank">symfony doc&#8217;s page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/symfony-refactor-of-the-zend-quick-start-tutorial/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
	</channel>
</rss>

