<?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>Chris Morrell &#187; wishlist</title>
	<atom:link href="http://cmorrell.com/tag/wishlist/feed" rel="self" type="application/rss+xml" />
	<link>http://cmorrell.com</link>
	<description>The personal home page of Chris Morrell</description>
	<lastBuildDate>Thu, 02 Feb 2012 16:34:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Better Zend Framework Documentation</title>
		<link>http://cmorrell.com/webdev/zf/zend-framework-documentation-777</link>
		<comments>http://cmorrell.com/webdev/zf/zend-framework-documentation-777#comments</comments>
		<pubDate>Tue, 30 Mar 2010 13:07:09 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=777</guid>
		<description><![CDATA[If you&#8217;ve every tried to navigate the Zend Framework documentation&#8217;s longer pages you&#8217;ve probably looked everywhere for a table of contents.  Sure, there&#8217;s a TOC for the major sections of the component, but if you&#8217;re looking for a specific part &#8230; <a href="http://cmorrell.com/webdev/zf/zend-framework-documentation-777">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve every tried to navigate the <a href="http://framework.zend.com/manual/en/zend.filter.set.html" target="_blank">Zend Framework documentation&#8217;s longer pages</a> you&#8217;ve probably looked everywhere for a table of contents.  Sure, there&#8217;s a TOC for the major sections of the component, but if you&#8217;re looking for a specific part of a page (or an overview of what that page covers) you&#8217;re out of luck.  For example, take a look at the Zend_Validate <a href="http://framework.zend.com/manual/en/zend.validate.set.html" target="_blank">list of standard validation classes</a>.  Now try to find the documentation on the URI validator.  Can&#8217;t find it?  That&#8217;s &#8217;cause it doesn&#8217;t exist.  Too bad you had to scroll down through 39 page-lengths&#8217; worth of documentation to find that out.</p>
<p><span id="more-777"></span>Wouldn&#8217;t it be nice if you&#8217;d had something like this:</p>
<p><img class="alignnone size-full wp-image-779" title="Zend Validate TOC" src="http://cdn1.cmorrell.com/wp-content/uploads/2010/03/Zend_Validate_TOC.png" alt="" width="281" height="338" /></p>
<p>Well, there are two things you can do.  The first is to vote on <a href="http://framework.zend.com/issues/browse/ZF-9509" target="_blank">ZF-9509</a> and <a href="http://framework.zend.com/issues/browse/ZF-9508" target="_blank">ZF-9508</a>.  But until the documentation is fixed, you can download my Greasemonkey script that gives you a page TOC right now:</p>
<p><a href="http://userscripts.org/scripts/show/72873" target="_blank">[Download id not defined]</a></p>
<p>Hope you enjoy!</p>
<div class="su-linkbox" id="post-777-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/zend-framework-documentation-777&quot;&gt;Better Zend Framework Documentation&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/zend-framework-documentation-777/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Review: Zend Framework 1.8 Web Application Development</title>
		<link>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760</link>
		<comments>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760#comments</comments>
		<pubDate>Wed, 24 Mar 2010 15:02:26 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=760</guid>
		<description><![CDATA[At the beginning of February PACKT Publishing sent me a copy of Zend Framework 1.8 Web Application Development by Keith Pope and asked me to post a review.  Unfortunately a bunch of stuff came up, so it wasn&#8217;t until this &#8230; <a href="http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At the beginning of February <a href="http://www.packtpub.com/" target="_blank">PACKT Publishing</a> sent me a copy of <em><a href="http://www.amazon.com/gp/product/1847194222?ie=UTF8&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;tag=inxilcom-20&amp;creativeASIN=1847194222">Zend Framework 1.8 Web Application Development</a></em> by Keith Pope and asked me to post a review.  Unfortunately a bunch of stuff came up, so it wasn&#8217;t until this last week that I got a chance to really look it over.  Here are some of my thoughts.</p>
<p><span id="more-760"></span></p>
<p>The book is structured in two parts.  The first two chapters cover the basic setup of the Zend Framework (ZF) and, more specifically, a look at its Model-View-Controller (MVC) implementation.  Almost all of the book from there on out focuses on building a real-world ecommerce application using ZF.  I tend to be a learning-by-doing type of person, which I think tends to be true of many programmers, so I think this is a pretty good way to lay out a book.</p>
<p>Much of the book focuses on Models, and how to use various ZF components to implement your domain logic.  Most people agree nowadays that you should have fat models and skinny controllers (in that your controllers should really just have enough code to facilitate your models doing the work), and Keith Pope&#8217;s focus on models really hits this home in the book.  The topics of user accounts, the shopping cart and the catalog are all addressed in this light, while still bringing up topics like forms, controllers, views, action helpers, etc.</p>
<p>In general, the book focuses on best practices, which I think is really important for new ZF developers.  Because one of the guiding principals of the Zend Framework is that it gives you freedom to implement things however you like and use only the components you want, it can be hard for people just getting started to get a sense of how they should use certain components, and particularly how everything falls together in a &#8220;typical&#8221; MVC application.   Following along with the development of the storefront application in this book is a great way to see how those components often are used together.</p>
<p>That said, there are ways in which the code in this book is outdated or less-than-ideal.  As with anything that moves as fast as the Zend Framework has been moving, it&#8217;s hard to keep up with the latest tricks and best practices (and in some places it feels like they skipped on editing to try to publish the book before it got too outdated—there are plenty of minor code inconsistencies and typos throughout).  This book is a good place to get started, but keep in mind that the Zend Framework is already at 1.10, with 2.0 on the horizon, so anything that&#8217;s not the <a href="http://framework.zend.com/manual/en/" target="_blank">Zend Framework Official Documentation</a> is in danger of being out of date at any moment.</p>
<p>Also, keep in mind that there&#8217;s already a lot of good information out there, so if you don&#8217;t mind finding it yourself, you might not need a book.  In fact, I found that most of the code in the authorization chapter was almost a direct copy of <a href="http://weierophinney.net/matthew/archives/201-Applying-ACLs-to-Models.html" target="_blank">Matthew Weier O&#8217;Phinney&#8217;s blog post on Applying ACL&#8217;s to Models</a>.  If you read blogs like Matthew&#8217;s (who is the project lead for ZF, and a fantastic resource) and spend time on <a href="http://zftalk.com/" target="_blank">#zftalk</a> you can figure most things out on your own (<a href="http://site.svn.dasprids.de/trunk/" target="_blank">Ben Scholzen&#8217;s demo application</a> is another good starting point).  The information may be a little scattered, but it&#8217;s out there.</p>
<p>In the end, I think that this book would be a really helpful resource to someone who&#8217;s just getting started with MVC architecture and other design patterns in PHP.  It also is a good way to see most of the Zend Framework best practices put to use in one place.  On the other hand, if you want the latest information available and are willing to work for it, everything you need is probably online and free.</p>
<p>Some resources that might be helpful to new ZF developers:</p>
<ul>
<li><a href="http://devzone.zend.com/tag/Zend%20Framework" target="_blank">Zend DevZone</a></li>
<li><a href="http://stackoverflow.com/questions/tagged/zend-framework" target="_blank">Questions tagged w/ Zend Framework on Stack Overflow</a></li>
<li><a href="http://zftalk.com/" target="_blank">#zftalk</a></li>
<li><a href="http://www.zendframeworkinaction.com/" target="_blank">Zend Framework in Action Blog</a></li>
<li><a href="http://weierophinney.net/matthew/" target="_blank">Matthew Weier O&#8217;Phinney&#8217;s Blog</a></li>
<li><a href="http://www.rmauger.co.uk/" target="_blank">Ryan Mauger&#8217;s Blog</a></li>
<li><a href="http://www.dasprids.de/" target="_blank">Ben Scholzen&#8217;s Blog</a></li>
</ul>
<div class="su-linkbox" id="post-760-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760&quot;&gt;Review: Zend Framework 1.8 Web Application Development&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/review-1-8-web-application-development-760/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Zend Framework Bash Completion Script</title>
		<link>http://cmorrell.com/webdev/zf/bash-completion-script-751</link>
		<comments>http://cmorrell.com/webdev/zf/bash-completion-script-751#comments</comments>
		<pubDate>Sat, 20 Mar 2010 15:05:11 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=751</guid>
		<description><![CDATA[If you use the Zend Framework CLI interface much you probably find yourself expecting tab-completion to work.  Well, with this bash completion script it will.  Just add the following line to your .bashrc or .bash_profile: source path/to/zf.bash Next time you &#8230; <a href="http://cmorrell.com/webdev/zf/bash-completion-script-751">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you use the Zend Framework CLI interface much you probably find yourself expecting tab-completion to work.  Well, with this bash completion script it will.  Just add the following line to your .bashrc or .bash_profile:</p>
<p><code>source path/to/zf.bash</code></p>
<p>Next time you load the terminal, you can type &#8220;zf c&#8221; and hit TAB twice to see a list of available commands (change, configure and create&#8221; or type &#8220;zf cr&#8221; and hit TAB to have &#8220;create&#8221; automatically inserted for you.  The script works for both action names and provider names (but not for anything past that).  Eventually I want the script to dynamically load the available commands (so that it works with custom providers and future versions of ZF without updates) but I couldn&#8217;t get that working for this version so I just hard coded them.</p>
<p>There&#8217;s also a version that completes commands from the <a href="http://cmorrell.com/open-source/galahad-framework-extension">Galahad Framework Extension</a> if you&#8217;re testing that out…</p>
<a href="http://cmorrell.com/downloads/5" title="Version 1.10.2, Downloaded 1827 times">Zend Framework CLI Bash Completion Script [1.71 kB]</a>
<p>Enjoy!</p>
<div class="su-linkbox" id="post-751-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/bash-completion-script-751&quot;&gt;Zend Framework Bash Completion Script&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/bash-completion-script-751/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Namespacing ACL resources &amp; Galahad_Acl</title>
		<link>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737</link>
		<comments>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737#comments</comments>
		<pubDate>Wed, 17 Mar 2010 16:04:25 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[galahad-fe]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=737</guid>
		<description><![CDATA[In most of my applications I like to handle authorization (querying the ACL) in one (or more) of three ways: Authorize access to a model&#8217;s method Authorize access to a controller action Authorize access to an arbitrary &#8220;permission&#8221; In general &#8230; <a href="http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In most of my applications I like to handle authorization (querying the ACL) in one (or more) of three ways:</p>
<ul>
<li>Authorize access to a model&#8217;s method</li>
<li>Authorize access to a controller action</li>
<li>Authorize access to an arbitrary &#8220;permission&#8221;</li>
</ul>
<p>In general I find it&#8217;s best to keep authorization within the domain (querying the ACL within my models when they&#8217;re accessed) as this provides the most consistent behavior.  For example, if I eventually add a REST API to my application I don&#8217;t have to duplicate all my authorization logic in the new REST controllers.  When the application calls something like <code>Default_Model_Post::save()</code> it either saves or throws an ACL exception, no matter where it was called from.  This is great in that it saves me from having to duplicate code and keeps my system more secure.</p>
<p>On the other hand, there are times when it&#8217;s just a lot easier to handle authorization in the controller.  For example, if guests should never access my &#8220;Admin&#8221; module, it doesn&#8217;t make sense to ever let them access /admin/ URLs.  Also, if you&#8217;re using Zend_Navigation, having ACL resources that match controller actions lets you utilize its ACL integration.</p>
<p>If you&#8217;re ever going to mix these two techniques, you&#8217;ll eventually bump into the case where a model and a controller share the same name.  What if you need to set permissions on a &#8220;user&#8221; controller and different permissions on a &#8220;user&#8221; model?  This is where namespacing comes into play.  As suggested by the <a href="http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.navigation.setup" target="_blank">Zend Framework manual</a>, I always name my controller action resources in the format <code>mvc:module.controller.action</code>.  I name my model resources similarly, in the format <code>model:module.modelName.methodName</code>.  In both theses cases, &#8220;mvc&#8221; and &#8220;model&#8221; are the namespace, and everything following the colon is the actual resource name.  Now I can refer to my &#8220;admin&#8221; module as <code>mvc:admin</code> and the models within my admin module as <code>model:admin</code>.</p>
<p>This is where things get interesting.  If you set up your ACL chains correctly, you can set permissions on whole modules or models and have those rules cascade to their child controllers or methods.  For example, say you set up your ACL as follows:</p>
<pre class="brush: php; title: ; notranslate">
$acl = new Zend_Acl();
$acl-&gt;addResource('mvc:');
$acl-&gt;addResource('mvc:admin', 'mvc:');
$acl-&gt;addResource('mvc:admin.user', 'mvc:admin');
$acl-&gt;addResource('mvc:admin.user.create', 'mvc:admin.user');

$acl-&gt;addRole('guest');
$acl-&gt;addRole('admin', 'guest');

$acl-&gt;deny();
$acl-&gt;allow('admin', 'mvc:admin');
</pre>
<p>Now if a user with the role &#8220;admin&#8221; tries to access the resource &#8220;mvc:admin.user.create&#8221; (http://basename/admin/user/create) they will be allowed, but a user with the role &#8220;guest&#8221; will not.  Using this technique gives you as much granularity as you need in your ACL, but at the same time lets you set broad permissions where appropriate.</p>
<p>This is where <code>Galahad_Acl</code> comes into play.  Setting up all these resources can be tedious, as is checking permissions in each controller.  <code>Galahad_Acl</code> in conjunction with <code>Galahad_Model_Entity</code> and <code>Galahad_Controller_Plugin_Acl</code> automate everything but the actual permissions that are specific to your application.</p>
<p><span id="more-737"></span></p>
<p>By default, whenever <code>Galahad_Acl</code> has a role added to it in the format &#8220;namespace:resource.subResourse&#8221; (etc) it automatically adds the resources up the chain.  For example, if I add &#8220;mvc:default.index.index&#8221; to a Galahad_Acl object, it would add the following resources to the ACL:</p>
<ul>
<li>mvc:</li>
<li>mvc:default (parent = &#8220;mvc:&#8221;)</li>
<li>mvc:default.index (parent = &#8220;mvc:default&#8221;)</li>
<li>mvc:default.index.index (parent = &#8220;mvc:default.index&#8221;)</li>
</ul>
<p><code>Galahad_Controller_Plugin_Acl</code> takes this a step further by automatically adding any controller action that&#8217;s dispatched to the ACL and then checking against the ACL.  This means that with the following ACL:</p>
<pre class="brush: php; title: ; notranslate">
$acl = new Galahad_Acl();
$acl-&gt;addRole('guest');
$acl-&gt;addRole('staff', 'guest');
$acl-&gt;addRole('admin', 'staff');
$acl-&gt;addResource('mvc:blog.entry.view');
$acl-&gt;deny();
$acl-&gt;allow('admin', 'mvc:');
$acl-&gt;allow('staff', 'mvc:blog');
$acl-&gt;allow('guest', 'mvc:blog.entry.view');
</pre>
<p>The following would be true:</p>
<ul>
<li>Role &#8220;admin&#8221; would be allowed access to any URL (&#8220;admin&#8221; is allowed access to &#8220;mvc:&#8221;)</li>
<li>Role &#8220;staff&#8221; would be allowed access to /blog/entry/edit even though permissions weren&#8217;t explicitly set for the resource &#8220;mvc:blog.entry.edit&#8221; (because &#8220;staff&#8221; is allowed to access &#8220;mvc:blog&#8221;)</li>
<li>Role &#8220;guest&#8221; would be allowed to view /blog/entry/view but no other portion of the blog (&#8220;guest&#8221; is allowed access to the specific resource &#8220;mvc:blog.entry.view&#8221;)</li>
</ul>
<p><code>Galahad_Model_Entity</code> works similarly.  By default each entity adds itself to the ACL in the format &#8220;model:module.modelName&#8221; so that the model <code>Default_Model_User</code> has the resource ID &#8220;model:default.user&#8221;.  Each model has a method called <code>_initAcl</code> which lets you manage permissions on a per-model basis.  This is better demonstrated in code:</p>
<pre class="brush: php; title: ; notranslate">
class Default_Model_Post extends Galahad_Model_Entity
{
    protected function _initAcl($acl)
    {
        // Deny permissions to anything on this model unless explicitly allowed
        // We don't have to add &quot;model:default.post&quot; because Galahad_Model_Entity
        // automatically does that for us
        $acl-&gt;deny(null, $this);

        // Allow guests to fetch the content of posts
        $acl-&gt;allow('guest', $this, 'fetch')

        // Allow admins to save changes to posts
        $acl-&gt;allow('admin', $this, 'save')
    }

    public function save()
    {
        if (!$this-&gt;getAcl()-&gt;isAllowed($this-&gt;getRole(), $this, 'save')) {
            throw new Galahad_Acl_Exception('Current user is not allowed to save posts');
        }

        $dataMapper = $this-&gt;getDataMapper();
        return $dataMapper-&gt;save($this);
    }
}
</pre>
<p>So, as you can see, the model denies access to itself unless explicitly allowed, and then allows access to certain methods for certain roles.</p>
<p>All three of these classes are in their early stages of development, but I&#8217;d love some feedback on the ideas/suggestions on how to make them better.</p>
<p>Check out the code on GitHub:</p>
<ul>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Acl.php" target="_blank">Galahad_Acl</a></li>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Controller/Plugin/Acl.php" target="_blank">Galahad_Controller_Plugin_Acl</a></li>
<li><a href="http://github.com/inxilpro/Galahad-FE/blob/master/library/Galahad/Model/Entity.php" target="_blank">Galahad_Model_Entity</a></li>
</ul>
<p>Also, for more information about the <code>Galahad_Model</code> system, check out my previous post on <a href="http://cmorrell.com/web-development/more-php-modelling-383">modeling in the Zend Framework</a>.</p>
<div class="su-linkbox" id="post-737-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737&quot;&gt;Namespacing ACL resources &amp; Galahad_Acl&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/namespacing-acl-resources-galahad-acl-737/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zend Framework URI validator &amp; filter</title>
		<link>http://cmorrell.com/webdev/zf/validate-filter-url-728</link>
		<comments>http://cmorrell.com/webdev/zf/validate-filter-url-728#comments</comments>
		<pubDate>Fri, 12 Mar 2010 19:06:53 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=728</guid>
		<description><![CDATA[For the last couple of months I&#8217;ve been incorporating portions of applications I&#8217;m working on into my Galahad Framework Extension project.  Right now it&#8217;s not at a point where I&#8217;d feel comfortable promoting it (you can check out the project &#8230; <a href="http://cmorrell.com/webdev/zf/validate-filter-url-728">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the last couple of months I&#8217;ve been incorporating portions of applications I&#8217;m working on into my Galahad Framework Extension project.  Right now it&#8217;s not at a point where I&#8217;d feel comfortable promoting it (you can <a title="Galahad Framework Extension" href="http://bit.ly/d3ULiy" target="_blank">check out the project on GitHub</a> if you want), but there are portions that are pretty solid that might be useful to others right now.  Two such portions are <code>Galahad_Validate_Uri</code> and <code>Galahad_Filter_PrependHttp</code> which are both very useful for processing forms with URL fields.</p>
<p><span id="more-728"></span></p>
<p>Recently I was building a form that contained a URL field, and after browsing the <a href="http://framework.zend.com/manual/en/zend.validate.html" target="_blank">Zend_Validate docs</a>, I was surprised not to find a <code>Zend_Validate_Uri</code> component.  Luckily, <code>Zend_Uri</code> already validates URIs, so it was just a matter of writing a wrapper that followed the Zend_Validate APIs.  Basic usage:</p>
<pre class="brush: php; title: ; notranslate">
$validator = new Galahad_Validate_Uri();
$validator-&gt;isValid('http://www.google.com/');
</pre>
<p>Obviously this would be much more useful when combined with <code>Zend_Form</code> or some more extensive validation chains, but you get the point.</p>
<p>Grab <a href="http://bit.ly/cFB0li" target="_blank">Galahad_Validate_Uri</a> from GitHub.</p>
<p>The second issue I often deal with is people forgetting (or not knowing) to include http:// in the URLs that they submit.  Rather than solve this at the controller-level, I decided this was a common enough problem to build a Zend_Filter component for.  Basic usage:</p>
<pre class="brush: php; title: ; notranslate">
$filter = new Galahad_Filter_PrependHttp(array(
    'allowedSchemes' =&gt; array('http://', 'https://', 'mailto:'),
    'checkUri' =&gt; true,
));
echo $filter-&gt;filter('google.com'); // Prints 'http://google.com'
</pre>
<p>This filter takes any string and prepends &#8220;http://&#8221; to it if it doesn&#8217;t already contain an allowed scheme (more on that below).  By default it allows &#8220;http://&#8221;, &#8220;https://&#8221; and &#8220;mailto:&#8221; schemes, but you could set this to anything (say you want to allow &#8220;itms://&#8221; [iTunes] links) by setting the &#8216;allowedSchemes&#8217; option.  It also (optionally) checks if the resulting URI is valid, and only applies the filter if it is (effectively only prepending &#8220;http://&#8221; to otherwise valid URIs).  Remember, though, that &#8220;http://something&#8221; is technically a valid URI, so that will be accepted.  In the future I hope to add additional options to limit to URLs that follow certain standards.</p>
<p>Grab <a href="http://bit.ly/csqLWK" target="_blank">Galahad_Filter_PrependHttp</a> from GitHub.</p>
<p><strong>Update</strong>: I&#8217;ve submitted Zend_Filter_PrependHttp to the Zend Framework wiki for comments.  <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Filter_PrependHttp+-+Chris+Morrell" target="_blank">Check it out</a> and let me know if you think there&#8217;s anything I should change (I&#8217;ve posted a few ideas already).</p>
<p>The validator and filter work well together with <code>Zend_Form</code> to create URL form elements:</p>
<pre class="brush: php; title: ; notranslate">
$this-&gt;addElement('text', 'my_url', array(
    'label' =&gt; 'URL:',
    'filters' =&gt; array('StringTrim', 'StringToLower', new Galahad_Filter_PrependHttp()),
    'validators' =&gt; array(new Galahad_Validate_Uri()),
));
</pre>
<p>The form element generated by that code will produce fairly normalized, valid URIs.</p>
<div class="su-linkbox" id="post-728-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/validate-filter-url-728&quot;&gt;Zend Framework URI validator &amp; filter&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/validate-filter-url-728/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More PHP Modeling (w/ video demo)</title>
		<link>http://cmorrell.com/webdev/more-php-modelling-383</link>
		<comments>http://cmorrell.com/webdev/more-php-modelling-383#comments</comments>
		<pubDate>Fri, 04 Dec 2009 17:49:26 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=383</guid>
		<description><![CDATA[[Updated with follow-up video] About a month ago I posted some ideas about PHP modeling in the Zend Framework and requested feedback. After a month of on-and-off discussions through this website and #zftalk I decided to sit down and implement &#8230; <a href="http://cmorrell.com/webdev/more-php-modelling-383">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>[Updated with follow-up video]</strong></p>
<p>About a month ago I posted some ideas about <a href="http://cmorrell.com/web-development/php-modeling-in-zend-framework-360">PHP modeling in the Zend Framework</a> and requested feedback.  After a month of on-and-off discussions through this website and <a href="http://zftalk.com/">#zftalk</a> I decided to sit down and implement things a little more.<br />
<span id="more-383"></span><br />
I now have some working base classes that <a href="http://github.com/inxilpro/Galahad-FE">can be found on GitHub</a>.  Right now I&#8217;m still thinking things out, so there&#8217;s no guarantee that&#8217;s the structure I&#8217;m going to finish with, but it&#8217;s what I&#8217;m playing with right now.  So far I&#8217;ve dropped the DAO interface and the Galahad_Service parent class all together (since both are going to be pretty unique to your application).  What&#8217;s left is mostly the Entity class and the DataMapper class (as well as a very generic Collection class).</p>
<p>I&#8217;ve also started to write some tooling for my modeling system, based on <a href="http://framework.zend.com/manual/en/zend.tool.framework.html">Zend_Tool</a>.  Right now it&#8217;s generating the model itself, a DAO based on <a href="http://framework.zend.com/manual/en/zend.db.table.html">Zend_Db_Table</a> and a <a href="http://framework.zend.com/manual/en/zend.form.html">Zend_Form</a> (see <a href="http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html">Matthew Weier O&#8217;Phinney&#8217;s post about using forms in your models</a> for my reasoning there).  It doesn&#8217;t generate the DataMapper yet, but that&#8217;s just a matter of writing the code…</p>
<p>Again, I&#8217;d love some feedback on the direction this is going.  Check out the video below and then let me know.  Comment below, email me at <a href="http://mailhide.recaptcha.net/d?k=01t3MHtCNlY1OI8TgogO8VwQ==&amp;c=3NSszgQSWON_Ovzh0YWmlyKF776ZaMWSTct2mtNMEaM=" onclick="window.open('http://mailhide.recaptcha.net/d?k=01t3MHtCNlY1OI8TgogO8VwQ==&amp;c=3NSszgQSWON_Ovzh0YWmlyKF776ZaMWSTct2mtNMEaM=', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">*****@cmorrell.com</a> or get in touch on Twitter: <a href="http://twitter.com/inxilpro">@inxilpro</a>.</p>
<p>[<a href="http://www.screencast.com/t/MTFlZDJiNW" target="_blank">View full size</a>, or watch below]</p>
<p><object width="405" height="229"><param name="movie" value="http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/jingh264player.swf"></param><param name="quality" value="high"></param><param name="bgcolor" value="#FFFFFF"></param><param name="flashVars" value="thumb=http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/FirstFrame.jpg&#038;containerwidth=405&#038;containerheight=229&#038;content=http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/00000032.mp4"></param><param name="allowFullScreen" value="true"></param><param name="scale" value="showall"></param><param name="allowScriptAccess" value="always"></param><param name="base" value="http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/"></param>  <embed src="http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/jingh264player.swf" quality="high" bgcolor="#FFFFFF" width="405" height="229" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/FirstFrame.jpg&#038;containerwidth=405&#038;containerheight=229&#038;content=http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/00000032.mp4" allowFullScreen="true" base="http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/" scale="showall"></embed></object></p>
<p>Follow-up Video (demo of a lot more code):</p>
<p><object width="320" height="265"><param name="movie" value="http://www.youtube.com/v/oABFXO9WV6w&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x5d1719&#038;color2=0xcd311b"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/oABFXO9WV6w&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x5d1719&#038;color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="320" height="265"></embed></object></p>
<div class="su-linkbox" id="post-383-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/more-php-modelling-383&quot;&gt;More PHP Modeling (w/ video demo)&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/more-php-modelling-383/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
<enclosure url="http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/FirstFrame.jpg&amp;containerwidth=405&amp;containerheight=229&amp;content=http://content.screencast.com/users/inxilpro/folders/Jing/media/33a696b5-cc1f-4f15-af43-d6fb0e2b5fac/00000032.mp4" length="11368" type="video/mp4" />
		</item>
		<item>
		<title>Calculating the difference in days between two Zend_Date objects</title>
		<link>http://cmorrell.com/webdev/calculating-the-difference-in-days-between-two-zend_date-objects-373</link>
		<comments>http://cmorrell.com/webdev/calculating-the-difference-in-days-between-two-zend_date-objects-373#comments</comments>
		<pubDate>Wed, 18 Nov 2009 17:46:12 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend_date]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=373</guid>
		<description><![CDATA[This just came up on #zftalk, and it appears that the information out there is either incomplete or incorrect, so I thought I&#8217;d just put out a simple solution.  Here&#8217;s a simple way to calculate the difference between two Zend_Date &#8230; <a href="http://cmorrell.com/webdev/calculating-the-difference-in-days-between-two-zend_date-objects-373">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This just came up on <a href="http://zftalk.com/">#zftalk</a>, and it appears that the information out there is either incomplete or incorrect, so I thought I&#8217;d just put out a simple solution.  Here&#8217;s a simple way to calculate the difference between two Zend_Date objects (in days):</p>
<pre class="brush: php; title: ; notranslate">
$jan1 = new Zend_Date('1.1.2009', Zend_Date::DATES);
echo &quot;\nJanuary first: &quot;, $jan1-&gt;toString();

$christmas = new Zend_Date('25.12.2009', Zend_Date::DATES);
echo &quot;\nChristmas is on: &quot;, $christmas-&gt;toString();

$diff = $christmas-&gt;sub($jan1);
echo &quot;\nNumber of days: &quot;, $diff / 60 / 60 / 24;
</pre>
<div class="su-linkbox" id="post-373-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/calculating-the-difference-in-days-between-two-zend_date-objects-373&quot;&gt;Calculating the difference in days between two Zend_Date objects&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/calculating-the-difference-in-days-between-two-zend_date-objects-373/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP Modeling (in Zend Framework)</title>
		<link>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360</link>
		<comments>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360#comments</comments>
		<pubDate>Thu, 05 Nov 2009 05:52:15 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[modeling]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=360</guid>
		<description><![CDATA[I&#8217;ve been thinking a lot about Modeling in a MVC application, particularly in the Zend Framework. Obviously each application is different, and any Model is going to be fairly unique to your application. That&#8217;s why ZF doesn&#8217;t provide a base &#8230; <a href="http://cmorrell.com/webdev/php-modeling-in-zend-framework-360">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking a lot about Modeling in a MVC application, particularly in the <a href="http://cmorrell.com/category/web-development/zf">Zend Framework</a>.  Obviously each application is different, and any Model is going to be fairly unique to your application.  That&#8217;s why ZF doesn&#8217;t provide a base <code>Model</code> class.  That said, there are some design patterns that a lot of people are using nowadays, and applications could use some base functionality to facilitate those patterns.</p>
<p>Zend Framework&#8217;s project lead, <a href="http://weierophinney.net/matthew/">Matthew Weier O&#8217;Phinney</a>, has a lot of <a href="http://www.slideshare.net/weierophinney/architecting-your-models">great thoughts about Modeling</a> that I&#8217;ve been trying to stick to.  In implementing those ideas, I&#8217;ve started thinking out some base classes to build my Models on top of.  Obviously these classes won&#8217;t work for everyone.  But they should work for a lot of &#8220;typical&#8221; web applications.</p>
<p><span id="more-360"></span></p>
<p>That said, here are some notes that I&#8217;ve been putting together.  I&#8217;m posting them now (very early) in hopes that I get some feedback.</p>
<h3>The 6 Classes</h3>
<h4>Galahad_Model</h4>
<p>This is the base class that all my others extend.  It is there mostly to provide some helper functionality that all my other classes use (mostly for guessing class names based on a naming convention—more on that later).</p>
<h4>Galahad_Model_Entity</h4>
<p>The Entity is the base for all <em>things</em>.  For example, a <code>User</code> would extend the Entity class.  The <code>Galahad_Model_Entity</code> class has some basic methods for getting other objects.  I haven&#8217;t thought this entirely through yet, but an example would be the Entity&#8217;s &#8220;Parent&#8221; Service (see below) or maybe a <code>Form</code> associated with that model or something similar.</p>
<h4>Galahad_Model_Collection</h4>
<p>The Collection class is just a wrapper for an array of Entities.  I like this because it allows for type hinting/etc.  This is pretty much a generic wrapper for an array that implements Iterator and Countable.  I can&#8217;t think of much more that it needs.</p>
<h4>Galahad_Model_Service</h4>
<p>This probably doesn&#8217;t belong as part of the &#8220;Model&#8221;—I need to think that out.  The Service Layer is where your application logic happens that&#8217;s not strictly part of a particular Model (for example, an interaction between two Models).  An example might be authentication.  The service layer will often map pretty closely to a public API (although obviously there will be things that your application can do that shouldn&#8217;t be exposed to the public).</p>
<h4>Galahad_Model_DataMapper</h4>
<p>The <code>DataMapper</code> maps your <code>Entity</code> to the appropriate <code>DAO</code> (see below) and makes sure the <code>DAO</code> gets the data it&#8217;s expecting.  The way I think about this is that the Data Mapper expects an <code>Entity</code> as its input, but passes an array to the DAO.</p>
<h4>Galahad_Model_Dao</h4>
<p>The <em>Data Access Object</em> (DAO) is what takes the actual data in your entity and persists it.  The most common DAO is going to be a database, but a web service could be a DAO as could a filesystem or any other method of persisting data.  The DAO is going to have similar methods as the DataMapper, but it expects <em>just the data</em>—nothing else (that&#8217;s why you need the DataMapper to fetch and process the data in your Entity).  An easy way to show this is in code:</p>
<pre class="brush: php; title: ; notranslate">
class Default_Model_DataMapper_User
  extends Galahad_Model_DataMapper
{
    public function save(User $user)
    {
        $dao = $this-&gt;_getDao();
        $dao-&gt;save(array(
            'name' =&gt; $user-&gt;getName(),
            'email' =&gt; $user-&gt;getEmail(),
            'date_modified' =&gt; time(),
        ));
    }
}
class Default_Model_Dao_DbTable_User
  extends Zend_Db_Table_Abstract
  implements Galahad_Model_Dao_Interface
{
    protected $_name = 'user';

    public function save(Array $data)
    {
        $this-&gt;insert($data);
    }
}
</pre>
<h3>Notes</h3>
<p>I&#8217;m going to reiterate one more time that this is a very early concept and that I&#8217;m looking for feedback.  It could be that I&#8217;m thinking about things completely backwards and it all needs to be thrown away.  At this point I certainly don&#8217;t recommend people running too far with these ideas until they&#8217;ve been discussed/thought out a little more.</p>
<p><strong>About the Galahad_Model base class</strong>—since all the different pieces of your model will likely follow the same naming conventions, the <code>Galahad_Model</code> class provides some helper functionality to guess the name of classes.  For example, inside of  <code>Default_Model_DataMapper_User</code> you&#8217;ll probably need to get an instance of <code>Default_Model_Dao_DbTable_User</code>.  So <code>Galahad_Model_DataMapper</code> provides a nice <code>getDao()</code> method to do this for you.  If you&#8217;ve set the DAO, it uses that, but if you didn&#8217;t, it assumes you want a DbTable, guesses the name for you based on the DataMapper&#8217;s class name (so that if you choose <code>My_Model_DataMapper_Person</code> it&#8217;ll know to return a <code>My_Model_Dao_DbTable_Person</code>) and instantiates it for you.</p>
<h3>Thoughts?</h3>
<p>What do you think?  Does this make any sense?  Or am I trying to make a simple thing more complicated than it needs to be?  I think a lot of this would make more sense in code, so maybe I&#8217;ll try to get what I have started cleaned up a little and attach it to this post.  In the meantime, I&#8217;d love feedback (in the comments below, or to <a href="http://www.twitter.com/inxilpro">@inxilpro</a>.</p>
<div class="su-linkbox" id="post-360-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/php-modeling-in-zend-framework-360&quot;&gt;PHP Modeling (in Zend Framework)&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Zend Framework: Using separate layouts per module</title>
		<link>http://cmorrell.com/webdev/zf/zend-framework-using-separate-layouts-per-module-329</link>
		<comments>http://cmorrell.com/webdev/zf/zend-framework-using-separate-layouts-per-module-329#comments</comments>
		<pubDate>Fri, 10 Jul 2009 15:02:38 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=329</guid>
		<description><![CDATA[Someone was recently asking on ZFTalk about how to use a different layout for each module in your application. Since this is a problem I&#8217;ve dealt with in the past and planned on adding to the Galahad FE, I thought &#8230; <a href="http://cmorrell.com/webdev/zf/zend-framework-using-separate-layouts-per-module-329">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Someone was recently asking on <a href="irc://irc.freenode.net/zftalk">ZFTalk</a> about how to use a different layout for each module in your application.  Since this is a problem I&#8217;ve dealt with in the past and planned on adding to the <a href="http://www.galahadfe.com" target="_blank">Galahad FE</a>, I thought I&#8217;d quickly write up a tutorial on how to do it:</p>
<h3>First, download the Plugin</h3>
<p>Put the following class in a <code>library/Galahad/Controller/Plugin/Modularlayout.php</code> file (you&#8217;ll probably have to create all those directories and the file).</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
/**
* This file is part of the Galahad Framework Extension.
*
* The Galahad Framework Extension is free software: you can redistribute
* it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* The Galahad Framework Extension is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
*
* @category  Galahad
* @package   Galahad
* @copyright Copyright (c) 2009 Chris Morrell &lt;http://cmorrell.com&gt;
* @license   GPL &lt;http://www.gnu.org/licenses/&gt;
* @version   0.2
*/

/**
* Use separate layout per module
*
* @category   Galahad
* @package    Galahad
* @copyright  Copyright (c) 2009 Chris Morrell &lt;http://cmorrell.com&gt;
* @license    GPL &lt;http://www.gnu.org/licenses/&gt;
*/
class Galahad_Controller_Plugin_Modularlayout extends Zend_Controller_Plugin_Abstract
{
     public function routeShutdown(Zend_Controller_Request_Abstract $request)
     {
          Zend_Layout::getMvcInstance()-&gt;setLayout($request-&gt;getModuleName());
     }
}
</pre>
<h3>Next, add the Galahad namespace</h3>
<p>Update your <code>Bootstrap.php</code> file&#8217;s autoloader initialization method (if you don&#8217;t have one, add one):</p>
<pre class="brush: php; title: ; notranslate">
protected function _initAutoloaders()
{
	$this-&gt;getApplication()-&gt;setAutoloaderNamespaces(array('Galahad_'));
	return $this;
}
</pre>
<p>Please note: You might need to have other namespaces in there, like <code>My_</code> or <code>App_</code> or <code>Default_</code>.</p>
<h3>Next, add the Plugin</h3>
<p>Update your <code>Bootstrap.php</code> file&#8217;s plugin initialization method (if you don&#8217;t have one, add one):</p>
<pre class="brush: php; title: ; notranslate">
protected function _initPlugins()
{
	$this-&gt;bootstrap('autoloaders');
	$this-&gt;bootstrap('frontController');

	$plugin = new Galahad_Controller_Plugin_Modularlayout();
        $this-&gt;frontController-&gt;registerPlugin($plugin);
}
</pre>
<h3>And you&#8217;re set!</h3>
<p>Just make sure you have a layout file in your <code>layouts</code> directory for each module (<code>modulename.phtml</code>).</p>
<div class="su-linkbox" id="post-329-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/zf/zend-framework-using-separate-layouts-per-module-329&quot;&gt;Zend Framework: Using separate layouts per module&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/zf/zend-framework-using-separate-layouts-per-module-329/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>IDE Wishlist &#8211; HTML/CSS Auto-Complete/Magic Edition</title>
		<link>http://cmorrell.com/webdev/ide-wishlist-css-html-322</link>
		<comments>http://cmorrell.com/webdev/ide-wishlist-css-html-322#comments</comments>
		<pubDate>Wed, 24 Jun 2009 15:16:15 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=322</guid>
		<description><![CDATA[This list is clearly not comprehensive, but these are a few things I&#8217;ve been wishing for lately or thought of just now. CSS IDE Wishlist Order auto-complete based on usage, not alphabet I&#8217;m sick of typing &#8220;d&#8221; and getting &#8220;direction&#8221; &#8230; <a href="http://cmorrell.com/webdev/ide-wishlist-css-html-322">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This list is clearly not comprehensive, but these are a few things I&#8217;ve been wishing for lately or thought of just now.</p>
<h3>CSS IDE Wishlist</h3>
<ol>
<li><strong>Order auto-complete based on usage, not alphabet<br />
</strong>I&#8217;m sick of typing &#8220;d&#8221; and getting &#8220;direction&#8221; when I clearly have never used the CSS direction property in my entire life.  Clearly I mean display.  I use the display property all the $*(#ing time, and yet every time I hit &#8220;d&#8221; what do I get?</li>
<li><strong>Arrange properties alphabetically or by group</strong><br />
I&#8217;m a little obsessive about organizing my style sheets, and as part of that I generally try to keep properties in the same general place for each rule.  For example, I try to keep positioning properties near the beginning of each declaration, presentational properties after that, and anything else last.  But of course the order gets messed up.  Wouldn&#8217;t it be really cool if you could just press a button and have your IDE reorder all your declarations so they follow some set of rules?  Maybe a little overboard, but it would be really useful.</li>
</ol>
<h3>HTML IDE Wishlist</h3>
<ol>
<li><strong>Pattern recognition<br />
</strong>OK, how many times have I populated a list with the following code:</p>
<pre>&lt;li&gt;&lt;a href="#"&gt;Something&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#"&gt;Something Else&lt;/a&gt;&lt;/li&gt;</pre>
<p>Wouldn&#8217;t it be really cool if on the third list item an auto-complete drop down popped up offering:</p>
<pre>&lt;li&gt;&lt;a href="#"&gt;<strong>|</strong>&lt;/a&gt;&lt;/li&gt;</pre>
<p>Or something similar</li>
<li><strong>Lorem ipsum autocomplete<br />
</strong>I know some IDEs have a lorem ipsum generator built in, but wouldn&#8217;t it be cool if when you started typing <strong>lorem ips</strong> it would offer something like:</li>
</ol>
<blockquote>
<ul>
<li>Lorem ipsum (1 paragraph)</li>
<li>Lorem ipsum (2+ paragraphs&#8230;) — would pop up a generator dialog</li>
<li>Lorem ipsum (list of 10 elements)</li>
<li>Lorem ipsum (list of elements&#8230;) — would pop up  a generator dialog</li>
</ul>
<p>Even cooler would be if it adjusted the suggestions from context—so if you were in a list it would offer a list first, etc.</p></blockquote>
<div class="su-linkbox" id="post-322-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/ide-wishlist-css-html-322&quot;&gt;IDE Wishlist &#8211; HTML/CSS Auto-Complete/Magic Edition&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/ide-wishlist-css-html-322/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 18/62 queries in 1.433 seconds using disk: basic
Object Caching 1324/1464 objects using disk: basic
Content Delivery Network via cdn1.cmorrell.com

Served from: cmorrell.com @ 2012-02-09 16:07:58 -->
