<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:admin="http://webns.net/mvcb/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:content="http://purl.org/rss/1.0/modules/content/">

    <channel>
    
    <title>Eli Van Zoeren: Blog</title>
    <link>http://elivz.com//blog/index/</link>
    <description></description>
    <dc:language>en</dc:language>
    <dc:rights>Copyright 2011 by Eli Van Zoeren</dc:rights>
    <dc:date>2011-06-28T08:20:09+00:00</dc:date>
    <admin:generatorAgent rdf:resource="http://expressionengine.com/" />
    

    <item>
      <title>Address fieldtype for Expression Engine</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fvz_address%2F&amp;seed_title=Address+fieldtype+for+Expression+Engine</link>
      <guid>http://elivz.com/blog/single/vz_address/</guid>
      <description><![CDATA[<p>While setting up the field groups for a new Expression Engine-based project (which I&#8217;m very excited to tell you about, just as soon as it&#8217;s ready!), I got to thinking: instead of creating a bunch of separate fields for an address&mdash;address, city, state, zip code, country&mdash;there should be a way to drop them all in as one field. A quick check of <a href="http://devot-ee.com">Devot-EE</a> didn&#8217;t turn up such a thing, so I threw one together this afternoon. VZ Address is a fieldtype for EE2 that combines the standard address fields you&#8217;ve probably set up many times into one unit. It even gives you a variety of ways to get the address data back out, and it works as a cell in a <a href="http://pixelandtonic.com/matrix">Matrix</a> field.</p>

<p><img src="http://elivz.com/images/uploads/vz_address.png" alt="VZ Address" title="The VZ Address settings page" width="578" height="180" class="img_wide" /></p>

<h4>Template Tages</h4>

<h5>Single Tags</h5>

<pre><code>{address_field [style="microformat|schema|rdfa|plain|inline"]}</code></pre>

<p>Will output the complete address, in a standard format. Use the <code>style</code> attribute to get code that supports one of the markup standards for parseable content (defaults to microformats) or to get the address with no html markup at all (plain or inline).</p>

<pre><code>
{address_field:street}
{address_field:street_2}
{address_field:city}
{address_field:region}
{address_field:postal_code}
{address_field:country [code="yes"]}
</code></pre>

<p>Output particular pieces of the address. If you use the parameter <code>code=&#8220;yes&#8221;</code> on the country tag, you will get the the international country code rather than the full country name.</p>

<pre><code>{address_field:map_url [source="google|yahoo|bing|mapquest"] [params=""]}</code></pre>

<p>Output a URL to the address on any one of a variety of mapping services. Specify which service you want to use with the source parameter (Google Maps is the default). Anything you put in the params parameter will be added to the end of the map URL, use it to specify zoom levels, map types, etc.</p>

<h4>Tag Pair</h4>

<pre><code>
{address_field}
    {street}
    {street_2}
    {city}, {region} {postal_code}
    {country}
{/address_field}
</code></pre>

<p>If you need more control over the output, use the tag pair to output each part of the address individually.</p>

<h4>Installation</h4>

<p><a href="https://github.com/elivz/vz_address.ee_addon/zipball/master">Download</a> and unzip the archive. Upload the <code>vz_address</code> folder to <code>/system/expressionengine/third_party/</code>.</p>

<h4><a href="https://github.com/elivz/vz_address.ee_addon">Visit the VZ Address repo on GitHub</a></h4>]]></description>
      <dc:subject>Expression Engine</dc:subject>
      <dc:date>2011-06-28T08:20:09+00:00</dc:date>
    </item>

    <item>
      <title>Bad Behavior spam&#45;blocking for Expression Engine 2</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fbad_behavior%2F&amp;seed_title=Bad+Behavior+spam%26%2345%3Bblocking+for+Expression+Engine+2</link>
      <guid>http://elivz.com/blog/single/bad_behavior/</guid>
      <description><![CDATA[<p>Way back in the dark ages (well, 2007), Paul Burdick wrote <a href="http://expressionengine.com/downloads/details/bad_behavior/">an extension</a> to use Bad Behavior spam blocking on an Expression Engine website. Since then, many things have happened&mdash;Expression Engine 2 was released, I got married and moved to Oregon&mdash;and many things have not&mdash;the apocalypse, an EE2 version of Bad Behavior. I decided it was high time to remedy that last item.</p>

<p>I have been using Low&#8217;s excellent <a href="http://loweblog.com/software/low-nospam/">NoSpam add-on</a> for years and still recommend it highly. However, it has it&#8217;s limitations. The biggest issue for me is that it does not block spam submissions to SAEF forms. Additionally, it doesn&#8217;t do its filtering until <em>after</em> the form is submitted, meaning that all that spam traffic is putting additional load on your poor server.</p>

<p><a href="http://bad-behavior.ioerror.us/">Bad Behavior</a> is an open-source script that has been around for a long time and is well-respected. It works differently than Akismet or other popular anti-spam scripts, in that it prevents spammers from accessing your website at all. The Bad Behavior script runs at the beginning of page load and checks a variety of data about the request to identify spammers. If it decides a particular request is suspicious, it immediately stops Expression Engine from processing the rest of the page and displays a simple error message. As a general rule, Bad Behavior attempts to never block legitimate users, even if that means the occasional spammer does get through. Therefore, you may want to run Low NoSpam or another comment-spam filter as a second line of defense.</p>

<p>Generally, you can just upload and activate the extension to be protected. There are settings you can tweak to fine-tune the way Bad Behavior works, but doing so is not necessary. Optionally, it will also check requests against <a href="http://www.projecthoneypot.org/services_overview.php">Project Honey Pot&#8217;s http:BL</a>, a blacklist of known spammers. To use that feature, you will need to sign up for an API key and enter it on the extension settings page.</p>

<p>The settings page also displays detailed logs for the past week (which is as long as Bad Behavior stores log data). This can be useful in resolving false-positives.</p>

<p><img src="http://elivz.com/images/uploads/vz_bad_behavior.png" alt="VZ Bad Behavior" title="The VZ Bad Behavior settings page" width="578" height="457" class="img_wide" /></p>

<h4>Installation</h4>

<p><a href="https://github.com/elivz/vz_bad_behavior.ee_addon/zipball/master">Download</a> and unzip the extension. Upload the &#8220;vz_bad_behavior&#8221; folder to your /system/expression_engine/third_party/ folder. Finally, enable the extension in your control panel. You can change some settings if you want, but there is usually no need to.</p>

<h4><a href="https://github.com/elivz/vz_bad_behavior.ee_addon">Visit the VZ Bad Behavior repo on GitHub</a></h4>

<p>P.S. If you appreciate the decrease in spam you see after installing this extension, don&#8217;t thank me. It only took me a couple hours to put this together. Thank Michael Hampton, the developer of the Bad Behavior library. Even better: <a href="http://bad-behavior.ioerror.us/donate/">make a donation to support its development</a>.
</p>]]></description>
      <dc:subject>Expression Engine</dc:subject>
      <dc:date>2011-06-08T22:56:03+00:00</dc:date>
    </item>

    <item>
      <title>High&#45;Performance WordPress with W3 Total Cache and Nginx</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fwordpress_with_w3tc_on_nginx%2F&amp;seed_title=High%26%2345%3BPerformance+WordPress+with+W3+Total+Cache+and+Nginx</link>
      <guid>http://elivz.com/blog/single/wordpress_with_w3tc_on_nginx/</guid>
      <description><![CDATA[<p>I recently set up <a href="http://elivz.net">a new server</a> to host website for my clients. I took the opportunity to re-think how I have been serving sites and optimize the whole software stack for better performance. Rather than the usual LAMP (Linux/Apache/MySQL/PHP) stack, I decided to go with LEMP, switching Apache out for <a href="http://wiki.nginx.org">Nginx</a>. Although most common PHP applications recommend Apache, they will actually run faster on Nginx. Usually all you just need to do is translate the .htaccess file rules into Nginx&#8217;s configuration file.</p>

<p>My first order of business once the new server was set up was to get WordPress running and to optimize its performance. The first few sites that would be going on the new hardware were using WordPress so although I will be going through a similar process for Expression Engine soon, WordPress was my test-case.</p>

<p>I always run the W3 Total Cache plugin with my WordPress installations. By storing copies of each rendered page to disk (as well as many other optimizations), W3TC dramatically decreases the load on the server under heavy traffic. This is particularly the case with the Nginx configuration I am about to show you, which lets most requests be handled by Nginx alone. Nginx was designed first and foremost as a <a href="http://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a>, so it serves static files almost instantly and with minimal processor or memory usage. There are a number of sample configurations around the web for running WordPress with W3TC on Nginx, but none of them quite did it for me. For one thing, they all rely heavily on <code>if</code> statements, <a href="http://wiki.nginx.org/IfIsEvil">which are evil</a>. So here is my take on it&hellip;.</p>

<h3>WordPress Settings</h3>

<p>First, you need to install <a href="http://wordpress.org/extend/plugins/w3-total-cache/">W3 Total Cache</a>. This will add a &#8220;Performance&#8221; section at the bottom of the left-hand menu in your control panel. W3 Total Cache has many, many options and I am not going to explain them all here. To begin with, though, select the checkboxes to enable &#8220;Page Cache&#8221;, &#8220;Minify&#8221;, &#8220;Object Cache&#8221;, and &#8220;Database Cache&#8221;. The Page Cache method should be set to &#8220;Disk Enhanced&#8221; and all the others to &#8220;Disk&#8221; or &#8220;Opcode&#8221; if available.</p>

<p>Next, go to the &#8220;Page Cache&#8221; details page from the Performance menu and check off &#8220;Cache home page&#8221;, &#8220;Cache feeds&#8221;, and &#8220;Cache 404 pages&#8221;. The other two options in that section will be overridden by our Nginx configuration, so it doesn&#8217;t really matter what they are set to. Next, go to the &#8220;Minify&#8221; details page and add all the CSS and Javascript files that are used in your theme. This process is a bit fiddly&mdash;the upcoming version of W3TC will make it much easier&mdash;but the options are fairly self-explanatory. All the other settings should be fine with their defaults. The &#8220;Browser Cache&#8221; section, although <em>very</em> important for Apache setups, will also be overridden by what we are about to so, so you can ignore it.</p>

<h3>Nginx Configuration</h3>

<p>The important part of this post! You need to add the following configuration to your <code>nginx.conf</code> file (or to a separate file in <code>/etc/nginx/sites-available/</code>, which is the recommended way of doing things). I am assuming you already have Nginx running with PHP-FPM. If not, there are plenty of tutorials available around the web, depending on your Linux distro.</p>

<script src="https://gist.github.com/878505.js"> </script>

<h4>Caveats:</h4>
<ul>
<li>I had to comment out the <code>PATH_INFO</code> line in my <code>fastcgi_params</code> in order for images urls in minified CSS files to be correct. Doing so doesn&#8217;t seem to have had any negative effects.</li>
<li>Some of this code would be better off in your main <code>http</code> block, rather than the <code>server</code> block. I have arranged it this way for simplicity and clarity. <a href="http://wiki.nginx.org/Pitfalls">Read more about how you <em>should</em> structure your configuration</a>.</li>
<li>I&#8217;m not an Nginx configuration expert, so there may be ways to improve this code. Please share anything you see and I will update the post.</li>
</ul>]]></description>
      <dc:subject>Programming</dc:subject>
      <dc:date>2011-03-14T08:24:50+00:00</dc:date>
    </item>

    <item>
      <title>jQuery plugin for two&#45;column lists without changing your markup</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fvzlistsplit%2F&amp;seed_title=jQuery+plugin+for+two%26%2345%3Bcolumn+lists+without+changing+your+markup</link>
      <guid>http://elivz.com/blog/single/vzlistsplit/</guid>
      <description><![CDATA[<p>This is a plugin that is very limited in scope, but quite useful in many circumstances. All it does is take a container element and split its child elements into two columns. In a perfect world we could just use CSS3&#8217;s <code>column-count</code> property to do this, but Opera and Internet Explorer (even the upcoming version 9) don&#8217;t support CSS columns. So here we are.</p>

<p><em>Caveats</em>: This plugin does not check the size of each child element and try to match the heights of the two columns. It simple puts half of the elements in one column and half in the other. This may sound limiting, but in fact it works surprisingly well in many cases. Think of a bullet list of product features, or of <a href="http://www.vsadc.com/people">company staff-members</a>. When all the items you are splitting are similar in size, or when there are enough of them that they can average each other out, this will be a good solution. Also, horizontal margins and padding on the child elements are not taken into account when calculating their width, so you will need to add that into the <code>gutter</code> value. I plan to fix this in a future version.</p>

<p>The actual columnization (like that?) is done using a little CSS trick I figured out. The items that should be in the first column get this styling: <code>float: left; clear: left; width: 50%;</code>. That stacks them down the left side of the containing block, while leaving room to the right for the right-hand column. Items in that second column get this styling: <code>display: block; width: 50%; margin-left: 50%;</code>, which pushes them over far enough to the right so they fit into the space we left before. Surprisingly, this simple CSS works in all browsers except Firefox &lt;3.5 when the elements to be put in columns are list-items. In that case, we inexplicably need to reset the left margin on the second column to 0.</p>

<p>In addition to simply setting this styling automatically, the plugin does some other calculations necessary to leave a gutter between the two columns and to resize the columns when the window is resized. Additionally, and optionally, the plugin will check for a native CSS implementation of columns and use that instead if it exists. If you use this feature, there are a several things to be aware of: First, the way CSS columns split up content is different than the way this plugin does it. Css columns will split elements between the two columns if necessary to maintain an even column length. Second, for the best possible user experience, you should set the CSS column styling in your stylesheet and use something like <a href="http://www.modernizr.com/">Modernizr</a> to only run the vzListSplit plugin when it is needed. That will prevent the <a href="http://en.wikipedia.org/wiki/Flash_of_unstyled_content">FOUC</a> before the Javascript code is run.</p>

<h3>Usage</h3>

<p>At its most basic, you can just run the plugin on the container element whose children should be put in columns.</p>

<pre><code>$('ul#features').vzListSplit();</code></pre>

<p>If you want more control over the results, you can use any of the following parameters.</p>

<ul>
<li><code>gutter</code>: The width of the gap between the columns. Can be specified in either pixels or a percentage. (Default <em>20px</em>)</li>
<li><code>width</code>: You can use this to manually set a total width for the columns. You might need this if the container is hidden on pageload (in which case jQuery will read its width as 0) or if you don&#8217;t want the columns to span the entire width of the containing element.</li>
<li><code>autosize</code>: When using a gap specified in pixels in normal mode or in percentages in <em>native</em> mode (see below), we need to recalculate some dimensions whenever the browser window is resized. If you know that the width of your container will not change when the browser is resized, or if you are having performance issues, you can set <code>autosize</code> to false to disable this feature. (<em>true</em>)</li>
<li><code>native</code>: When this is set to <code>true</code> the plugin will check for a native CSS columns implementation and use that when possible. Please see the note above about display differences when using this. (<em>false</em>)</li>
<li><code>children_selector</code>: You can use this to put only certain child elements into columns. Be aware, though, that mixing columnized elements with non-columnized elements be lead to unpredictable results. (<em>null</em> - all child elements)</li>
<li><code>split_class</code>: This classname will be set on the container element when the plugin runs. You could use this to style columns or to hide the container before the plugin is run. (<em>columns</em>)</li>
</ul>

<h3><a href="/files/listsplit/vzListSplit.js">Download the Script</a></h3>]]></description>
      <dc:subject>Programming</dc:subject>
      <dc:date>2011-01-31T09:46:48+00:00</dc:date>
    </item>

    <item>
      <title>VZ Members Fieldtype</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fvz_members%2F&amp;seed_title=VZ+Members+Fieldtype</link>
      <guid>http://elivz.com/blog/single/vz_members/</guid>
      <description><![CDATA[<p>VZ Members is my second fieldtype for Brandon Kelly&#8217;s <a href="http://brandon-kelly.com/fieldframe">FieldFrame</a> extension. I needed a way to select any number of site members to associate with an entry. In my case I am doing this to allow entry creators to set permissions on an entry-by-entry basis. You could also use it to link to the profiles of people mentioned in an article, or inside a Matrix field to create a list of events, each with a date, title, and the personnel who will be in attendance. If you find other creative ways to use VZ Members, please share them in the comments.</p>

<p><img src="http://elivz.com/images/uploads/vz_members_screenshot.jpg" alt="VZ Members fieldtype screenshot" width="330" height="96" /></p>

<p>The fieldtype displays either a dropdown list or a group of checkboxes containing the members in one or more member groups. The allowed member groups can be set on a per-field basis. For each field you can also choose whether the user can select only one member (from a drop-down list) or any number of members (checkboxes).</p>

<h4><a href="http://github.com/elivz/vz_members">Download VZ Members</a></h4>

<h4>Prerequisites</h4>

<p>You must have <a href="http://brandon-kelly.com/fieldframe">FieldFrame</a> (version 1.4+) installed to use VZ Members on EE 1.6+.</p>

<h4>Template Tags</h4>

<h5>Single Tags</h5>

<pre><code>{members_field}</code></pre>

<p>Will output a pipe-delimited list of member ids. You can also use the <code>separator</code> parameter to separate them with something other than a pipe. For instance <code>{members_field separator=', '}</code> would output something like: <code>1, 4, 5, 8</code>.</p>

<pre><code>{members_field:names}</code></pre>

<p>Will output a list of member screen names with a comma and space between each. You can also use the <code>separator</code> parameter to separate them with anything else. For instance <code>{members_field:names separator=' and '}</code> would output something like: <code>Bob Smith and Jane Doe and Jimmy Jones</code>.</p>

<pre><code>{members_field:is_allowed members="1|4" groups="3" current_member="yes"}</code></pre>

<p>Checks if the members selected in this entry are among the members or groups specified in the tag parameters. You can specify member ids and/or group ids and either one can be a pipe-delimited list. You can also use the <code>current_member=&#8220;yes&#8221;</code> parameter to check if the logged in member is among the selected members.</p>

<p>With EE 1.6, it can also be used as a tag pair, in which case the content between the tags will only be displayed if the selected members are among those specified in the tag. EE 2 does not, unfortunately, support that syntax so you must use the tag inside a conditional to get the same effect. For example, if you want to show a notice for every weblog entry where a super-admin was selected, use this code in EE 1.6: <code>{members_field:is_allowed groups="1"}Super!{/members_field:is_allowed}</code>. In EE 2, the equivalent would be: <code>&#123;if &#8220;{members_field:is_allowed groups="1"}&#8221;&#125;Super!&#123;/if&#125;</code>.</p>

<pre><code>{members_field:is_not_allowed members="1|4" groups="3" current_member="yes"}</code></pre>

<p>This is the exact opposite of <code>:is_allowed</code>. See above for options.</p>

<h5>Tag Pair</h5>

<pre><code>{members_field}{id} - {screen_name}{/members_field}</code></pre>

<p>If you need more control over the output, use the tag pair.</p>

<p><strong>Optional Parameters:</strong></p>

<p><code>orderby=&#8220;id|username|screen_name|group_id&#8221;</code> - The column to use in ordering the output. Default is <code>id</code>.</p>

<p><code>sort=&#8220;asc|desc&#8221;</code> - Which order to sort in. Default is <code>asc</code>.</p>

<p><code>backspace=&#8220;2&#8221;</code> - Remove the last <em>x</em> characters from the final iteration.</p>

<p><strong>Variables:</strong></p>

<p><code>id</code> - The id of the current member.</p>

<p><code>username</code> - The login name of the current member.</p>

<p><code>screen_name</code> - The screen name of the current member.</p>

<p><code>group_id</code> - The id of the group to which the current member belongs.</p>

<p><code>count</code> - The number of the current iteration.</p>

<p><code>total_results</code> - The total number of members selected.</p>

<p><code>switch=&#8220;odd|even&#8221;</code> - Switch between multiple values each time through the loop.</p>

<h4>Installation</h4>

<p>Download and unzip the extension. Upload the files, following the folder structure in the download. You simply need to enable the VZ Members fieldtype in FieldFrame&#8217;s extension settings to be ready to go.</p>

<h4>Version History</h4>

<ul>
<li><strong>Version 1.0.3</strong> Compatibility with Safecracker.</li>
<li><strong>Version 1.0.2</strong> Add <code>&#123;field_name:is_not_allowed&#125;</code> tag and <code>current_member</code> parameter.</li>
<li><strong>Version 1.0.1</strong> Fix for unselectable buttons in Internet Explorer.</li>
<li><strong>Version 1.0.0</strong> EE2 compatible! Also completely redesigned with lots of code cleanup and refactoring.</li>
<li><strong>Version 0.97</strong> Fixed a couple bugs in the HTML output.</li>
<li><strong>Version 0.96</strong> Added <code>:is_allowed</code> tag.</li>
<li><strong>Version 0.95</strong> Initial public release. <em>May be buggy! Use at your own risk!</em> If you do find any bugs, please report them on the <a href="http://github.com/elivz/vz_members/issues">GitHub Issues page</a>.</li>
</ul>

<p>&nbsp;</p>]]></description>
      <dc:subject>Expression Engine, Programming</dc:subject>
      <dc:date>2009-11-02T07:45:07+00:00</dc:date>
    </item>

    <item>
      <title>All New VZ Url fieldtype</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fnew_vz_url%2F&amp;seed_title=All+New+VZ+Url+fieldtype</link>
      <guid>http://elivz.com/blog/single/new_vz_url/</guid>
      <description><![CDATA[<p>This morning I pushed version 1.1 of my VZ Url fieldtype for <a href="http://brandon-kelly.com/fieldframe/">Brandon Kelly&#8217;s FieldFrame extension</a> up to GitHub. The code for this version completely rewritten to (hopefully!) eliminate some issues with ajax calls returning in the wrong order, leading to false negatives. While I was at it, I made the errors display in a pop-up box, allowing for more verbose errors without breaking the layout.</p>

<p><img src="http://elivz.com/images/uploads/vz_url_popup.jpg" alt="Pop-up error message" width="278" height="126" class="img_small" />There is also one significant new feature. Previously, if the entered url was redirected to another site (i.e. http://google.com, which redirects to http://www.google.com) it would be displayed as an error. Now, a more helpful message is show, with the option to update to the new url.</p>

<p><em><strong>Update:</strong> I have since updated VZ Url to version 2, which supports Expression Engine 1.6+ and 2.0+.</em></p>

<p>You can <a href="http://elivz.com/blog/single/vz_url_extension/">get the full details on VZ Url from my original post</a> or <a href="http://github.com/elivz/vz_url" title="Download VZ Url">download it from GitHub</a>.
</p>]]></description>
      <dc:subject>Expression Engine, Programming</dc:subject>
      <dc:date>2009-10-25T20:53:35+00:00</dc:date>
    </item>

    <item>
      <title>Securing your downloads with mod_xsendfile</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fmod_xsendfile%2F&amp;seed_title=Securing+your+downloads+with+mod_xsendfile</link>
      <guid>http://elivz.com/blog/single/mod_xsendfile/</guid>
      <description><![CDATA[<p>I know I haven&#8217;t been the best blogger lately (in part because I&#8217;ve been <a href="http://www.newmediacampaigns.com">blogging over at my new job</a>). So to help remedy that I am going to try posting more short tips and snippets. These are things I want to be able to refer back to myself, and that I think might be useful to other people.</p>

<h3>Why use mod_xsendfile?</h3>

<p>In many case you have files available through your webapp that should only be accessible to certain people. You don&#8217;t want to rely on security through obscurity (throwing them all in a public folder, but only showing the links to certain visitors). Although that will deter casual users from getting ahold of the forbidden files, once someone has the link they could post it anywhere and your security is blown. What you want to do is to squirrel the files away outside of your publicly-accessible folder and then give them out as needed once a user is validated by whatever authentication method you are using.</p>

<p>Apache&#8217;s <a href="http://tn123.ath.cx/mod_xsendfile/">mod_xsendfile module</a> (inspired by <a href="http://blog.lighttpd.net/articles/2006/07/02/x-sendfile">lighthttpd&#8217;s X-Sendfile</a>) is the tool for this job. By intercepting http requests with the &#8220;X-Sendfile&#8221; header and outputting the contents of a specified file, it both enables per-file authentication and is more efficient than processing the file contents through your server-side script and sending it to the browser that way. The file path you give to mod_xsendfile doesn&#8217;t need to be in the server&#8217;s public folder, so it is a very secure way to store sensitive files.</p>

<h3>Installing on Mac OS X</h3>

<p>(<em>Installing on any Apache server will be similar, but I use OS X for development, so that is what these instructions are based on.</em>)</p>

<h4>Prerequisites:</h4>
<ul>
<li>Xcode Developer Tools (which is can be installed from your OS X DVD)</li>
<li>Basic knowledge of the command line</li>
</ul>

<h4>Download the source</h4>

<p>Open up the Terminal and create a folder to hold the mod_xsendfile source files:</p>

<pre><code>mkdir ~/src
cd ~/src</code></pre>

<p>Now download the source and uncompress it:</p>

<pre><code>curl -O http://tn123.ath.cx/mod_xsendfile/mod_xsendfile-0.9.tar.gz
tar xzvf mod_xsendfile-0.9.tar.gz
cd mod_xsendfile-0.9</code></pre>

<p>Compile and install it:</p>

<pre><code>sudo apxs -cia mod_xsendfile.c</code></pre>

<p>You will have to enter your password and it will do its thing. Finally you need to enable the module. You can choose to do this globally in your httpd.conf file or for just a particular project in a .htaccess file. Either way, the syntax is the same:</p>

<pre><code># Enable mod_xsendfile
XSendFile On
# Allow sending files from above the requested uri
XSendFilePath /absolute/path/to/the/files/</code></pre>

<p>(<code>XSendFilePath</code> is only necessary if the files you want to serve using mod_xsendfile are outside of your public web root folder.)</p>

<p>Finally restart Apache by opening your System Preferences and in the Sharing pane unchecking and re-checking the &#8220;Web Sharing&#8221; option.</p>

<h3>Sending a file</h3>

<p>This part is easy. Just set the x_sendfile header with the path to the file you want to send. Make sure you check first if the current user is allowed to access the file! They will not see the xsendfile header or have any way of knowing where the file is actually stored.</p>

<h4>In PHP</h4>

<pre><code>header("X-Sendfile: $filePath");
header("Content-Disposition: attachment; file=$fileName");</code></pre>

<h4>In Ruby on Rails</h4>

<pre><code>response.headers['X-Sendfile'] = @file.path
response.headers['Content-Disposition'] = "attachment; filename=#{@file.file_name}"
render :nothing => true</code></pre>]]></description>
      <dc:subject>Programming</dc:subject>
      <dc:date>2009-10-20T07:21:49+00:00</dc:date>
    </item>

    <item>
      <title>VZ Url extension</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fvz_url_extension%2F&amp;seed_title=VZ+Url+extension</link>
      <guid>http://elivz.com/blog/single/vz_url_extension/</guid>
      <description><![CDATA[<p><a href="http://brandon-kelly.com/">Brandon Kelly</a> has done the <a href="http://expressionengine.com">Expression Engine</a> developer community a great service with the release yesterday of his <a href="http://wiki.github.com/brandonkelly/bk.fieldframe.ee_addon/">FieldFrame</a> extension. He has created a framework for the quick development of new fieldtypes (like the XHTML and drop-down types that come with EE). I couldn&#8217;t resist experimenting with FieldFrame, and&#8212;aside from a few areas that are not yet documented&#8212;it is as easy as promised.</p>

<p>I whipped up a Url fieldtype, somewhat similar to <a href="http://www.designchuchi.ch/index.php/blog/comments/url-field-extension-for-expressionengine/">Designchuchi&#8217;s URL Field Extension</a>, but with the addition of ajax validation. When the user leaves the url field, it will ping the url they entered and display an error message if it doesn&#8217;t find a valid webpage there. If the page has moved, it will also alert the user and offer to update to the new location.</p>

<p><img src="http://elivz.com/images/uploads/vz_url.jpg" alt="VZ Url screenshot" width="368" height="74" class="img_med" />Please note that VZ Url will not prevent the user from saving their weblog entry if if cannot validate the url&#8212;it just warns them. This is intentional, perhaps they are linking to a page they have not yet created, or the site they are linking to is currently down but they know the url is correct. I may add this functionality as an option later on.</p>

<h4>Prerequisites</h4>

<p>You must have the <em>FieldFrame</em> and <em>jQuery for the  Control Panel</em> extensions installed and enabled. Your server will also need to have the CURL library enabled for the link checking to work.</p>

<h4>Tag</h4>

<p>You will generally display the entered url in your templates just like you would any other text field: <code>{vz_url_field_name}</code>. You can also use the optional <code>redirect</code> parameter to immediately redirect visitors to the entered url. You should only use this if you <em>really</em> know what you&#8217;re doing&#8230;with great power, etc. The syntax for redirects is <code>{vz_url_field_name redirect="yes"}</code>.</p>

<h4>Installation</h4>

<p>Download and unzip the extension below. Upload the files, following the folder structure in the download. You will need to enable the VZ Url fieldtype in FieldFrame&#8217;s extension settings. Then you will need to go back to FieldFrame&#8217;s settings &amp; show the settings for VZ Url to set the error message that will be shown if the url is invalid.</p>

<p>That&#8217;s it! Now you can use the VZ Url field type anywhere you were previously using a plain text field. Switching from a Text Field to a VZ Url field (or vice-versa) will not affect your data.</p>

<h4>Version History</h4>

<ul>
<li><strong>Version 2.1.2</strong> Fixed a javascript error that was preventing multiple fields on the same page from validating at the same time.</li>
<li><strong>Version 2.1.0</strong> Added the option to only allow local URLs. Removed error message settings interface (edit the language file if you need to change the wording). Heads up: This will probably be the last new version for EE1, aside from bug fixes.</li>
<li><strong>Version 2.0.3</strong> Now compatible with <a href="http://expressionengine.com/downloads/details/safecracker/">SafeCracker</a>.</li>
<li><strong>Version 2.0.1</strong> Added <code>redirect</code> parameter that immediately redirects visitors to the  field&#8217;s url. The inspiration and most of the code for this feature came from <a href="http://www.brianlitzinger.com/">Brian Litzinger</a>.</li>
<li><strong>Version 2.0.0</strong> EE2 compatibility! Also, error messages are restyled, the &#8220;redirect&#8221; message can be edited, and most of the code was refactored.</li>
<li><strong>Version 1.1.7</strong> Changed handling of redirected url. They are now considered valid as-is, but with the pop-up prompt to update to the final url. Also fixed a bug in checking multiple VZ Url fields when editing an existing entry.</li>
<li><strong>Version 1.1.4</strong> Removed hard-coded url to a testing copy of proxy.php that I had mistakenly left in.</li>
<li><strong>Version 1.1.3</strong> No longer equates &#8220;no url&#8221; as &#8220;invalid url&#8221;.</li>
<li><strong>Version 1.1.2</strong> Compatible with PHP &lt; 5.2. Compatible with Multi-Site Manager installations. Slight styling fixes.</li>
<li><strong>Version 1.1.1</strong> Checks to make sure it&#8217;s even a valid url before trying to ping the remote server.</li>
<li><strong>Version 1.1</strong> Completely refactored code. Displays errors&#8212;inluding a new message for redirected urls&#8212;in a new, prettier, pop-up box. Hopefully also fixed all the bugs mentioned in the comments up to now. <a href="http://elivz.com/blog/single/new_vz_url/">Read more in my blog post</a>.</li>
<li><strong>Version 1.0.2</strong> Preparation for FieldFrame 1.2&#8212;thanks to Brandon Kelly!</li>
<li><strong>Version 1.0</strong> Now checks urls as you type, rather than waiting until you move to the next field. Also some aesthtic adjustments.</li>
<li><strong>Version 0.9.9</strong> Cleaned up the design, refactored the javascript, and added support for FF Matrix.</li>
<li><strong>Version 0.9.8</strong> Moved some code around to simplify things.</li>
<li><strong>Version 0.9.7</strong> Update to new API structure in FieldFrame 0.9.5; moved to GitHub.</li>
<li><strong>Version 0.9.6</strong> Minor update to take advantage of new features in FieldFrame 0.9.2.</li>
<li><strong>Version 0.9.5</strong> Initial public release. <em>May be buggy! Use at your own risk!</em> But please tell me if you do find any bugs and I will do my best to fix them.</li>
</ul>

<h4><a href="http://github.com/elivz/vz_url">Download VZ Url</a></h4>]]></description>
      <dc:subject>Expression Engine, Programming</dc:subject>
      <dc:date>2009-03-12T03:07:30+00:00</dc:date>
    </item>

    <item>
      <title>listFilter jQuery plugin</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Flistfilter_plugin%2F&amp;seed_title=listFilter+jQuery+plugin</link>
      <guid>http://elivz.com/blog/single/listfilter_plugin/</guid>
      <description><![CDATA[<p>A project I am working on needed a way to filter a long list of staff members. We needed to be able to filter by several different criteria, and several different interfaces (text search, dropdown lists). And it needed to happen in-place&mdash;no page reloads. Thus my listFilter <a href="http://jquery.com">jQuery</a> plugin was born.</p>

<p>listFilter allows you to automatically filter out items from a list on the fly, using any number of criteria and data items. You can <a href="/examples/listFilter/">look at the example</a> to see how it works.</p>

<h3>How to use</h3>

<p>First you need to inlude jQuery and the plugin script:</p>

<p><code>&lt;script src=&#8221;/scripts/jquery.min.js&#8221;&gt;&lt;/script&gt;<br />
&lt;script src=&#8221;/scripts/jquery.listfilter.js&#8221;&gt;&lt;/script&gt;</code></p>

<p>You will need to things in you page: a list to filter and a form containing the controls you will use to set the filter criteria. These controls can be text inputs, textboxes, or select boxes. The list can be an actual list&#8212;&lt;ul&gt; or &lt;ol&gt;&#8212;or it can be any other element containing a group of similar elements (for instance a &lt;table&gt;, which contains &lt;tr&gt; elements). The trick here is that each filter criteria needs to match up with a sub-element of the list items. So if your list item looks like this: <code>&lt;li&gt;&lt;h3 class=&#8220;name&#8221;&gt;Name&lt;/h3&gt; &lt;p&gt;Plumber&lt;/p&gt;&lt;/li&gt;</code>, you could have a criteria form that looks like this:</p>

<p><code>&lt;form id=&#8220;criteria&#8221;&gt;<br />
&nbsp;  &lt;label&gt;Name:&gt; &lt;input type=&#8220;text&#8221; id=&#8220;name_filter&#8221; /&gt;<br />
&nbsp;  &lt;label&gt;Job:&gt; &lt;input type=&#8220;text&#8221; id=&#8220;job_filter&#8221; /&gt;<br />
&lt;/form&gt;</code></p>

<p>You will notice that the <em>id</em> of each filter matches the <em>class</em> of an item in the list, with &#8220;_filter&#8221; added to the end. That is how the script knows what to filter.</p>

<p>Finally, you need to initialize the filtering with this line of code (either in the head of you document, or in an external script):</p>

<p><code>$(document).ready(function() {<br />
   $('#listToFilter').listFilter('#criteria');<br />
});</code></p>

<p>There are three optional settings that you can pass to the listFilter function as a second parameter. <em>listElement</em> lets you specify the child element of <code>#listToFilter</code> that represents an individual item (default is &#8220;li&#8221;). <em>transition</em> specifies the effect used to show and hide the list items&#8212;can be &#8220;toggle&#8221;, &#8220;slide&#8221;, or &#8220;fade&#8221; (default is &#8220;toggle&#8221;). Finally, <em>speed</em> specifies the speed at which the transition will take place (default is 500). So if you wanted to filter the rows of a table by sliding unneeded rows up slowly, you would use:</p>

<p><code>$(document).ready(function() {<br />
   $('#tableToFilter').listFilter('#criteria', {listElement: 'tr', transition: 'slide', speed: 2000});<br />
});</code></p>

<h3><a href="http://elivz.com/examples/listFilter/jquery.listfilter.js">Download the script</a></h3>

<p>Leave a comment if you have any questions or improvements. This plugin is loosely based on liveSearch by <a href="http://orderedlist.com/articles/live-search-with-quicksilver-style-for-jquery">John Nunemaker</a> as revised by <a href="http://ejohn.org/blog/jquery-livesearch/">John Resig</a>.
</p>]]></description>
      <dc:subject>Programming</dc:subject>
      <dc:date>2009-02-14T02:57:45+00:00</dc:date>
    </item>

    <item>
      <title>New Business Cards</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fnew_business_cards%2F&amp;seed_title=New+Business+Cards</link>
      <guid>http://elivz.com/blog/single/new_business_cards/</guid>
      <description><![CDATA[<p>I finally got around to having new business cards printed (actually, I got them about a month ago, but I am just getting around to writing about them). Last summer I gave up my old New Orleans-local phone number when I bought my iPhone and had been procrastinating on ordering cards with the new number.</p>

<p>Part of the reason for my procrastination was the need to decide how and where I wanted them printed: Should I spend more to get them letterpressed? Should I get them from one of the many super-cheap online printers? Could I do it locally and/or sustainably? In the end, I went with <a href="http://www.themandatepress.com/">The Mandate Press</a>, a low-cost letterpress shop out of Salt Lake City. They have a running deal on 250 <a href="http://yhst-28030640693459.stores.yahoo.net/suyoownde.html">custom business cards</a> for $95. With a discount coupon (do a search, the coupon codes are everywhere) and shipping, my total came to $93. The tradeoff for such a low price is not having any options for paper or ink color, and a two- to three-week wait for the cards.</p>

<p><img src="http://elivz.com/images/uploads/business_card.jpg" alt="Eli Van Zoeren's business card" class="img_wide" width="578" height="300" /></p>

<p>Overall, I am satisfied with my cards. <a href="http://www.crane.com/CraneLettra/">The paper</a> is good quality&#8212;thick and white with a nice texture. There is a noticeable impression around the letters, which is reason to pay extra for letterpress, right? The printing itself could be better, though. It looks like there wasn&#8217;t quite enough ink on the press, so the black band, in particular, isn&#8217;t actually black. It has the same white specks peeking through that you would expect in a newspaper. I guess for a third the price of anywhere else I have seen, I don&#8217;t expect perfection; and I would certainly consider ordering from Mandate again. But if you really need to impress people with the quality of your card you will probably need to look elsewhere (or use one of Mandate&#8217;s custom options, which I expect are more tightly controlled).
</p>]]></description>
      <dc:subject>Business, Graphic Design</dc:subject>
      <dc:date>2009-01-03T02:30:13+00:00</dc:date>
    </item>

    <item>
      <title>Roadblock extension</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Froadblock_extension%2F&amp;seed_title=Roadblock+extension</link>
      <guid>http://elivz.com/blog/single/roadblock_extension/</guid>
      <description><![CDATA[<p>This is my first (public) extension for <a href="http://expressionengine.com">Expression Engine</a>. A site I am working on for a client needed a way to display the Terms of Use every time a user logs in&#8230;and it needed to be on a by-computer basis, rather than a by-user basis, since more than one person will be using the same login credentials.</p>

<p>What Roadblock does is look every time someone logs in to see if they have been shown a message yet, and how long ago. If they have not yet seen the roadblock, or if it was over a specified length of time ago, the roadblock will be displayed (or, optionally, they will be sent to a url of your choosing). Although I built it for displaying the term of use, it would also be useful for displaying reminders or instructions. <strong>Please note:</strong> There is no checking to ensure that the user &#8220;agrees&#8221; to the message. If you need their access to the site to be conditional on accepting an agreement, you will have to look elsewhere.</p>

<h3>Installation</h3>

<p>Download the file <a href="http://elivz.com/files/ext.roadblock.zip">ext.roadblock.zip</a>. Inside the archive you will find two files: lang.roadblock.php goes in your language/english folder and ext.roadblock.php goes in the extensions folder. You can now enable it in the extensions section of your control panel.</p>

<h3>Settings</h3>

<p><em>Users should see the roadblock</em> The interval between displays of the roadblock for each user.</p>

<p><em>Track users by</em> We can either keep track of who has seen the roadblock by User ID or by Computer. The latter option uses cookies, meaning that if the same user logs on using two different computers (or browsers) they will be shown the roadblock twice.</p>

<p><em>Url to redirect to</em> By default, the roadblock message will be shown in your User Message template (as defined in the Specialty Templates section of the CP) with a link to this address at the bottom. Normally, this would be the home page of you website (which it is set to by default). Optionally, you can leave the remaining settings fields blank, in which case this address will be used as the roadblock itself. This option allows you to create a unique template for the roadblock message, or create additional functionality within it.</p>

<p><em>Title</em> &amp; <em>Text</em> This is the actual content of the roadblock message. Anything you put in the <em>Text</em> field will be run through EE&#8217;s Xhtml processor.</p>

<p><em>Link text</em> The link to continue on to the website.</p>

<p><em>Url to redirect to when the roadblock is not shown</em> If this field is filled in, the user will be routed directly to the specified url when the roadblock is not shown, bypassing the Expression Engine &#8220;you are logged in&#8221; confirmation message.</p>

<h3>Disclaimer</h3>

<p>Remember, this is my first real extension, and I have tested it on my own system but if it blows up you installation of Expression Engine I cannon be held responsible. <strong>Use at your own risk!</strong></p>

<p>If you have questions, find bugs, or otherwise need help, please see my post on the <a href="http://expressionengine.com/forums/viewthread/93878/">Expression Engine Forums</a>.
</p>]]></description>
      <dc:subject>Expression Engine, Web design</dc:subject>
      <dc:date>2008-10-15T01:04:34+00:00</dc:date>
    </item>

    <item>
      <title>Are people really convinced by this?</title>
      <link>http://elivz.com/feeder/?FeederAction=clicked&amp;feed=Blog+Feed&amp;seed=http%3A%2F%2Felivz.com%2Fblog%2Fsingle%2Fare_people_really_convinced_by_this%2F&amp;seed_title=Are+people+really+convinced+by+this%3F</link>
      <guid>http://elivz.com/blog/single/are_people_really_convinced_by_this/</guid>
      <description><![CDATA[<p>This election is getting <a href="http://www.johnmccain.com/Informing/Multimedia/Player.aspx?guid=848322d6-92fe-403e-9cc7-85b6b3ee4011" title="Celeb" TV ad">more</a> and <a href="http://online.wsj.com/article_email/SB121755336096303089-lMyQjAxMDI4MTA3MTUwNTEzWj.html" title="Too Fit to Be President?">more</a> <a href="http://www.johnmccain.com/Informing/Multimedia/Player.aspx?guid=779c7d13-7d76-47a5-a4cd-e928e8f1f1d6" title=""The One" TV ad">ridiculous</a>.
</p>]]></description>
      <dc:subject>Politics</dc:subject>
      <dc:date>2008-08-02T01:49:54+00:00</dc:date>
    </item>

    
    </channel>
</rss>