<?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>Aviblock.com &#187; Expression Engine</title>
	<atom:link href="http://www.aviblock.com/blog/tag/expression-engine/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aviblock.com/blog</link>
	<description>My musings on web development</description>
	<lastBuildDate>Thu, 03 Jun 2010 13:40:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fixing PATH_INFO on bluehost and other shared hosts</title>
		<link>http://www.aviblock.com/blog/2009/08/07/fixing-path_info-on-bluehost-and-other-shared-hosts/</link>
		<comments>http://www.aviblock.com/blog/2009/08/07/fixing-path_info-on-bluehost-and-other-shared-hosts/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 19:54:43 +0000</pubDate>
		<dc:creator>Avi</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cgi.fix_pathinfo]]></category>
		<category><![CDATA[Expression Engine]]></category>
		<category><![CDATA[ORIG_PATH_INFO]]></category>
		<category><![CDATA[PATH_INFO]]></category>
		<category><![CDATA[php.ini]]></category>

		<guid isPermaLink="false">http://www.aviblock.com/blog/?p=66</guid>
		<description><![CDATA[The first time I setup an Expression Engine site on bluehost, and removed the index.php file via the .htaccess file, I ran into a problem where every template was redirecting back to the main index template. At the time, I traced this down to fact that the &#8220;segments&#8221; were not getting populated properly.
A brief search [...]]]></description>
			<content:encoded><![CDATA[<p>The first time I setup an Expression Engine site on bluehost, and removed the index.php file via the .htaccess file, I ran into a problem where every template was redirecting back to the main index template. At the time, I traced this down to fact that the &#8220;segments&#8221; were not getting populated properly.<br />
A brief search led to the EE wiki, which advocated swapping out PATH_INFO for ORIG_PATH_INFO. Although not being a fan of hacking core stuff, I was kind of cornered into this, so I went for it. This has been my running solution for the past two years.<br />
Recently, I ran into an issue where the $_SERVER['PHP_SELF'] was not returning anything after the file name. In other words, for http://mysite/foo.php/bar, PHP_SELF should be equal to foo.php/bar.<br />
I spoke with my host about it (a similar host to bluehost), and they said to put the following in the php.ini file: cgi.fix_pathinfo=Off<br />
After, I did this, PHP_SELF worked fine. Unfortunately, I ran into a similar situation like I described at the outset. Then it hit me&#8230;I changed ORIG_PATH_INFO back to PATH_INFO and&#8230;it worked!<br />
So now I listed this as another potential solution in the EE wiki.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aviblock.com/blog/2009/08/07/fixing-path_info-on-bluehost-and-other-shared-hosts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Templatizer</title>
		<link>http://www.aviblock.com/blog/2009/05/19/templatizer/</link>
		<comments>http://www.aviblock.com/blog/2009/05/19/templatizer/#comments</comments>
		<pubDate>Tue, 19 May 2009 14:07:04 +0000</pubDate>
		<dc:creator>Avi</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[Expression Engine]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.aviblock.com/blog/?p=51</guid>
		<description><![CDATA[I released an extension the other day for EE. You can find it here.
The basic idea is that creating templates in Expression Engine, especially if you don&#8217;t plan to edit them from the CP, can sometimes be a little repetitive and annoying.
Normally with EE, the templates are stored in the database, and you have the [...]]]></description>
			<content:encoded><![CDATA[<p>I released an extension the other day for EE. You can find it <a href="http://expressionengine.com/forums/viewthread/114771/">here</a>.</p>
<p>The basic idea is that creating templates in Expression Engine, especially if you don&#8217;t plan to edit them from the CP, can sometimes be a little repetitive and annoying.<br />
Normally with EE, the templates are stored in the database, and you have the option of <i>also</i> storing them on the filesystem. But in order for them to be recognized by EE, they must reside in the database at least.</p>
<p>Using this extension, you can start your template off as a physical file, and the first time you view it in the browser, it will automatically be recognized by EE and inserted into the database!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aviblock.com/blog/2009/05/19/templatizer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash Messenger for Expression Engine</title>
		<link>http://www.aviblock.com/blog/2009/05/07/flash-messenger-for-expression-engine/</link>
		<comments>http://www.aviblock.com/blog/2009/05/07/flash-messenger-for-expression-engine/#comments</comments>
		<pubDate>Thu, 07 May 2009 16:47:11 +0000</pubDate>
		<dc:creator>Avi</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[Expression Engine]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[Flash Message]]></category>
		<category><![CDATA[Flash Messenger]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[sessions]]></category>

		<guid isPermaLink="false">http://www.aviblock.com/blog/?p=42</guid>
		<description><![CDATA[A common idiom in web development is that a form is submitted via POST, and then a redirect is done to a success page. The reason for this is that if we left the result of the submission to return HTML to the browser, we would run into the infamous and confusing message "To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier." (At least the way firefox tells you). This has become none as the <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get">POST/REDIRECT/GET</a> pattern.

The problem becomes that, because of the stateless nature of HTTP, this second request has absolutely no connection to the previous request. If we just wanted to display a thank you page, or a success page, this would not be much of a problem. But what if we wanted to display the same form again, and display a success message on top when its submitted?

One way of doing this, which is the way Expression Engine does it, is to pass in a parameter in the query string, like ?success=1. The problem with this is that now if somebody refreshes the page, they'll see the same message. Not the biggest deal in the world, but can we do better?]]></description>
			<content:encoded><![CDATA[<p>A common idiom in web development is that a form is submitted via POST, and then a redirect is done to a success page. The reason for this is that if we left the result of the submission to return HTML to the browser, we would run into the infamous and confusing message &#8220;To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.&#8221; (At least the way firefox tells you). This has become none as the <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get">POST/REDIRECT/GET</a> pattern.</p>
<p>The problem becomes that, because of the stateless nature of HTTP, this second request has absolutely no connection to the previous request. If we just wanted to display a thank you page, or a success page, this would not be much of a problem. But what if we wanted to display the same form again, and display a success message on top when its submitted?</p>
<p>One way of doing this, which is the way Expression Engine does it, is to pass in a parameter in the query string, like ?success=1. The problem with this is that now if somebody refreshes the page, they&#8217;ll see the same message. Not the biggest deal in the world, but can we do better?<br />
<span id="more-42"></span><br />
The answer to all the statelessness of HTTP is with sessions. There is a pattern that takes advantage of this called a &#8220;<a href="http://blog.agilephp.com/2008/06/03/flash-messages/">flash message</a>&#8220;. The basic idea is to store a value in a session when the form is submitted, and to echo it back the first time the page is displayed again, after a succesful POST.</p>
<p>I wanted this functionality in some of my Expression Engine SAEF&#8217;s and other such forms. I also wanted a way to easily set up flash messages, within the form itself, so that I didn&#8217;t have to hack any  modules, or look for a hook. </p>
<p>Here is what the API looks like. I will pick on  solspaces {exp:user:edit} which I am using to create a edit profile form.</p>
<p>Image the following form:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h1&gt;My Profile&lt;/h1&gt;
{exp:user:edit}
&lt;label for=&quot;first_name&quot;&gt;First Name&lt;/label&gt;
&lt;input name=&quot;first_name&quot; type=&quot;text&quot; value=&quot;{first_name}&quot; /&gt;
&lt;label for=&quot;last_name&quot;&gt;Last Name&lt;/label&gt;
&lt;input name=&quot;last_name&quot; type=&quot;text&quot; value=&quot;{last_name}&quot; /&gt;
&lt;input type=&quot;submit&quot; /&gt;
{/exp:user:edit}</pre></div></div>

<p>This creates a basic profile form where the user can change his first and last name (assuming these custom member variables were set up). If we submit this form, it will return right to were it came from, with no indication as to that anything happened.</p>
<p>So we will change it like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;h1&gt;My Profile&lt;/h1&gt;
{flash_msg}
{exp:user:edit}
{exp:flash_msg msg=&quot;Profile edited succesfully!&quot;}
&lt;label for=&quot;first_name&quot;&gt;First Name&lt;/label&gt;
&lt;input name=&quot;first_name&quot; type=&quot;text&quot; value=&quot;{first_name}&quot; /&gt;
&nbsp;
&lt;label for=&quot;last_name&quot;&gt;Last Name&lt;/label&gt;
&lt;input name=&quot;last_name&quot; type=&quot;text&quot; value=&quot;{last_name}&quot; /&gt;
&lt;input type=&quot;submit&quot; /&gt;
{/exp:user:edit}</pre></div></div>

<p>Now when we submit the form, we are greeted with the message &#8220;Profile edited succesfully!&#8221;. Refresh the page, and its gone!</p>
<p>And now for the exciting technical part! How is this magic done?</p>
<p>First the general overview: The plugin creates a hidden form element who&#8217;s value is a random hash. At the same time this element is created, a session variable is created with this hash and the message, as well as a flag. There is a extension on the session_end hook which looks for the presence of this form element, and the session variable. If the two hashes are the same, the flag in the session variable is set, and the plugin knows it can display the session variable.</p>
<p>Here is the extension:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> sessions_end<span style="color: #009900;">&#40;</span><span style="color: #000088;">$SESS</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">global</span> <span style="color: #000088;">$IN</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>REQ <span style="color: #339933;">==</span> <span style="color: #0000ff;">'ACTION'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$IN</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">GBL</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flash-hash'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash-hash'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'done'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I think that code is pretty self explanatory (or at least I explained it earlier).</p>
<p>Now the plugin:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> Flash_msg<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">global</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">,</span> <span style="color: #000088;">$FNS</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$FNS</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">random</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'encrypt'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'done'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">swap_var_single</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'msg'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">swap_var_single</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span>  <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'done'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;flash-hash&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$hash</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;msg&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch_param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'msg'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">return_data</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&lt;input name=&quot;</span>flash<span style="color: #339933;">-</span>hash<span style="color: #0000ff;">&quot; type=&quot;</span>hidden<span style="color: #0000ff;">&quot; value=&quot;</span><span style="color: #000088;">$hash</span><span style="color: #0000ff;">&quot; /&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Pretty straight forward, I think. The only interesting thing here is the line:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">swap_var_single</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #000088;">$TMPL</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This takes advantage of some bad OOP design on Expression Engine&#8217;s part, so that my plugin can make changes, like variable substitution, anywhere in the template!</p>
<p>There&#8217;s one problem with all of this though. What if we set one of the fields in that form to required, and left it out? We would see the output of the Expression Engine&#8217;s error page, and when we went back, the flash message would appear! We need a way at to determine if the form was successful or not. Unfortunately, a successful submit is merely a semantic thing. Its up to the programmer to determine if was successful or not. I though about this problem for a long time, and then came up with an ingenious, almost hackish solution. If only there was a hook in the Output::show_user_error() method!</p>
<p>In absence of that I thought, why don&#8217;t I just subclass the Output class, and overwrite that method, and then replace the global $OUT variable with new version!</p>
<p>As simple as this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MyOutput <span style="color: #000000; font-weight: bold;">extends</span> Output <span style="color: #009900;">&#123;</span>
	 <span style="color: #000000; font-weight: bold;">function</span> show_user_error<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'submission'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span><span style="color: #339933;">,</span> <span style="color: #000088;">$heading</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'done'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">show_user_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errors</span><span style="color: #339933;">,</span> <span style="color: #000088;">$heading</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This just simply overwrites the show_user_error method, resets the flag, and shores off back to its parent to do the rest!</p>
<p>I simply include this little class at the bottom of the extension and then we rewrite our extension method as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> sessions_end<span style="color: #009900;">&#40;</span><span style="color: #000088;">$SESS</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">global</span> <span style="color: #000088;">$IN</span><span style="color: #339933;">,</span> <span style="color: #000088;">$OUT</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>REQ <span style="color: #339933;">==</span> <span style="color: #0000ff;">'ACTION'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$hash</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$IN</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">GBL</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flash-hash'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$OUT</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyOutput<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash-hash'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$hash</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'flash_msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'done'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>All I&#8217;m doing now is replacing the global $OUT variable with my own subclassed Output class!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aviblock.com/blog/2009/05/07/flash-messenger-for-expression-engine/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Presenting a list of Timezones to the user</title>
		<link>http://www.aviblock.com/blog/2009/03/12/presenting-a-list-of-timezones-to-the-user/</link>
		<comments>http://www.aviblock.com/blog/2009/03/12/presenting-a-list-of-timezones-to-the-user/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 20:41:18 +0000</pubDate>
		<dc:creator>Avi</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Expression Engine]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[timezones]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://ablock.webfactional.com/blog/?p=3</guid>
		<description><![CDATA[ 
I first got into timezones when I working on an calendar app which displayed various times of day which are pertinent to Jewish daily life. The app would display calculated times which of course would differ based on the timezone of the given location. As I investigated into timezones, I found them to be fairly [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>I first got into timezones when I working on an <a title="OU Calendar Application" href="http://www.ou.org/holidays/calendar" target="_blank">calendar app</a> which displayed various times of day which are pertinent to Jewish daily life. The app would display calculated times which of course would differ based on the timezone of the given location. As I investigated into timezones, I found them to be fairly complicated. Not all timezones are even on the hour&#8230;some are at 30 minute offsets, some at 45 minutes, and historically there have been even stranger offsets than that.</p>
<p>To make matters worse, there&#8217;s the whole issue of Daylight Saving Time. Apparently some places have it some don&#8217;t. Some countries have a set date for DST, some pick a new one each year depending on circumstances. And of course, DST does not mean only adding one hour. <br />
<span id="more-3"></span><br />
My research led me to what is &#8220;colloquially&#8221; known as the <a title="Olson Database" href="http://www.twinsun.com/tz/tz-link.htm" target="_blank">&#8220;Olson&#8221; database</a>. The Olson database is a <a href="http://article.gmane.org/gmane.comp.time.tz/2496" target="_blank">de facto standard</a> in the world of keeping time. The most recognizable part of the way timezones are identified is the {Continent}/{Location} signature. For example, the timezone that I am in is called &#8220;America/New_York&#8221;. The Olson database tracks all historical information about timezones back at least until 1970. By timezone information, this also means transitions for DST and the GMT offset for both standard time and DST.</p>
<p>The best part of all of this, is that PHP 5 and up has <a title="PHP Support's Timezones" href="http://www.php.net/timezones " target="_blank">built in support</a> for understanding Olson timezones. This means that you all you need is the timezone id (the tzid), and you can have PHP worry about all the timezone and DST calculations.</p>
<p>Recently, I was working on another app which required members to select a timezone. The app is written on top of <a title="Expression Engine" href="http://www.expressionengine.com" target="_blank">Expression Engine</a> which contains a full blown membership system. The membership system includes a timezone setting. Let&#8217;s take a quick look at the what this look like:</p>
<div id="attachment_9" class="wp-caption alignnone" style="width: 1034px"><img class="size-large wp-image-9" title="Screenshot of timezone selection from Expression Engine" src="http://ablock.webfactional.com/blog/wp-content/uploads/2009/03/ss121-1024x350.png" alt="Selecting a timezone in Expression Engine" width="1024" height="350" /><p class="wp-caption-text">Selecting a timezone in Expression Engine</p></div>
<p>Notice the checkbox that says &#8220;Daylight Saving Time&#8221;? This means that the user has to remember, every year, to select that checkbox when DST happens. Not very fun. Expression Engine is written in PHP 4, and the authors <a title="Expression Engine to stay supporting PHP4" href="http://expressionengine.com/blog/entry/i_see_dead_server_side_scripting_languages/" target="_blank">intend to keep that</a>, stubbornly, for as long as possible.</p>
<p>I&#8217;m not here to wrant on Expression Engine (that&#8217;s for another time), but either way, this would not suit my purposes. I can&#8217;t rely on users remembering to &#8220;spring forward&#8221; when they have to.</p>
<p>The alternative is to provide a list based on the Olson database. The problem is that, as of this post, their are 560 tzid&#8217;s in the database, and they are not &#8220;friendly&#8221; nor recognizable to anybody but geeks. </p>
<p>I started looking around on the Interwebs trying to see what other people came up with. There was a <a href="http://stackoverflow.com/questions/119672/how-would-you-organize-a-timezone-dropdown" target="_blank">question</a> on <a title="stackoverflow.com" href="http://www.stackoverflow.com" target="_blank">Stackoverflow.com</a> which hit the nail on the head, but anybody answering the question missed the point completely.</p>
<p>Eventually I realized that I must present a list similar to Expression Engine&#8217;s list, but which has the values as Olson tzid&#8217;s. The first step was to clean up the list a little. Much of the information is redundant, and only there for historical purposes. For instance, until 2006, much of <a href="http://www.mccsc.edu/time.html" target="_blank">Indiana did not observe DST.</a> After 2006, however, the story changed. This explains why there are so many Olson tzid&#8217;s with Indiana in them. However, for all practical purposes, they&#8217;re the same.</p>
<p>The question is, what defines them as the same? I determined the best way would be to look at the DST transition date (if applicable), and the resulting offsets and compare them. Fortunately, PHP has a function that does this&#8230;<a href="http://us.php.net/manual/en/function.timezone-transitions-get.php" target="_blank">timezone_transitions_get()</a>.</p>
<p>My idea was to pull in all the timezones and their transistions into excel and sort them by offset, and transition dates to identify which tzids are similar. After that, to figure out a friendly name to call them.</p>
<p>Doing more research I found somebody made a <a title="spreadsheet for timezones" href="http://www.timdavis.com.au/data/olson-time-zone-database-to-standard-windows-time-zone-v01/ " target="_blank">spreadsheet</a> which tried to map Windows timezone names to Olson tzid&#8217;s. I used this a base reference for the names I chose, although I found not all the data in that spreadsheet was accurate (one day I will submit my changes to the author). Some timezones I had to come up with my own names like &#8220;America/Havana&#8221; which has different rules for any place in its timezone. I decided to call this (GMT-05:00) Cuba for lack of anything else.</p>
<p>In the end, I came up with a list of about 80 or so timezones, and I&#8217;m somewhat proud of my results:</p>
<p>Here is the list:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;option value=&quot;Pacific/Midway&quot;&gt;(GMT-11:00) Midway Island, Samoa&lt;/option&gt;
&lt;option value=&quot;America/Adak&quot;&gt;(GMT-10:00) Hawaii-Aleutian&lt;/option&gt;
&lt;option value=&quot;Etc/GMT+10&quot;&gt;(GMT-10:00) Hawaii&lt;/option&gt;
&lt;option value=&quot;Pacific/Marquesas&quot;&gt;(GMT-09:30) Marquesas Islands&lt;/option&gt;
&lt;option value=&quot;Pacific/Gambier&quot;&gt;(GMT-09:00) Gambier Islands&lt;/option&gt;
&lt;option value=&quot;America/Anchorage&quot;&gt;(GMT-09:00) Alaska&lt;/option&gt;
&lt;option value=&quot;America/Ensenada&quot;&gt;(GMT-08:00) Tijuana, Baja California&lt;/option&gt;
&lt;option value=&quot;Etc/GMT+8&quot;&gt;(GMT-08:00) Pitcairn Islands&lt;/option&gt;
&lt;option value=&quot;America/Los_Angeles&quot;&gt;(GMT-08:00) Pacific Time (US &amp; Canada)&lt;/option&gt;
&lt;option value=&quot;America/Denver&quot;&gt;(GMT-07:00) Mountain Time (US &amp; Canada)&lt;/option&gt;
&lt;option value=&quot;America/Chihuahua&quot;&gt;(GMT-07:00) Chihuahua, La Paz, Mazatlan&lt;/option&gt;
&lt;option value=&quot;America/Dawson_Creek&quot;&gt;(GMT-07:00) Arizona&lt;/option&gt;
&lt;option value=&quot;America/Belize&quot;&gt;(GMT-06:00) Saskatchewan, Central America&lt;/option&gt;
&lt;option value=&quot;America/Cancun&quot;&gt;(GMT-06:00) Guadalajara, Mexico City, Monterrey&lt;/option&gt;
&lt;option value=&quot;Chile/EasterIsland&quot;&gt;(GMT-06:00) Easter Island&lt;/option&gt;
&lt;option value=&quot;America/Chicago&quot;&gt;(GMT-06:00) Central Time (US &amp; Canada)&lt;/option&gt;
&lt;option value=&quot;America/New_York&quot;&gt;(GMT-05:00) Eastern Time (US &amp; Canada)&lt;/option&gt;
&lt;option value=&quot;America/Havana&quot;&gt;(GMT-05:00) Cuba&lt;/option&gt;
&lt;option value=&quot;America/Bogota&quot;&gt;(GMT-05:00) Bogota, Lima, Quito, Rio Branco&lt;/option&gt;
&lt;option value=&quot;America/Caracas&quot;&gt;(GMT-04:30) Caracas&lt;/option&gt;
&lt;option value=&quot;America/Santiago&quot;&gt;(GMT-04:00) Santiago&lt;/option&gt;
&lt;option value=&quot;America/La_Paz&quot;&gt;(GMT-04:00) La Paz&lt;/option&gt;
&lt;option value=&quot;Atlantic/Stanley&quot;&gt;(GMT-04:00) Faukland Islands&lt;/option&gt;
&lt;option value=&quot;America/Campo_Grande&quot;&gt;(GMT-04:00) Brazil&lt;/option&gt;
&lt;option value=&quot;America/Goose_Bay&quot;&gt;(GMT-04:00) Atlantic Time (Goose Bay)&lt;/option&gt;
&lt;option value=&quot;America/Glace_Bay&quot;&gt;(GMT-04:00) Atlantic Time (Canada)&lt;/option&gt;
&lt;option value=&quot;America/St_Johns&quot;&gt;(GMT-03:30) Newfoundland&lt;/option&gt;
&lt;option value=&quot;America/Araguaina&quot;&gt;(GMT-03:00) UTC-3&lt;/option&gt;
&lt;option value=&quot;America/Montevideo&quot;&gt;(GMT-03:00) Montevideo&lt;/option&gt;
&lt;option value=&quot;America/Miquelon&quot;&gt;(GMT-03:00) Miquelon, St. Pierre&lt;/option&gt;
&lt;option value=&quot;America/Godthab&quot;&gt;(GMT-03:00) Greenland&lt;/option&gt;
&lt;option value=&quot;America/Argentina/Buenos_Aires&quot;&gt;(GMT-03:00) Buenos Aires&lt;/option&gt;
&lt;option value=&quot;America/Sao_Paulo&quot;&gt;(GMT-03:00) Brasilia&lt;/option&gt;
&lt;option value=&quot;America/Noronha&quot;&gt;(GMT-02:00) Mid-Atlantic&lt;/option&gt;
&lt;option value=&quot;Atlantic/Cape_Verde&quot;&gt;(GMT-01:00) Cape Verde Is.&lt;/option&gt;
&lt;option value=&quot;Atlantic/Azores&quot;&gt;(GMT-01:00) Azores&lt;/option&gt;
&lt;option value=&quot;Europe/Belfast&quot;&gt;(GMT) Greenwich Mean Time : Belfast&lt;/option&gt;
&lt;option value=&quot;Europe/Dublin&quot;&gt;(GMT) Greenwich Mean Time : Dublin&lt;/option&gt;
&lt;option value=&quot;Europe/Lisbon&quot;&gt;(GMT) Greenwich Mean Time : Lisbon&lt;/option&gt;
&lt;option value=&quot;Europe/London&quot;&gt;(GMT) Greenwich Mean Time : London&lt;/option&gt;
&lt;option value=&quot;Africa/Abidjan&quot;&gt;(GMT) Monrovia, Reykjavik&lt;/option&gt;
&lt;option value=&quot;Europe/Amsterdam&quot;&gt;(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna&lt;/option&gt;
&lt;option value=&quot;Europe/Belgrade&quot;&gt;(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague&lt;/option&gt;
&lt;option value=&quot;Europe/Brussels&quot;&gt;(GMT+01:00) Brussels, Copenhagen, Madrid, Paris&lt;/option&gt;
&lt;option value=&quot;Africa/Algiers&quot;&gt;(GMT+01:00) West Central Africa&lt;/option&gt;
&lt;option value=&quot;Africa/Windhoek&quot;&gt;(GMT+01:00) Windhoek&lt;/option&gt;
&lt;option value=&quot;Asia/Beirut&quot;&gt;(GMT+02:00) Beirut&lt;/option&gt;
&lt;option value=&quot;Africa/Cairo&quot;&gt;(GMT+02:00) Cairo&lt;/option&gt;
&lt;option value=&quot;Asia/Gaza&quot;&gt;(GMT+02:00) Gaza&lt;/option&gt;
&lt;option value=&quot;Africa/Blantyre&quot;&gt;(GMT+02:00) Harare, Pretoria&lt;/option&gt;
&lt;option value=&quot;Asia/Jerusalem&quot;&gt;(GMT+02:00) Jerusalem&lt;/option&gt;
&lt;option value=&quot;Europe/Minsk&quot;&gt;(GMT+02:00) Minsk&lt;/option&gt;
&lt;option value=&quot;Asia/Damascus&quot;&gt;(GMT+02:00) Syria&lt;/option&gt;
&lt;option value=&quot;Europe/Moscow&quot;&gt;(GMT+03:00) Moscow, St. Petersburg, Volgograd&lt;/option&gt;
&lt;option value=&quot;Africa/Addis_Ababa&quot;&gt;(GMT+03:00) Nairobi&lt;/option&gt;
&lt;option value=&quot;Asia/Tehran&quot;&gt;(GMT+03:30) Tehran&lt;/option&gt;
&lt;option value=&quot;Asia/Dubai&quot;&gt;(GMT+04:00) Abu Dhabi, Muscat&lt;/option&gt;
&lt;option value=&quot;Asia/Yerevan&quot;&gt;(GMT+04:00) Yerevan&lt;/option&gt;
&lt;option value=&quot;Asia/Kabul&quot;&gt;(GMT+04:30) Kabul&lt;/option&gt;
&lt;option value=&quot;Asia/Yekaterinburg&quot;&gt;(GMT+05:00) Ekaterinburg&lt;/option&gt;
&lt;option value=&quot;Asia/Tashkent&quot;&gt;(GMT+05:00) Tashkent&lt;/option&gt;
&lt;option value=&quot;Asia/Kolkata&quot;&gt;(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi&lt;/option&gt;
&lt;option value=&quot;Asia/Katmandu&quot;&gt;(GMT+05:45) Kathmandu&lt;/option&gt;
&lt;option value=&quot;Asia/Dhaka&quot;&gt;(GMT+06:00) Astana, Dhaka&lt;/option&gt;
&lt;option value=&quot;Asia/Novosibirsk&quot;&gt;(GMT+06:00) Novosibirsk&lt;/option&gt;
&lt;option value=&quot;Asia/Rangoon&quot;&gt;(GMT+06:30) Yangon (Rangoon)&lt;/option&gt;
&lt;option value=&quot;Asia/Bangkok&quot;&gt;(GMT+07:00) Bangkok, Hanoi, Jakarta&lt;/option&gt;
&lt;option value=&quot;Asia/Krasnoyarsk&quot;&gt;(GMT+07:00) Krasnoyarsk&lt;/option&gt;
&lt;option value=&quot;Asia/Hong_Kong&quot;&gt;(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi&lt;/option&gt;
&lt;option value=&quot;Asia/Irkutsk&quot;&gt;(GMT+08:00) Irkutsk, Ulaan Bataar&lt;/option&gt;
&lt;option value=&quot;Australia/Perth&quot;&gt;(GMT+08:00) Perth&lt;/option&gt;
&lt;option value=&quot;Australia/Eucla&quot;&gt;(GMT+08:45) Eucla&lt;/option&gt;
&lt;option value=&quot;Asia/Tokyo&quot;&gt;(GMT+09:00) Osaka, Sapporo, Tokyo&lt;/option&gt;
&lt;option value=&quot;Asia/Seoul&quot;&gt;(GMT+09:00) Seoul&lt;/option&gt;
&lt;option value=&quot;Asia/Yakutsk&quot;&gt;(GMT+09:00) Yakutsk&lt;/option&gt;
&lt;option value=&quot;Australia/Adelaide&quot;&gt;(GMT+09:30) Adelaide&lt;/option&gt;
&lt;option value=&quot;Australia/Darwin&quot;&gt;(GMT+09:30) Darwin&lt;/option&gt;
&lt;option value=&quot;Australia/Brisbane&quot;&gt;(GMT+10:00) Brisbane&lt;/option&gt;
&lt;option value=&quot;Australia/Hobart&quot;&gt;(GMT+10:00) Hobart&lt;/option&gt;
&lt;option value=&quot;Asia/Vladivostok&quot;&gt;(GMT+10:00) Vladivostok&lt;/option&gt;
&lt;option value=&quot;Australia/Lord_Howe&quot;&gt;(GMT+10:30) Lord Howe Island&lt;/option&gt;
&lt;option value=&quot;Etc/GMT-11&quot;&gt;(GMT+11:00) Solomon Is., New Caledonia&lt;/option&gt;
&lt;option value=&quot;Asia/Magadan&quot;&gt;(GMT+11:00) Magadan&lt;/option&gt;
&lt;option value=&quot;Pacific/Norfolk&quot;&gt;(GMT+11:30) Norfolk Island&lt;/option&gt;
&lt;option value=&quot;Asia/Anadyr&quot;&gt;(GMT+12:00) Anadyr, Kamchatka&lt;/option&gt;
&lt;option value=&quot;Pacific/Auckland&quot;&gt;(GMT+12:00) Auckland, Wellington&lt;/option&gt;
&lt;option value=&quot;Etc/GMT-12&quot;&gt;(GMT+12:00) Fiji, Kamchatka, Marshall Is.&lt;/option&gt;
&lt;option value=&quot;Pacific/Chatham&quot;&gt;(GMT+12:45) Chatham Islands&lt;/option&gt;
&lt;option value=&quot;Pacific/Tongatapu&quot;&gt;(GMT+13:00) Nuku'alofa&lt;/option&gt;
&lt;option value=&quot;Pacific/Kiritimati&quot;&gt;(GMT+14:00) Kiritimati&lt;/option&gt;</pre></div></div>

<p>If anybody can offer any improvements to this or a different suggestion altogether, that would be great.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aviblock.com/blog/2009/03/12/presenting-a-list-of-timezones-to-the-user/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
