<?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>nephtali blog</title>
	<atom:link href="http://blog.nephtaliproject.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.nephtaliproject.com</link>
	<description>Nephtali web framework updates and other techie stuff</description>
	<lastBuildDate>Thu, 15 Mar 2012 06:37:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Nephtali 3.3.2 Released: Streamlined Pure Pipe Registration and Many Enhancements/Fixes</title>
		<link>http://blog.nephtaliproject.com/?p=262</link>
		<comments>http://blog.nephtaliproject.com/?p=262#comments</comments>
		<pubDate>Thu, 02 Feb 2012 07:31:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[New Feature]]></category>
		<category><![CDATA[New Release]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=262</guid>
		<description><![CDATA[Finally, Nephtali 3.3.2 is released. The biggest addition to this release are the new registration functions that greatly simplify working with pure pipes. That said, there are several other improvements, and I&#8217;ve made a quick list of them below: Removed &#8230; <a href="http://blog.nephtaliproject.com/?p=262">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Finally, <a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">Nephtali 3.3.2 is released</a>. The biggest addition to this release are <a href="http://blog.nephtaliproject.com/?p=241">the new registration functions that greatly simplify working with pure pipes</a>. That said, there are several other improvements, and I&#8217;ve made a quick list of them below:</p>
<ul>
<li>Removed required_ports key from registor_action (vestige from days of old.)</li>
<li>Deprecated &#8216;is_valid&#8217; flag in favor of &#8216;is_set&#8217; flag for pure pipe signature checks.</li>
<li>Corrected omission of &#8216;error_message&#8217; spelling check for ports in debug mode.</li>
<li>Fixed JSON-formatting bug for REST-ful port validation requests containing multiple errors.</li>
<li>Port &#8216;error_message&#8217; option now properly overrides the default error messages generated for specific failures.</li>
<li>Started tradition of adding version number to the ncore root docblock to facilitate identification of the current version of Nephtali you&#8217;re using.</li>
<li>Fixed bug leading to unnecessary calls of curl parallel processing function.</li>
</ul>
<p>As usual, let me know if you see any issues.</p>
<p>Next, either integrated unit testing (now that the syntactically pure pipe functions are done, unit testing should be quite enjoyable) -OR- using caching capabilities to parse HTML files, create AST&#8217;s and store optimized code for databinding pages (should lead to big performance payoff.) What would you like next?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=262</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New registration functions for pure pipes</title>
		<link>http://blog.nephtaliproject.com/?p=241</link>
		<comments>http://blog.nephtaliproject.com/?p=241#comments</comments>
		<pubDate>Wed, 18 Jan 2012 08:10:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[New Feature]]></category>
		<category><![CDATA[New Release]]></category>
		<category><![CDATA[Software Development Practices]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=241</guid>
		<description><![CDATA[I suspect many of those who viewed the recent enhancements to Nephtali that promote pure pipe functions thought the example code was terribly verbose. Frankly, it is, for the most typical situations. With that admission, let me say that there &#8230; <a href="http://blog.nephtaliproject.com/?p=241">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I suspect many of those who viewed the <a href="http://blog.nephtaliproject.com/?p=210">recent enhancements to Nephtali that promote pure pipe functions</a> thought the example code was terribly verbose. Frankly, it is, for the most typical situations. With that admission, let me say that there is a method to my madness.</p>
<p>I firmly believe developers should strive to account for as much complexity as possible in the early stages of development.  After establishing a strong, extensible foundation from which to work, we can then examine various use cases of developers to identify the most common needs, and work to provide tools (general functions, API enhancements, hooks, plugins, etc.) that facilitate these high-traffic scenarios.</p>
<h2>General pipes</h2>
<p>In terms of Nephtali pipes, I first created a general pipe registration function. While using the general pipe can sometimes require significant amounts of code, it is extensible to every situation I&#8217;ve encountered while using Nephtali.</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\pipe\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'general_pipe'</span><span class="sy0">,</span>
    <span class="re0">$function</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$args</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="co1">// make it happen </span>
        <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<h2>Action pipes</h2>
<p>After working with Nephtali for a while, I realized that I could greatly facilitate one particular use case: performing specific actions if/when sets of ports are present on a request. This lead to the development of action pipes.</p>
<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\pipe\register_action<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'user'</span><span class="sy0">,</span>
    <span class="re0">$actions</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        n\port\signature<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'update_user'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="co1">// typically have port validation code here and db update, but omitted for brevity</span>
            <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'update'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span><span class="sy0">,</span>
        n\port\signature<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'insert_user'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="co1">// typically have port validation code here and db insert, but omitted for brevity</span>
            <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'insert'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<h2>General pure pipes</h2>
<p>Most recently, Nephtali had added the ability to work with functions that, at least in terms of syntactic appearance, are pure. The benefit to this type of approach is that unit testing a function that appears syntactically pure can be done with relative ease, as you can push in any set of values to a pipe&#8217;s function at test time to ensure that the function&#8217;s logic is correct.</p>
<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\pipe\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'user'</span><span class="sy0">,</span>
    <span class="re0">$function</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$args</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
                <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st_h">'User updated.'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
                    <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span> <span class="kw1">else</span>
        <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
                <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st_h">'User inserted.'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
                    <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
            <span class="kw1">return</span> <span class="st_h">''</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'signatures'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
            <span class="st_h">'update'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">,</span>
            <span class="st_h">'insert'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span>
	<span class="br0">&#41;</span><span class="sy0">,</span>
        <span class="re0">$args</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
            <span class="st_h">'update'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\sql\action\update<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'users'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'values'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span><span class="sy0">,</span>
            <span class="st_h">'insert'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\sql\action\insert<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'users'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'values'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#41;</span>
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<p>I think we can agree that the above example is painfully verbose, especially when one compares this code to equivalent code in other web frameworks. However, the above code is also very capable, and extends to situations where one may wish to manually work with many different sets of ports and sub-pipes, whilst keeping the ability to maintain the purity of the function (again, the purity I&#8217;m speaking of is the syntactic purity, which affords easy testing of the functions logic and correctness, as you can pass in any array of values to the $args array at test time.)</p>
<p>Now, having worked with the above code for several weeks, I&#8217;ve developed two functions that handle the most typical use cases.</p>
<h2>Pure display pipes</h2>
<p>One of the most common use cases is wanting to display a feedback view if one or more of the ports that the view requires is/are invalid, display a default view if there is data available, display an empty view if there is no data, or display an error view if there is an error during the processing of the pipe. This can now be accomplished through use of the <a title="Nephtali API documentation for pipe functions." href="http://nephtaliproject.com/documentation/api/index?id=9" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/api/index?id=9&amp;referer=');">n\pipe\register_pure_display() function</a>.</p>
<p>The pure display pipe expects a default, empty, error, and feedback view present in the markup for the pipe. And, just as with the other pipe functions, you can also pass in an optional $opts argument to set the databinding (form or placeholder); whitelists; override the default, feedback, or empty functions; etc.</p>
<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\pipe\register_pure_display<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'users'</span><span class="sy0">,</span>
    <span class="re0">$rows_func</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$port_vals</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
        <span class="kw1">return</span> n\sql\source\query<span class="br0">&#40;</span><span class="re0">$query</span> <span class="sy0">=</span> <span class="st_h">'SELECT * FROM users'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<h2>Pure action pipes</h2>
<p>As noted above, wanting to performing specific actions if/when sets of ports are present on a request is a common use case for Nephtali users, and the <a title="Nephtali API documentation for pipes." href="http://nephtaliproject.com/documentation/api/index?id=9" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/api/index?id=9&amp;referer=');">n\pipe\register_pure_action() function</a>  facilitates this workflow utilizing the new pure capabilities. The first action to have a valid signature (all of the ports are present, but not necessarily valid) will be executed.</p>
<p>The pure action pipe expects the markup to contain a feedback view for displaying error messages if any of the ports are invalid, a status view for displaying the status message (databound to its {message} placeholder within the &lt;!&#8211;data&#8211;&gt; region), and an error view.</p>
<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\pipe\register_pure_action<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'user'</span><span class="sy0">,</span>
    <span class="re0">$actions</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'update'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
            <span class="st_h">'io_func'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$port_vals</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
                <span class="kw1">return</span> n\sql\action\update<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'users'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$port_vals</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span><span class="sy0">,</span>
            <span class="st_h">'signature'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span> <span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">,</span>
            <span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st_h">'User updated.'</span>
        <span class="br0">&#41;</span>
        <span class="st_h">'insert'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
            <span class="st_h">'io_func'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$port_vals</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
                <span class="kw1">return</span> n\sql\action\insert<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'users'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$port_vals</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span><span class="sy0">,</span>
            <span class="st_h">'signature'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">,</span>
            <span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st_h">'User inserted.'</span>
        <span class="br0">&#41;</span>
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<h2>Conclusion</h2>
<p>Although not officially released yet, you can pull the changes from trunk to start utilizing the new pure functions to speed your development now. I won&#8217;t be changing the API at this point, although I may add a couple other features before making the next release. Hopefully you&#8217;ll find the new functions as useful as I do, and with this work out of the way, the next step will be to integrate unit testing directly within Nephtali.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=241</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update immediately from Nephtali 3.3.0 to 3.3.1 for a bug fix</title>
		<link>http://blog.nephtaliproject.com/?p=235</link>
		<comments>http://blog.nephtaliproject.com/?p=235#comments</comments>
		<pubDate>Thu, 01 Sep 2011 18:25:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[New Release]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=235</guid>
		<description><![CDATA[Sorry, there is a big string escaping bug in Nephtali 3.3.0. Please update immediately to Nephtali 3.3.1. The unit test didn&#8217;t show the issue because I only added one data row and because of caching, one row didn&#8217;t show the issue, &#8230; <a href="http://blog.nephtaliproject.com/?p=235">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sorry, there is a big string escaping bug in Nephtali 3.3.0. Please <a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">update immediately to Nephtali 3.3.1</a>. The unit test didn&#8217;t show the issue because I only added one data row and because of caching, one row didn&#8217;t show the issue, you need 2 rows to see the bug.</p>
<p>Again, my apologies.</p>
<p><strong>Update Feb. 23, 2012:</strong> To clear up confusion, the bug did not leave sites vulnerable in terms of security. Rather, Nephtali&#8217;s default behavior to escape all output overrode any whitelists that were set up to pass through the escaping mechanism. What this means is that sites were not left vulnerable to XSS attacks, but they were likely vulnerable to ugly aesthetics when expected tags were escaped.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=235</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nephtali 3.3.0 is live</title>
		<link>http://blog.nephtaliproject.com/?p=231</link>
		<comments>http://blog.nephtaliproject.com/?p=231#comments</comments>
		<pubDate>Tue, 16 Aug 2011 02:18:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[New Release]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=231</guid>
		<description><![CDATA[Nephtali 3.3.0 is now available for download. You can view what&#8217;s new in Nephtali 3.3.0 in the previous blog post entitled &#8220;What&#8217;s coming to Nephtali 3.3?&#8221; There are many new enhancements (including some performance improvements) and some big new features, so &#8230; <a href="http://blog.nephtaliproject.com/?p=231">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">Nephtali 3.3.0 is now available for download</a>. You can view what&#8217;s new in Nephtali 3.3.0 in the previous blog post entitled &#8220;<a href="http://blog.nephtaliproject.com/?p=210">What&#8217;s coming to Nephtali 3.3?</a>&#8221;</p>
<p>There are many new enhancements (including some performance improvements) and some big new features, so hopefully you take the time to read up. That said, the biggest new features are changes to the API that promote the usage of pure functions within pipes, making it easier to write correct code and integrate unit testing.</p>
<p>And, as always, please let me know if you find any issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=231</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s coming to Nephtali 3.3?</title>
		<link>http://blog.nephtaliproject.com/?p=210</link>
		<comments>http://blog.nephtaliproject.com/?p=210#comments</comments>
		<pubDate>Sat, 16 Jul 2011 07:39:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[New Feature]]></category>
		<category><![CDATA[New Release]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=210</guid>
		<description><![CDATA[What&#8217;s coming to Nephtali 3.3? Lots of stuff! Basic updates First, let&#8217;s get to the basic updates. Pipes can be set to be optionally displayed if the markup for the pipe is present (just set is_optional to true in $opts array &#8230; <a href="http://blog.nephtaliproject.com/?p=210">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What&#8217;s coming to Nephtali 3.3? Lots of stuff!</p>
<h2>Basic updates</h2>
<p>First, let&#8217;s get to the basic updates.</p>
<ol>
<li>Pipes can be set to be optionally displayed if the markup for the pipe is present (just set is_optional to true in $opts array for n\pipe\register().)</li>
<li>Ports can now be registered in bulk through n\port\register_bulk().</li>
<li>Regexes updated for url and US phone.</li>
<li>Many micro-optimizations implemented.</li>
<li>Many improvements to doc-blocks within the API.</li>
</ol>
<p>Now, before we move on to discuss the <strong>big new features</strong>, let me give you some background.</p>
<h2>Functional programming languages <em>light my fire</em></h2>
<p>I love functional programming languages. Nephtali&#8217;s design principles clearly trace their roots to my experience with functional languages such as LISP, Haskell, Erlang, and others. While PHP is obviously not a functional programming language, through the Nephtali framework I&#8217;ve sought to embrace general functional programming principles such as immutability, laziness through use of a registration model, and using arrays for everything under the sun.</p>
<p>One of my favorite aspects of functional languages is the value placed in keeping functions &#8220;pure.&#8221; You can read what <a href="http://en.wikipedia.org/wiki/Pure_function" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Pure_function?referer=');">Wikipedia says about pure functions</a> if you&#8217;re not familiar with them, but in short, a pure function will produce the same output for a given set of arguments every time the function is called because no other state is brought into or altered by the function. Pure functions are easier to reason about in terms of correctness, easier to test, and probably even increase life expectancy <img src='http://blog.nephtaliproject.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Some of you who are coming from functional languages are now saying to yourselves, &#8220;Yes, these principles of functional programming languages are great, but what could this possibly have to do with the syntactically challenged language PHP?&#8221;</p>
<p>I built a framework for PHP because of practical reasons. I develop websites for a living and my clients don&#8217;t care what language I&#8217;m using, they just want an effective, reasonably priced, maintainable website. PHP is a very practical language choice in light of these considerations. And, through Nephtali, I&#8217;ve been able to simulate some of the functional programming features I&#8217;ve missed the most. Now, back to the discussion of pure functions in Nephtali.</p>
<h2>Nephtali 3.3 will promote pure pipe functions</h2>
<p>While I can&#8217;t force particular functions to be pure in PHP, I can try and promote pure functions through the features and conventions in Nephtali, and Nephali 3.3 provides you with some handy features that facilitate keeping a lexically-pure pipe function. Let&#8217;s work through an example contrasting the code of an old-style Nephtali action pipe (I must stress Nephtali 3.3 is fully backwards compatible with this style) with the newer, pure-promoting style.</p>
<h3>Old-style action pipe</h3>
<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\port\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'id'</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> 10
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\port\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'company_name'</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">50</span><span class="sy0">,</span>
        <span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_TEXT
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\port\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'description'</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">500</span><span class="sy0">,</span>
        <span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_TEXT_MULTILINE
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\port\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'url'</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">200</span><span class="sy0">,</span>
        <span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_URL
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\port\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'did'</span><span class="sy0">,</span>
    <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        <span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> 10<span class="sy0">,</span>
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\val<span class="br0">&#40;</span><span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'update_host'</span><span class="sy0">,</span> <span class="re0">$value</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span><span class="st_h">'company_name'</span><span class="sy0">,</span><span class="st_h">'description'</span><span class="sy0">,</span><span class="st_h">'url'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
n\val<span class="br0">&#40;</span><span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'insert_host'</span><span class="sy0">,</span> <span class="re0">$value</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'company_name'</span><span class="sy0">,</span><span class="st_h">'description'</span><span class="sy0">,</span><span class="st_h">'url'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
n\val<span class="br0">&#40;</span><span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'delete_host'</span><span class="sy0">,</span> <span class="re0">$value</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'did'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
n\pipe\register_action<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'host'</span><span class="sy0">,</span>
    <span class="re0">$actions</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
        n\port\signature<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'update_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$rows</span> <span class="sy0">=</span> n\port\validate<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'update_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
            <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
&nbsp;
            n\sql\action\update<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> n\port\get<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'update_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've updated the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
         <span class="br0">&#125;</span><span class="sy0">,</span>
        n\port\signature<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'insert_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$rows</span> <span class="sy0">=</span> n\port\validate<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'insert_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
            <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
&nbsp;
            n\sql\action\insert<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> n\port\get<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'insert_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've added the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
         <span class="br0">&#125;</span><span class="sy0">,</span>
        n\port\signature<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'delete_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$rows</span> <span class="sy0">=</span> n\port\validate<span class="br0">&#40;</span>n\val<span class="br0">&#40;</span><span class="st_h">'delete_host'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
            <span class="br0">&#123;</span>
                <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
&nbsp;
            n\sql\action\delete<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$id</span> <span class="sy0">=</span> n\port\get<span class="br0">&#40;</span><span class="st_h">'did'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've deleted the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
         <span class="br0">&#125;</span>
    <span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<p>I won&#8217;t talk much about this example as most Nephtali users are familiar with this approach. However, let me just point out the amount of work it takes to either mentally work through correctness of the code OR write unit tests for it.</p>
<h3>New pure-promoting pipe</h3>
<div id="wpshdo_7" class="wp-synhighlighter-outer"><div id="wpshdt_7" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_7"></a><a id="wpshat_7" class="wp-synhighlighter-title" href="#codesyntax_7"  onClick="javascript:wpsh_toggleBlock(7)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_7" onClick="javascript:wpsh_code(7)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_7" onClick="javascript:wpsh_print(7)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_7" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\port\register_bulk<span class="br0">&#40;</span>
	<span class="re0">$ports</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
		<span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">10</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'company_name'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">50</span><span class="sy0">,</span>
			<span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_TEXT
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'description'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">500</span><span class="sy0">,</span>
			<span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_TEXT_MULTILINE
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'url'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> <span class="nu0">200</span><span class="sy0">,</span>
			<span class="st_h">'filter'</span> <span class="sy0">=&gt;</span> n\<a href="http://www.php.net/constant" onclick="pageTracker._trackPageview('/outgoing/www.php.net/constant?referer=');"><span class="kw3">constant</span></a>\FILTER_URL
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'did'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'max_length'</span> <span class="sy0">=&gt;</span> 10<span class="sy0">,</span>
		<span class="br0">&#41;</span>
	<span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
n\pipe\register<span class="br0">&#40;</span>
    <span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'host'</span><span class="sy0">,</span>
    <span class="re0">$function</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$args</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
				<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've updated the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
				<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've inserted the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
				<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;We've deleted the host&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> <span class="st_h">''</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="sy0">,</span>
	<span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
		<span class="st_h">'signatures'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
			<span class="st_h">'update'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span><span class="st_h">'company_name'</span><span class="sy0">,</span><span class="st_h">'description'</span><span class="sy0">,</span><span class="st_h">'url'</span><span class="br0">&#41;</span><span class="sy0">,</span>
			<span class="st_h">'insert'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'company_name'</span><span class="sy0">,</span><span class="st_h">'description'</span><span class="sy0">,</span><span class="st_h">'url'</span><span class="br0">&#41;</span><span class="sy0">,</span>
			<span class="st_h">'delete'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'did'</span><span class="br0">&#41;</span>
		<span class="br0">&#41;</span>
	<span class="br0">&#41;</span><span class="sy0">,</span>
	<span class="re0">$args</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
		<span class="st_h">'update'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			try <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\sql\action\update<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'values'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> catch <span class="br0">&#40;</span>Exception <span class="re0">$e</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span><span class="sy0">,</span>
		<span class="st_h">'insert'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			try <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\sql\action\insert<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$inputs</span> <span class="sy0">=</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'values'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> catch <span class="br0">&#40;</span>Exception <span class="re0">$e</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span><span class="sy0">,</span>
		<span class="st_h">'delete'</span> <span class="sy0">=&gt;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			try <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\sql\action\delete<span class="br0">&#40;</span><span class="re0">$table_name</span> <span class="sy0">=</span> <span class="st_h">'hosts'</span><span class="sy0">,</span> <span class="re0">$id</span> <span class="sy0">=</span> <span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'values'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'did'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> catch <span class="br0">&#40;</span>Exception <span class="re0">$e</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span>
	<span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<p>In the new style, the pipe function is structured so that you can quite easily reason about the flow AND write unit tests for it. No contrived mock objects, no IO gotchas, just pass in the arguments representing the states you want to test and voila, you&#8217;ve got a test (mind you, if you haven&#8217;t carefully reasoned the correctness of your code, your test will suck, but I know you like seeing pretty green lights, so&#8230;)</p>
<p>The &#8220;how&#8221; behind the above code owes much to the magic of the $args argument. While it looks like an array, it&#8217;s actually an object that implements the appropriate interfaces so it can be accessed like an array, keeping consistent with Nephtali&#8217;s M.O. in that regard. It stores the functions and only processes a function once you try to access the value. However, any further access to the variable makes use of a cached value result, so you don&#8217;t have to worry about calling an insert function more than once by accessing the value later on in your code, for example.</p>
<p>The beauty in the $args argument is that it encourages you to keep as much logic as possible in the easily tested pipe function. Only pull out the basic state-accessing/changing operations into the $args functions, and you&#8217;ll have code that&#8217;s easier to reason about and to test.</p>
<p>Coming soon, to a server near you&#8230;</p>
<p>P.S. &#8211; You can obviously refactor the new pure-promoting style so it is much shorter, as I&#8217;ve done below (and, indeed, it could even be shorter, but this gives you just a quick idea), but I didn&#8217;t include this in the body of the article out of fear that it&#8217;s harder to conceptually work through what&#8217;s going on in terms of the new features.</p>
<div id="wpshdo_8" class="wp-synhighlighter-outer"><div id="wpshdt_8" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_8"></a><a id="wpshat_8" class="wp-synhighlighter-title" href="#codesyntax_8"  onClick="javascript:wpsh_toggleBlock(8)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_8" onClick="javascript:wpsh_code(8)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_8" onClick="javascript:wpsh_print(8)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_8" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;"><span class="re0">$function</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$args</span><span class="sy0">,</span> <span class="re0">$signatures</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="re0">$valid_sig_processor</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$signature</span><span class="sy0">,</span> <span class="re0">$arg</span><span class="sy0">,</span> <span class="re0">$message</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signature</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'feedback'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$signature</span><span class="br0">&#91;</span><span class="st_h">'errors'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
				<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$arg</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="sy0">,</span> <span class="re0">$rows</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'message'</span> <span class="sy0">=&gt;</span> <span class="re0">$message</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> n\view\render<span class="br0">&#40;</span><span class="re0">$view</span> <span class="sy0">=</span> <span class="st_h">'error'</span><span class="sy0">,</span> <span class="re0">$markup</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="br0">&#125;</span>
			<span class="br0">&#125;</span>
		<span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> <span class="re0">$valid_sig_processor</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'update'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st0">&quot;We've updated the host.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> <span class="re0">$valid_sig_processor</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'insert'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st0">&quot;We've inserted the host.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_valid'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> <span class="re0">$valid_sig_processor</span><span class="br0">&#40;</span><span class="re0">$signatures</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re0">$args</span><span class="br0">&#91;</span><span class="st_h">'delete'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st0">&quot;We've deleted the host.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> <span class="st_h">''</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
    <span class="br0">&#125;</span></pre></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=210</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nephtali debugging features now documented</title>
		<link>http://blog.nephtaliproject.com/?p=205</link>
		<comments>http://blog.nephtaliproject.com/?p=205#comments</comments>
		<pubDate>Sat, 21 May 2011 02:42:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Nephtali Website]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=205</guid>
		<description><![CDATA[Although they&#8217;ve been around for a long time, I&#8217;ve done a poor job of documenting the debugging capabilities built in to Nephtali. Although very basic, the debugging features have helped me on many occasions, speeding the process of bug squashing. &#8230; <a href="http://blog.nephtaliproject.com/?p=205">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Although they&#8217;ve been around for a long time, I&#8217;ve done a poor job of documenting the debugging capabilities built in to Nephtali. Although very basic, the debugging features have helped me on many occasions, speeding the process of bug squashing. I sincerely apologize for the delay in providing proper documentation.</p>
<p>With the formal apology now issued, let&#8217;s move on to the update: <a href="http://nephtaliproject.com/documentation/examples/debugging.php" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/examples/debugging.php?referer=');">I&#8217;ve now documented Nephtali&#8217;s debugging features in the examples section of the website</a>.</p>
<p>The primary debugging feature is the debug display, a special page that can be triggered by adding the Get variable &#8220;nmode=debug&#8221; to any url when Nephtali has been set to <a href="http://nephtaliproject.com/documentation/setup/#configure" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/setup/_configure?referer=');">&#8220;dev&#8221; mode in ncore.php</a>. The debug display shows the Get, Post, Cookie, and Session variables; the ports and their corresponding values and validity; and watched variables, variables that have been manually added to the debug display.</p>
<p>Again, the debugging features are very simple, but don&#8217;t let the simplicity lull you into avoiding them. Nephtali is not a large, complex framework. Many times the bugs you&#8217;ve run up against are easily spotted in the debugging display.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=205</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nephtali 3.2.3 adds ability to set config mode by page, improves Postgre support, and improves developer experience</title>
		<link>http://blog.nephtaliproject.com/?p=189</link>
		<comments>http://blog.nephtaliproject.com/?p=189#comments</comments>
		<pubDate>Fri, 22 Apr 2011 23:56:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[New Feature]]></category>
		<category><![CDATA[New Release]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=189</guid>
		<description><![CDATA[The most recent release of Nephtali (version 3.2.3) offers some simple enhancements, bug fixes, and improved documentation. Page-by-page config mode You can now easily change the configuration mode used for a page without having to change the whole site. For &#8230; <a href="http://blog.nephtaliproject.com/?p=189">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The most recent release of <a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">Nephtali (version 3.2.3)</a> offers some simple enhancements, bug fixes, and improved documentation.</p>
<h2>Page-by-page config mode</h2>
<p>You can now easily change the configuration mode used for a page without having to change the whole site. For instance, if you&#8217;d like to put one page in &#8216;dev&#8217; mode and keep the rest of the site in &#8216;prod&#8217; mode, you&#8217;d just add the following snippet of PHP to the top of your markup file:</p>
<div id="wpshdo_9" class="wp-synhighlighter-outer"><div id="wpshdt_9" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_9"></a><a id="wpshat_9" class="wp-synhighlighter-title" href="#codesyntax_9"  onClick="javascript:wpsh_toggleBlock(9)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_9" onClick="javascript:wpsh_code(9)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_9" onClick="javascript:wpsh_print(9)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_9" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span> <span class="re0">$nephtali_config_mode</span> <span class="sy0">=</span> <span class="st_h">'dev'</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
&lt;!DOCTYPE html&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;</pre></div></div>
<p><a href="http://nephtaliproject.com/documentation/setup/#configure" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/setup/_configure?referer=');">To avoid potential security issues</a>, you must specifically  enable this feature by opening nconfig.php and adding a fifth argument to n\config\save():</p>
<div id="wpshdo_10" class="wp-synhighlighter-outer"><div id="wpshdt_10" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_10"></a><a id="wpshat_10" class="wp-synhighlighter-title" href="#codesyntax_10"  onClick="javascript:wpsh_toggleBlock(10)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_10" onClick="javascript:wpsh_code(10)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_10" onClick="javascript:wpsh_print(10)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.nephtaliproject.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_10" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;">n\config\save<span class="br0">&#40;</span>
<span class="re0">$mode</span> <span class="sy0">=</span> <span class="st_h">'dev'</span><span class="sy0">,</span>
<span class="re0">$dev</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
<span class="co1">// settings</span>
<span class="br0">&#41;</span><span class="sy0">,</span>
<span class="re0">$test</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
<span class="co1">// settings</span>
<span class="br0">&#41;</span><span class="sy0">,</span>
<span class="re0">$prod</span> <span class="sy0">=</span> <a href="http://www.php.net/array" onclick="pageTracker._trackPageview('/outgoing/www.php.net/array?referer=');"><span class="kw3">array</span></a><span class="br0">&#40;</span>
<span class="co1">// settings</span>
<span class="br0">&#41;</span><span class="sy0">,</span>
<span class="re0">$allow_page_overrides</span> <span class="sy0">=</span> <span class="kw4">TRUE</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<h2>Added support in n\sql\action\* functions for PostgresSQL lastInsertId</h2>
<p>PostgreSQL&#8217;s use of sequences requires the name of the sequence object in the <a href="http://php.net/manual/en/pdo.lastinsertid.php" onclick="pageTracker._trackPageview('/outgoing/php.net/manual/en/pdo.lastinsertid.php?referer=');">name parameter of PDO-&gt;lastInsertId() calls</a>. To accommodate this in Nephtali, an optional last_insert_id_name parameter has been added to the following functions within the n\sql\action namespace:</p>
<ul>
<li>query($query, array $inputs, $dbh = null, $last_insert_id_name = null)</li>
<li>insert($table_name, array $inputs, $dbh = null, $last_insert_id_name = null)</li>
<li>save($table_name, array $inputs, $dbh = null, $last_insert_id_name = null)</li>
</ul>
<h2>Viewing debug output vs. automatic error handling</h2>
<p>You can no longer control on a pipe-by-pipe basis whether an uncaught exception within a pipe function is automatically handled or not (you used to have to add &#8216;auto_error_handling&#8217; =&gt; false to the $opts array for a pipe.) Going forward, the mode for the current request determines whether uncaught exceptions are automatically handled (i.e., the required &#8216;error&#8217; view is shown) or the debug output is displayed. These changes are meant to simplify the development process and help Nephtali&#8217;s default configuration come inline with developers&#8217; expectations.</p>
<p>The settings for the modes are as follow:</p>
<ul>
<li><strong>dev</strong> &#8211; Show debug output.</li>
<li><strong>test</strong> &#8211; Automatically catch exceptions and display error view.</li>
<li><strong>prod</strong> &#8211; Automatically catch exceptions and display error view.</li>
</ul>
<h2>Improved feedback</h2>
<p>Nephtali now checks for typos in $opts array keys supplied to n\port\register() calls. This change avoids issues where a misspelled key silently has no impact on the port validation, a significant source of confusion for the developer who thought they had properly set up the port. The checks for typos only occur in &#8216;dev&#8217; mode (this helps keep &#8216;prod&#8217; mode fast as can be), and Nephtali will even recommend the associative key you meant to keep going by the closest valid spelling match.</p>
<p>Additionally, when one accidentally tries to change the value of an immutable n\val(), the error feedback has been improved.</p>
<h2>Bug fixes and improved documentation</h2>
<p>The n\arr\format() function has now been fixed so-as to properly return array values that don&#8217;t have any formatting functions applied to them. A big thanks goes out to <a href="http://blog.davingranroth.com/" onclick="pageTracker._trackPageview('/outgoing/blog.davingranroth.com/?referer=');">Davin Granroth for reporting the issue</a>.</p>
<p>Additionally, the documentation for several of Nephtali&#8217;s functions has improved significantly. Let me know if you see any issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=189</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nephtali vs CakePHP, Yii, Kohana, Symfony, and Zend PHP Frameworks</title>
		<link>http://blog.nephtaliproject.com/?p=166</link>
		<comments>http://blog.nephtaliproject.com/?p=166#comments</comments>
		<pubDate>Wed, 02 Feb 2011 07:06:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=166</guid>
		<description><![CDATA[Upon being asked if I knew of a writeup contrasting Nephtali with the Yii PHP framework, I realized I&#8217;d better get to work writing a post that fills the void. And, while contemplating the content, I realized I could include &#8230; <a href="http://blog.nephtaliproject.com/?p=166">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Upon being asked if I knew of a writeup contrasting <a href="http://nephtaliproject.com" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com?referer=');">Nephtali</a> with the<a href="http://www.yiiframework.com/" onclick="pageTracker._trackPageview('/outgoing/www.yiiframework.com/?referer=');"> Yii PHP framework</a>, I realized I&#8217;d better get to work writing a post that fills <a href="http://www.google.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=nephtali+vs+yii" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?sourceid=chrome_amp_ie=UTF-8_amp_q=nephtali+vs+yii&amp;referer=');">the void</a>. And, while contemplating the content, I realized I could include several other frameworks in the analysis, as Nephtali&#8217;s core design principles and architecture stand in stark contrast to popular conventions.</p>
<p>Let&#8217;s briefly contrast the <a href="http://cakephp.org/" onclick="pageTracker._trackPageview('/outgoing/cakephp.org/?referer=');">CakePHP</a>, <a href="http://www.yiiframework.com/" onclick="pageTracker._trackPageview('/outgoing/www.yiiframework.com/?referer=');">Yii</a>, <a href="http://kohanaframework.org/" onclick="pageTracker._trackPageview('/outgoing/kohanaframework.org/?referer=');">Kohana</a>, <a href="http://www.symfony-project.org/" onclick="pageTracker._trackPageview('/outgoing/www.symfony-project.org/?referer=');">Symfony</a>, and <a href="http://zendframework.com/" onclick="pageTracker._trackPageview('/outgoing/zendframework.com/?referer=');">Zend</a> PHP Frameworks with <a href="http://nephtaliproject.com" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com?referer=');">Nephtali</a>.</p>
<h2>Design Principles: Don&#8217;t hide complexity, strive for simplicity</h2>
<h3>Just enough <em>is</em> more</h3>
<p>Nephtali&#8217;s core API fits within one file and <a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">the current download is <strong>35 KB </strong>(smaller than many jpegs.)</a> The downloads for the frameworks we&#8217;re contrasting Nephtali with range from around <strong>one to 6.6 MB</strong>.  Now, to a degree, this difference in size does speak to the difference in power out-of-the-box for developers. However, Nephtali has very different goals and design principles than the other frameworks.</p>
<p>Throughout the development of Nephtali, the core components of the vast majority of web applications were carefully debated and prioritized. Only features deemed essential and/or especially error prone were included in the framework.</p>
<p>Nephtali is a framework you can learn to use in a weekend, and it will provide you with a simple, solid foundation for any web application.  In contrast, the other frameworks are very powerful PHP ecosystems that can cater to your every whim, and although you can gain competency for basic tasks over a weekend, you&#8217;ll likely need much more time to truly learn them.</p>
<p>Now, please don&#8217;t assume that I&#8217;m saying I don&#8217;t like the frameworks I&#8217;m contrasting Nephtali with because they&#8217;re too big. On the contrary, I rather like and frequently use several of them.  I tend to use Nephtali for my core needs, and then if I need some OAuth or SMTP capabilities, I&#8217;ll just leverage<a href="http://zendframework.com/apidoc/core/" onclick="pageTracker._trackPageview('/outgoing/zendframework.com/apidoc/core/?referer=');"> Zend Framework&#8217;s powerful API&#8217;s</a> for my particular need (yes, Nephtali plays nicely with your other framework friends.)</p>
<h3>Functionally inspired</h3>
<p>The frameworks contrasted with Nephtali in this article are all built using object-oriented programming principles. In contrast, Nephtali takes its cues from <a href="http://en.wikipedia.org/wiki/Functional_programming" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Functional_programming?referer=');">functional programming</a>.</p>
<p>Now, some of you may be thinking, &#8220;Hey, PHP isn&#8217;t a functional programming langauge.&#8221;  You&#8217;re right. However, some of the new capabilities included in PHP 5.3 (<a href="http://php.net/manual/en/functions.anonymous.php" onclick="pageTracker._trackPageview('/outgoing/php.net/manual/en/functions.anonymous.php?referer=');">anonymous functions</a>, <a href="http://php.net/manual/en/functions.anonymous.php" onclick="pageTracker._trackPageview('/outgoing/php.net/manual/en/functions.anonymous.php?referer=');">closures</a>, <a href="http://www.php.net/manual/en/language.namespaces.php" onclick="pageTracker._trackPageview('/outgoing/www.php.net/manual/en/language.namespaces.php?referer=');">namespaces</a>) provide just enough power for Nephtali&#8217;s novel approach. Specifically, Nephtali doesn&#8217;t contain any classes, tries to avoid mutable variables, and makes heavy use of anonymous functions.</p>
<p>Why the functional emphasis? In my experience, functional programming has proven to be easy to test, easy to debug, and it affords great parsimony (one of the main reasons Nephtali can do so much with so little code.)</p>
<h3>Security is not an add-on</h3>
<p>Security plays a significant role in every step of Nephtali&#8217;s design process. Specifically, the <a href="http://www.sans.org/top25-software-errors/" onclick="pageTracker._trackPageview('/outgoing/www.sans.org/top25-software-errors/?referer=');">SANS Top 25 list of the most dangerous software errors</a> served as a guide for general security issues that should be addressed in every web application, including:</p>
<ul>
<li><a href="http://cwe.mitre.org/top25/#CWE-79" onclick="pageTracker._trackPageview('/outgoing/cwe.mitre.org/top25/_CWE-79?referer=');">Failure to preserve web-page structure (e.g., XSS)</a><br />
Nephtali provides automatic, powerful output escaping, and this is paired with powerful, simple input validation.</li>
<li><a href="http://cwe.mitre.org/top25/#CWE-352" onclick="pageTracker._trackPageview('/outgoing/cwe.mitre.org/top25/_CWE-352?referer=');">Failure to preserve SQL structure (e.g., SQL injection)</a><br />
Nephtali makes prepared statements easy and more fun than an amusement park.</li>
<li><a href="http://cwe.mitre.org/top25/#CWE-209" onclick="pageTracker._trackPageview('/outgoing/cwe.mitre.org/top25/_CWE-209?referer=');">Information exposure through error messages</a><br />
Nephtali makes appropriate error displays for production pages a requirement.</li>
<li><a href="http://cwe.mitre.org/data/definitions/434.html" onclick="pageTracker._trackPageview('/outgoing/cwe.mitre.org/data/definitions/434.html?referer=');">Unrestricted upload of file with dangerous type</a><br />
Nephtali&#8217;s input validation includes checks for file names and size.</li>
<li><a href="http://cwe.mitre.org/top25/#CWE-311" onclick="pageTracker._trackPageview('/outgoing/cwe.mitre.org/top25/_CWE-311?referer=');">Missing encryption of sensitive data<br />
</a>Nephtali includes simple encryption functions.</li>
</ul>
<p>Now, is it fair to say that this emphasis on security stands in stark contrast to the other frameworks in this post? No. However, as Bruce Schneier has noted, &#8220;<a href="http://www.schneier.com/crypto-gram-0003.html#8" onclick="pageTracker._trackPageview('/outgoing/www.schneier.com/crypto-gram-0003.html_8?referer=');">…complexity is the worst enemy of security</a>&#8221; and it is fair to say that Nephtali has embraced simplicity to a degree that surpasses the other frameworks.</p>
<h2>Architecture: Not a typical PHP MVC</h2>
<h3>Dynamic region controllers (pipes)</h3>
<p>All of the other frameworks listed here are standard MVC-architectured applications. In terms of the controller, you either find a front controller (controls which view is displayed application-wide) or a page controller (controls which view is displayed for a particular page.)</p>
<p>Nephtali ushers in a new level of granularity with it&#8217;s controllers. Instead of a front or page controller, Nephtali provides controllers that manage views within dynamic content regions of pages (pipes.)  Essentially, a pipe is a controller that determines which view of the dynamic region to display and then handles any required databinding. A page can contain multiple pipes that all act independently on the page.</p>
<h3>No ORM</h3>
<p>The other PHP frameworks offer powerful Object Relational Mappers (ORMs) that abstract away much of the work of persisting objects in databases. However, as already noted, Nephtali borrows significantly from functional programming, so you&#8217;ll see no ORM (although you could use a third party library.)</p>
<p>PHP offers a fantastic data-access abstraction layer, PDO, and Nephtali merely provides some convenient wrapper functions for PDO&#8217;s API. The result is simple, fast, clean code that can easily be refactored as your project grows. Need to work with multiple databases? No problem. Need to optimize your complex queries? No problem.</p>
<h3>PHP-free markup</h3>
<p>The convention in the cother PHP frameworks is to embed PHP directly within the markup of the pages to display the dynamic output. In contrast, Nephtali cleanly separates PHP from your HTML.  If you have a page that contains a dynamic region (e.g., a list of recent blog titles), you merely embed xml comments within your markup to let Nephtali know where the region is.  All of your PHP is contained within a code-behind file.</p>
<p>Nephtali&#8217;s approach provides several benefits. Designers, front-end developers, and UX professionals can easily manage the markup and directory structure, and prototypes can easily flow into working websites. Output escaping is automatically handled, and for speed, the context of the escaping can be explicitly declared (e.g., html, attribute, uri.) Nephtali can be installed on existing sites without breaking legacy PHP code.</p>
<h2>Closing thoughts</h2>
<p>Nephtali is not for everyone. If you&#8217;re an object oriented programmer at heart, then you won&#8217;t be satisfied working with Nephtali. If you&#8217;re looking for an extensive web framework with an API that covers a veritable treasure trove of powerful PHP code that can do everything from creating PDF&#8217;s to generating <a href="http://www.figlet.org/" onclick="pageTracker._trackPageview('/outgoing/www.figlet.org/?referer=');">figlets</a>, then Nephtali will come up short. If you&#8217;re looking for a well-backed, popular web framework, then Nephtali will appear to be the odd-one-out.</p>
<p>However, if you&#8217;re looking for a simple, powerful tool that helps you get the core features of your web applications right, then maybe Nephtali is just the web framework for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=166</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A very primitive PHP docblock parser</title>
		<link>http://blog.nephtaliproject.com/?p=156</link>
		<comments>http://blog.nephtaliproject.com/?p=156#comments</comments>
		<pubDate>Fri, 14 Jan 2011 22:44:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Nephtali Website]]></category>
		<category><![CDATA[New Feature]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=156</guid>
		<description><![CDATA[Well, as I mentioned in a previous post, I&#8217;d pined for a PHP 5.3 documentation generator that could handle Nephtali&#8217;s core API long enough, so I recently cobbled a very, very primitive PHP docblock parser that does the job.  There&#8217;s no &#8230; <a href="http://blog.nephtaliproject.com/?p=156">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Well, as I mentioned in a previous post, <a href="http://blog.nephtaliproject.com/?p=151">I&#8217;d pined for a PHP 5.3 documentation generator that could handle Nephtali&#8217;s core API long enough</a>, so I recently cobbled a very, very primitive PHP docblock parser that does the job.  There&#8217;s no formal markup generator. I&#8217;m just using Nephtali to generate a rudimentary display of the documentation.</p>
<p>The parser is currently being used to generate<a href="http://nephtaliproject.com/documentation/api/" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/api/?referer=');"> Nephtali&#8217;s API documentation</a>, and so far it appears acceptable.  Now, upfront, let me assert the following:</p>
<ol>
<li>I&#8217;m not a great (or even average) parser writer.  Some might even label my skills poor or non-existant.</li>
<li>Nephtali&#8217;s core API only makes use of namespaced contants and functions, so I didn&#8217;t have to add handling for classes (although I did carve out some space for their future implementation.)  For instance, it&#8217;s so specialized now that the only namespaces it recognizes are block namespaces (as is used in ncore.php.)</li>
<li>I did this in a few days after being fed up, not after careful deliberation throughout a well conceived design process.</li>
</ol>
<p>You just hand the nlib\doc_generator\start_parsing() some string code and a nlib\doc_generator\DocNode object, and the object will be filled up with the available namespaces. Each namespace will contain its corresponding constant and function objects.  Each function will posess a nlib\doc_generator\Doc object, which contains all of the appropriate doc block properties.  Again, very, very primitive.</p>
<p>Currently, the parser and dev tools are included with<a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');"> the Nephtali download</a> in the nlib/doc_generator directory, although I&#8217;ll eventually pull this out into its own project.</p>
<p>So, if any of you have feedback, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=156</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nephtali 3.2.2 brings better documentation</title>
		<link>http://blog.nephtaliproject.com/?p=154</link>
		<comments>http://blog.nephtaliproject.com/?p=154#comments</comments>
		<pubDate>Fri, 14 Jan 2011 05:38:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[New Release]]></category>

		<guid isPermaLink="false">http://blog.nephtaliproject.com/?p=154</guid>
		<description><![CDATA[There&#8217;s a new release of Nephtali (3.2.2), and the emphasis on the release and the website of late has been on improving documentation.  Although there is still a long way to go, Nephtali is much better documented than it has &#8230; <a href="http://blog.nephtaliproject.com/?p=154">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s <a href="http://code.google.com/p/nephtali/downloads/list" onclick="pageTracker._trackPageview('/outgoing/code.google.com/p/nephtali/downloads/list?referer=');">a new release of Nephtali (3.2.2)</a>, and the emphasis on the release and the website of late has been on improving documentation.  Although there is still a long way to go, Nephtali is <a href="http://nephtaliproject.com/documentation/" onclick="pageTracker._trackPageview('/outgoing/nephtaliproject.com/documentation/?referer=');">much better documented than it has ever been</a>.  This is due to work on the docblocks in this release, and the development of the parser mentioned in the previous post.</p>
<p>There are other edits, including a couple bugs and the change from constants to strings for triggering the appropriate mode for databinding (&#8220;placeholder&#8221; or &#8220;form&#8221;.)</p>
<p>Additionally, you&#8217;ll see that theres a doc_generator directory in nlib that includes the parser used to generate the object model for the Nephtali API documentation.  This will likely be split off into a separate project in the future, but for now, we&#8217;ll just keep it with core Nephtali.</p>
<p>Please post any issues you find.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nephtaliproject.com/?feed=rss2&#038;p=154</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: basic
Database Caching using disk: basic
Object Caching 1107/1235 objects using disk: basic

Served from: blog.nephtaliproject.com @ 2012-05-19 14:50:30 -->
