<?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 &#187; Web Development</title>
	<atom:link href="http://www.robertspeer.com/blog/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.robertspeer.com/blog</link>
	<description>Symfony,  PHP, Wordpress, Business Analysis</description>
	<lastBuildDate>Wed, 26 May 2010 14:50:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<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[<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>11</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[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[internationalization]]></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>2</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>25</slash:comments>
		</item>
		<item>
		<title>EstateSales.net &#8211; A great example of a niche market website</title>
		<link>http://www.robertspeer.com/blog/estatesalesnet-a-great-example-of-a-niche-market-website/</link>
		<comments>http://www.robertspeer.com/blog/estatesalesnet-a-great-example-of-a-niche-market-website/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 15:57:23 +0000</pubDate>
		<dc:creator>robert_speer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Entrepreneurs]]></category>
		<category><![CDATA[estatesales.net]]></category>
		<category><![CDATA[small business]]></category>
		<category><![CDATA[startups]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=19</guid>
		<description><![CDATA[So I was browsing through craigslist.com, looking for some deals.  I happened across a post for some estate sales in the garage sale section.  And this site was listed for more information. Turns out there are companies that do a lot of estate sales, which are pretty much well organized garage sales for the recently [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>So I was browsing through craigslist.com, looking for some deals.  I happened across a post for some estate sales in the garage sale section.  And this site was listed for more information.</p>
<p>Turns out there are companies that do a lot of estate sales, which are pretty much well organized garage sales for the recently deceased or almost deceased.  From the <a title="How EstateSales.net came to be" href="http://www.estatesales.net/story.aspx" target="_blank">EstateSales.net Story page</a> I learned that Dan McQuade had made a little business out fixing up and selling old mixers.  </p>
<p>From that side project he ended up meeting several people who organized estate sales, and from them he found a under served, and inefficient market that could benefit from the reach, information throughput, and scalability of the Internet.</p>
<p>Fortunately his son Mickey knows a thing or two about making websites.  In only a few short years they were an overnight success <img src='http://www.robertspeer.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Another awesome thing about this site is that they probably don&#8217;t have do deal with the hassle of a lot of employees.  Everything is probably, or should be, automated and manageable online from a beach chair in Jamaica.</p>
<p>If I wasn&#8217;t such a introverted curmudgeon I&#8217;d get out and find my own problems to solve and get rich off of, but for now I&#8217;ll just enjoy the success of others.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/estatesalesnet-a-great-example-of-a-niche-market-website/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>online bookstore optimized for &#8220;muddling through&#8221;</title>
		<link>http://www.robertspeer.com/blog/online-bookstore-optimized-for-muddling-through/</link>
		<comments>http://www.robertspeer.com/blog/online-bookstore-optimized-for-muddling-through/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 02:35:22 +0000</pubDate>
		<dc:creator>robert_speer</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=16</guid>
		<description><![CDATA[http://zoomii.com This is a really interesting take on a online bookstore that is really optimized for free form exploration with a very intuitive interface for those accoustomed to a mouse with a scroll wheel. Interesting User Interface, and it brings up some thought provoking usability questions. This type of experimentation is going to lead to [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Zoomii - online bookstore" href="http://zoomii.com" target="_blank">http://zoomii.com</a></p>
<p>This is a really interesting take on a online bookstore that is really optimized for free form exploration with a very intuitive interface for those accoustomed to a mouse with a scroll wheel.</p>
<p>Interesting User Interface, and it brings up some thought provoking usability questions.</p>
<p>This type of experimentation is going to lead to some very interesting Information architecture in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/online-bookstore-optimized-for-muddling-through/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webdigs got a 8.5 rating on it&#8217;s mortgage calculator</title>
		<link>http://www.robertspeer.com/blog/webdigs-got-a-85-rating-on-its-mortgage-calculator/</link>
		<comments>http://www.robertspeer.com/blog/webdigs-got-a-85-rating-on-its-mortgage-calculator/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 14:06:25 +0000</pubDate>
		<dc:creator>robert_speer</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=14</guid>
		<description><![CDATA[I don&#8217;t know why I&#8217;m still surprised by the Internet, but there&#8217;s a guy who ranks loan calculators. Fortunately he liked webdigs.com&#8216;s mortgage calculator: http://superloancalculators.com/?p=12 A new version of the mortgage calculator will be out soon, maybe we&#8217;ll break 9.]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t know why I&#8217;m still surprised by the Internet, but there&#8217;s a guy who ranks loan calculators.</p>
<p>Fortunately he liked <a href="http://www.webdigs.com">webdigs.</a><a href="http://www.webdigs.com">com</a>&#8216;s mortgage calculator:</p>
<p><a href="http://superloancalculators.com/?p=12">http://superloancalculators.com/?p=12 </a></p>
<p>A new version of the mortgage calculator will be out soon, maybe we&#8217;ll break 9.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/webdigs-got-a-85-rating-on-its-mortgage-calculator/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TableKit a easy sortable table based on Prototype.js</title>
		<link>http://www.robertspeer.com/blog/tablekit-a-easy-sortable-table-based-on-prototypejs/</link>
		<comments>http://www.robertspeer.com/blog/tablekit-a-easy-sortable-table-based-on-prototypejs/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 01:44:41 +0000</pubDate>
		<dc:creator>robert_speer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[sortable tables]]></category>
		<category><![CDATA[TableKit]]></category>

		<guid isPermaLink="false">http://www.robertspeer.com/blog/?p=11</guid>
		<description><![CDATA[Many times using scripts I find on the Internet turns into kind of a hassle. They are usually unfinished side projects, or are kind of bloated and slow. TableKit is not one of those scripts, it&#8217;s fast &#38; easy to implement. Development time was low, and the designers didn&#8217;t complain too much about working with [...]]]></description>
			<content:encoded><![CDATA[<p>   Many times using scripts I find on the Internet turns into kind of a hassle.  They are usually unfinished side projects, or are kind of bloated and slow.</p>
<p><a href="http://www.millstream.com.au/view/code/tablekit/" target="_blank">TableKit</a>  is not one of those scripts, it&#8217;s fast &amp; easy to implement.  Development time was low, and the designers didn&#8217;t complain too much about working with it.   What it lets you do is create a html table slap in some ID&#8217;s &amp; classes, load the js, and you have a really nice sortable table.  This sort of elegance in design is never easy and the folks at <a href="http://www.millstream.com.au" target="_blank">Millstream Web Software</a> have done a great job on this.</p>
<p>I used it on the Real Estate site I&#8217;m working on <a href="http://www.webdigs.com/mywebdigs" target="_blank">webdigs.com/mywebdigs</a> (free sign up required) to organize our users favorite saved houses. I&#8217;ve found myself using it a lot for my own home search.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertspeer.com/blog/tablekit-a-easy-sortable-table-based-on-prototypejs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
