<?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>3RM Design Blog &#187; ExpressionEngine</title>
	<atom:link href="http://www.3roadsmedia.com/blog/category/expressionengine/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.3roadsmedia.com/blog</link>
	<description>Website Coding Tips &#38; Graphic Design Inspiration</description>
	<lastBuildDate>Thu, 02 Sep 2010 15:27:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multilevel dropdown category navigation in ExpressionEngine</title>
		<link>http://www.3roadsmedia.com/blog/multilevel-dropdown-category-navigation-in-expressionengine/</link>
		<comments>http://www.3roadsmedia.com/blog/multilevel-dropdown-category-navigation-in-expressionengine/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 21:54:50 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[ExpressionEngine]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.3roadsmedia.com/blog/?p=1099</guid>
		<description><![CDATA[If you&#8217;ve ever wanted to create dropdown, category-based navigation in your ExpressionEngine website, you&#8217;ve probably also wanted to punch a hole in your desk. It&#8217;s not easy. Or is it? In this tutorial, I&#8217;ll show you how. Requirements To follow along in this tutorial, you&#8217;ll need: An ExpressionEngine website running EE 1.6.x (I haven&#8217;t yet [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever wanted to create dropdown, category-based navigation in your ExpressionEngine website, you&#8217;ve probably also wanted to punch a hole in your desk. It&#8217;s not easy. Or is it? In this tutorial, I&#8217;ll show you how.<br />
<span id="more-1099"></span></p>
<h2>Requirements</h2>
<p>To follow along in this tutorial, you&#8217;ll need:</p>
<ul>
<li>An ExpressionEngine website running EE 1.6.x (I haven&#8217;t yet tested this in EE 2.0)</li>
<li>The Subcategories plugin</li>
<li>To use category URL titles in your links, <strong>not </strong>category IDs</li>
</ul>
<p>The Subcategories plugin is available for download on <a href="http://expressionengine.com/forums/viewthread/27220/">this thread</a> in the EE forums; however, since it&#8217;s not clear which version to grab, and since there was a minor bug in the code, I&#8217;ve made a corrected version available for direct download <a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2010/07/pi.subcategories.txt">right here</a>.</p>
<p>Grab the plugin, save it as <strong>pi.subcategories.php</strong>, and upload it to your <strong>system/plugins </strong>directory.</p>
<h2>Live Demo</h2>
<p>If you&#8217;re the visual type (like I am) you probably need to <a href="http://www.3roadsmedia.com/sandbox/index.php/site/">see the menus in action</a>. The demo is pulling from a live EE install on our web server. It may also help to <a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2010/07/ee_cat_structure.png">see a screenshot of the category heirarchy</a>.</p>
<h2>Template Structure</h2>
<p>Once you&#8217;ve uploaded the plugin file, you&#8217;ll need to create a few templates:</p>
<ol>
<li>embeds/navigation</li>
<li>embeds/subcategories</li>
<li>embeds/sub_subcategories</li>
<li>an additional embed for each additional level of subcategories (if you desire more)</li>
</ol>
<p>For the visuals, here is <a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2010/07/ee_template_page.png">a screenshot of my templates page</a>.</p>
<p>The <strong>embeds/navigation </strong>template controls your main, top-level navigation. Embedding this template as I have done is optional; you can also leave your main navigation code in your header template (or wherever it normally appears).</p>
<p>The <strong>embeds/subcategories </strong>template is only called if a top-level category has any subcategories. It displays a list of, well&#8230;subcategories.</p>
<p>The <strong>embeds/sub_subcategories </strong>template is only called if a subcategory has any subcategories.</p>
<p>You can create as many levels of dropdowns/flyouts as you want by replicating the <strong>embeds/subcategories </strong>template and naming it something else (like embeds/sub_sub_subcategories).</p>
<h2>The Code</h2>
<p>In your <strong>embeds/navigation </strong>template, place the following code:</p>
<pre>&lt;ul id="nav"&gt;
   {exp:weblog:categories parent_only="yes" style="linear"}
      &lt;li&gt;
         {exp:query sql="SELECT cat_id FROM exp_categories WHERE parent_id = '{category_id}' LIMIT 1"}
            &lt;a href="{path='SITE_INDEX'}"{if '{total_results}' &gt; 0} class="fly"{/if}&gt;{category_name}&lt;/a&gt;
            {if '{total_results}' &gt; 0}{embed="embeds/subcategories" cat_id="{category_id}"}{/if}
         {/exp:query}
      &lt;/li&gt;
   {/exp:weblog:categories}
&lt;/ul&gt;</pre>
<p>If you&#8217;re scratching your head about what that all means, here it is:</p>
<ul>
<li>First, we use the <a href="http://expressionengine.com/docs/modules/weblog/categories.html">exp:weblog:categories</a> tag pair to show a list of all categories. We show only top-level categories by using the <strong>parent_only=&#8221;yes&#8221; </strong>parameter.</li>
<li>Next, we output a link to the category and display the name (using <strong>{path=&#8217;SITE_INDEX&#8217;} </strong>removes the &#8220;category&#8221; segment from the URL). The {exp:query} call allows us to add a class of &#8220;fly&#8221; to anchors that are associated with parent categories. This is useful if you&#8217;d like to add styling to your parent categories (<a href="http://www.3roadsmedia.com/sandbox/index.php/site/">see the demo</a> for an example).</li>
<li>The {exp:query} call also checks to see if your top-level categories have children. If so, call the <strong>embeds/subcategories </strong>template.</li>
</ul>
<p>In your <strong>embeds/subcategories </strong>template, place the following code:</p>
<pre>&lt;ul&gt;
   {exp:subcategories root_node="{embed:cat_id}"}
      &lt;li&gt;
         &lt;a href="{homepage}/category/{category_url}"{if '{subcategories_count}' &gt; 0} class="fly"{/if}&gt;{category_name}&lt;/a&gt;
         {if '{subcategories_count}' &gt; 0}{embed="embeds/sub_subcategories" subcat_id="{category_id}"}{/if}
      &lt;/li&gt;
   {/exp:subcategories}
&lt;/ul&gt;</pre>
<p>Here is an explanation of the code:</p>
<ul>
<li>We passed in the parent&#8217;s category ID as <strong>cat_id</strong>. The subcategories plugin takes this value in the <strong>root_node </strong>parameter to pull a list of subcategories.</li>
<li>For each subcategory, output a link. The Subcategories plugin has a neat variable called {subcategories_count}, which lets us replace the SQL query that you see in the embeds/navigation template. If there are subcategories, apply a class of &#8220;fly&#8221; to the anchor. This lets us style our anchors to indicate that there are more dropdowns/flyouts.</li>
<li>Lastly, use the {subcategories_count} variable to see if the current subcategory has subcategories of its own. If so, call the <strong>sub_subcategories </strong>template.</li>
</ul>
<p>In your<strong> embeds/sub_subcategories</strong> template, place the following code:</p>
<pre>&lt;ul&gt;
   {exp:subcategories root_node="{embed:subcat_id}"}
      &lt;li&gt;
         &lt;a href="{homepage}/category/{category_url}"&gt;{category_name}&lt;/a&gt;
      &lt;/li&gt;
   {/exp:subcategories}
&lt;/ul&gt;</pre>
<p>Note how similar this code is to the embeds/subcategories code. The only difference is that we did not check to see if the grandchild categories had subcategories of their own. We can easily do this by adding the following line&#8230;</p>
<pre>{if '{subcategories_count}' &gt; 0}{embed="embeds/sub_sub_subcategories" subcat_id="{category_id}"}{/if}</pre>
<p>&#8230;and then creating an <strong>embeds/sub_sub_subcategories</strong> template. In this way, you can create as many levels of menus as you want.</p>
<h2>Enjoy</h2>
<p>Adding category based dropdown menus to an ExpressionEngine website doesn&#8217;t have to be a drag. This tutorial should get you up and running without trouble; however, if you find bugs or see ways to improve the examples here, let us know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3roadsmedia.com/blog/multilevel-dropdown-category-navigation-in-expressionengine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use a ModalBox to edit content inline with ExpressionEngine</title>
		<link>http://www.3roadsmedia.com/blog/use-a-modal-box-to-edit-content-inline-with-expressionengine/</link>
		<comments>http://www.3roadsmedia.com/blog/use-a-modal-box-to-edit-content-inline-with-expressionengine/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 20:59:20 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Developer's Toolbox]]></category>
		<category><![CDATA[ExpressionEngine]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.3roadsmedia.com/?p=437</guid>
		<description><![CDATA[0]]></description>
			<content:encoded><![CDATA[<p>A couple months ago, I wrote a post on <a href="http://www.3roadsmedia.com/blog/inline-editing-with-expressionengine-and-ajax/">how to use AJAX to edit content inline</a> &#8211; without accessing the control panel and without a page refresh.</p>
<p>Since then, I&#8217;ve found a much cooler and more practical way of editing content inline: by using a <a href="http://en.wikipedia.org/wiki/Modal_window">modal box</a>. The result is the same: authorized users can update certain content blocks without control panel access and without any knowledge of HTML.</p>
<p><span id="more-437"></span>In fact, I think this method is far more robust, flexible, and user friendly than the AJAX one I shared with you a while back.</p>
<p>Let&#8217;s get started.</p>
<h2>What is a modal box?</h2>
<p>If you already know what a modal box is and why you would use it with ExpressionEngine, feel free to <a href="#step1">skip ahead</a> to the implementation.</p>
<p>A modal box is a JavaScript driven dialogue box that &#8220;pops over&#8221; a page&#8217;s content. It is not a separate popup window, so it won&#8217;t be blocked by a user&#8217;s browser. Perhaps most importantly, a modal box requires the user to interact with it before the user can do anything else on the page.</p>
<div id="attachment_440" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-440" title="modal-box-example" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/05/modal-box-example.jpg" alt="A simple modal box" width="490" height="353" /><p class="wp-caption-text">A simple modal box</p></div>
<h2>Why use a modal box for inline editing?</h2>
<p>Usability. A modal box does not require the user to leave the current page, which means a user can interact with the dialogue (or series of dialogues) while still seeing the same page in the background.</p>
<p>For ExpressionEngine users in particular, <strong>not having to leave the page you want to edit is a big bonus</strong>, since finding a particular weblog entry in the control panel can be time consuming.</p>
<h2>Can I see a demonstration?</h2>
<p><a href="http://www.3roadsmedia.com/sandbox/index.php/modalbox_test/index/">Here is the end result</a> of this tutorial. Feel free to make some changes &#8211; these are posting to an actual EE database so you can see how this method works.</p>
<p>You can also go to <a href="http://www.wildbit.com/labs/modalbox/">Wildbit&#8217;s Modal Box page</a> and check out the demos.</p>
<h2>Getting a modal box to work with ExpressionEngine</h2>
<p>The goal for this tutorial is to implement a modal box that allows us to edit the content of an ExpressionEngine weblog entry <strong>inline</strong>; that is, without control panel access.</p>
<h3 id="step1">Step 1: Create a new weblog, custom fields, and template group</h3>
<p>To be as comprehensive as possible, I&#8217;ll assume that you&#8217;re starting with a fresh EE install. If you already have weblogs set up, <a href="#step2">skip to the next step</a>.</p>
<p>Create a new weblog (in a flash of brilliance, I named mine &#8220;ModalBox Test&#8221; and gave it a short name of <strong>modalbox_test</strong>).</p>
<p>Create a new custom field group (or use the default one). Make sure it has at least one text input field type and one textarea field type. I set the formatting for my fields to &#8220;none,&#8221; but you don&#8217;t have to.</p>
<div id="attachment_443" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-443" title="modalbox-ee-custom-fields" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/05/modalbox-ee-custom-fields.png" alt="I created two custom fields for this tutorial. Use the short names above if you plan to follow this tutorial to a T." width="490" height="146" /><p class="wp-caption-text">Use the short names above if you plan to follow this tutorial to a T.</p></div>
<p>Assign your field group to your modalbox_test weblog.</p>
<p>Create a new template group. I called mine <strong>modalbox_test</strong>, the same as the weblog.</p>
<h3 id="step2">Step 2: Grab the ModalBox files</h3>
<p>Visit Wildbit&#8217;s site and <a href="http://www.wildbit.com/labs/modalbox/">download the latest version of ModalBox</a> (I&#8217;m using 1.6.0 for this tutorial).</p>
<p>Extract the zip file on your computer, then upload the <strong>modalbox1.6.0</strong> folder to your web server. For this tutorial, I renamed my modalbox1.6.0 folder to <strong>modalbox </strong>and uploaded it to my <strong>system/scripts </strong>folder (this folder does not exist by default, so you will have to create it).</p>
<div id="attachment_442" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-442" title="modalbox-folder-location1" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/05/modalbox-folder-location1.png" alt="For the visually inclined." width="490" height="186" /><p class="wp-caption-text">For the visually inclined.</p></div>
<p>The <strong>system </strong>folder is EE&#8217;s default system folder. You may have renamed it to something else.</p>
<h3>Step 3: Link the ModalBox files to your template</h3>
<p>I&#8217;ve prepared the following code block that you can use in your new template. If you&#8217;re using my custom field names from <a href="#step1">Step #1</a>, you don&#8217;t need to change anything. Otherwise, be sure to replace my custom field names with your own.</p>
<p>Copy and paste the following code into your <strong>modalbox_test/index</strong> template (the calls to the ModalBox files are in <span style="color: #ff0000;"><strong>red boldface</strong></span>):</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;Inline Editing with Modal Boxes&lt;/title&gt;
    &lt;link rel="stylesheet" type="text/css" href="{stylesheet=weblog/stylesheet}" /&gt;

    &lt;!-- Modalbox files --&gt;
<span style="color: #ff0000;"><strong>    &lt;script type="text/javascript" src="{scripts}/modalbox/lib/prototype.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="{scripts}/modalbox/lib/scriptaculous.js?load=effects"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="{scripts}/modalbox/modalbox.js"&gt;&lt;/script&gt;
    &lt;link rel="stylesheet" type="text/css" href="{scripts}/modalbox/modalbox.css" media="screen" /&gt;</strong></span>
    &lt;!--// Modalbox files --&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;An example of inline editing with ExpressionEngine and Modal Boxes&lt;/h1&gt;

&lt;ul&gt;
    {exp:weblog:entries disable="categories|member_data|pagination|trackbacks" weblog="modalbox_test"}
        &lt;li&gt;
            &lt;h2&gt;{title}&lt;/h2&gt;
            &lt;p&gt;&lt;strong&gt;{modalbox_input}&lt;/strong&gt;&lt;/p&gt;
            &lt;p&gt;{modalbox_textarea}&lt;/p&gt;
        &lt;/li&gt;
    {/exp:weblog:entries}
&lt;/ul&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>Notice the {scripts} variable. </strong>That is a global variable I set up in EE that contains the path to my scripts folder (e.g., http://www.yoursite.com/system/scripts).</p>
<h3>Step 4. Add an &#8220;Edit&#8221; link</h3>
<p>Before you go any further, add some test entries, then preview your template to make sure everything is hooked up correctly.</p>
<p>Once that&#8217;s done, add the following line of code to your template. Place it where you&#8217;d like the &#8220;Edit&#8221; link to appear (I placed mine right below the &lt;h2&gt; tags in the sample code).</p>
<pre>{if logged_in}&lt;a onclick=<code><span style="color: #000000;"><span style="color: #dd0000;">"Modalbox.show($('modalbox-content-{entry_id}'), {title: this.title, width: 800}); return false;" </span><span style="color: #0000bb;">title</span><span style="color: #007700;">=</span><span style="color: #dd0000;">"Edit this weblog entry" </span><span style="color: #0000bb;">href</span><span style="color: #007700;">=</span><span style="color: #dd0000;">"#"</span><span style="color: #007700;">&gt;</span><span style="color: #0000bb;">Edit</span><span style="color: #007700;">&lt;/</span><span style="color: #0000bb;">a</span><span style="color: #007700;">&gt;{/if}</span></span></code></pre>
<p>This line of code tells the ModalBox script to load a DIV with an ID of <strong>modalbox-content-XX</strong> (where XX is the entry&#8217;s ID) into a ModalBox that is 800 pixels wide with a heading of &#8220;Edit weblog entry.&#8221;</p>
<h3>Step 5. Create the DIV</h3>
<p>In the previous step, we told ModalBox to find and display a DIV with a particular ID. This DIV will contain a SAEF (<a href="http://expressionengine.com/wiki/Hard_Coded_Stand_Alone_EDIT_Form_Guide/">stand alone edit form</a>), which allows us to easily and safely post our changes to the EE database.</p>
<p><a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/06/SAEF.txt">Grab the SAEF code here</a> and paste it wherever you like in your main template, so long as it is within the {exp:weblog:entries} tags.</p>
<p>The only thing you&#8217;ll need to change in the SAEF are the custom field ID numbers associated with each of your custom fields.</p>
<p>What?</p>
<p>When you created custom fields for your weblog, ExpressionEngine assigned each of them a unique ID number. We need to know what these numbers are in order to pull the correct information from the database.</p>
<p><strong>To find these numbers</strong>, go to Admin › Weblog Administration › Custom Weblog Fields, then click &#8220;Add/Edit Custom Fields&#8221; next to the field group you created for this tutorial. Mouse over each of your custom fields and note the number that appears in the bottom left of your browser:</p>
<div id="attachment_444" class="wp-caption aligncenter" style="width: 509px"><img class="size-full wp-image-444" title="modalbox-ee-custom-field-id-explanation" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/05/modalbox-ee-custom-field-id-explanation.png" alt="How to find a field ID for your custom fields" width="499" height="251" /><p class="wp-caption-text">How to find a field ID for each of your custom fields</p></div>
<p>Here are my field IDs:</p>
<ul>
<li>modalbox_input: <strong>73</strong></li>
<li>modalbox_textarea: <strong>74</strong></li>
</ul>
<p>In your SAEF, find any references to these field IDs. <strong>They will look like field_id_XX, where XX is the field ID</strong>. For example, I would change my SAEF to look like this (my changes are in <span style="color: #ff0000;"><strong>red</strong></span>):</p>
<pre>&lt;label for="amount"&gt;Modalbox Input&lt;/label&gt;
&lt;input type="text" name="<strong>field_id_<span style="color: #ff0000;">73</span></strong>" id="amount" value="{modalbox_input}" /&gt;
&lt;input type="hidden" name="<strong>field_ft_<span style="color: #ff0000;">73</span></strong>" value="none" /&gt;

&lt;label for="details"&gt;Modalbox Textarea&lt;/label&gt;
&lt;textarea name="<strong>field_id_<span style="color: #ff0000;">74</span></strong>" id="details"&gt;{modalbox_textarea}&lt;/textarea&gt;
&lt;input type="hidden" name="<strong>field_ft_<span style="color: #ff0000;">74</span></strong>" value="none" /&gt;</pre>
<p><strong>The field_ft_XX lines control the formatting for a particular field</strong>. You can leave them set to &#8220;none&#8221; to remove all HTML formatting.</p>
<h3>Step 6. Test your ModalBox</h3>
<p>Save and preview your template, then click an &#8220;Edit&#8221; link to call the ModalBox. If you&#8217;ve followed along closely, you&#8217;ll see a form populated with your weblog entry&#8217;s content.</p>
<div id="attachment_464" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-464" title="The results of our hard work" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/06/modalbox-success.png" alt="The results of our hard work" width="500" height="207" /><p class="wp-caption-text">The results of our hard work</p></div>
<p>Make some changes and click &#8220;Save&#8221; and you should be sent to the location specified in the &#8220;return&#8221; parameter of your SAEF. If this is the same page you just came from, you should see your changes.</p>
<h3>Step 7. Add a success message</h3>
<p>If you make a change and get dumped back on a page without any visual cues that something changed, you (or your client) may not have a clue what just happened.</p>
<p>That&#8217;s why I suggest adding a success message.</p>
<p>First, alter the <strong>return </strong>parameter in your SAEF to include the following:</p>
<pre>return="modalbox_test/index<strong>/?updated=true</strong>"</pre>
<p>You can set &#8220;updated&#8221; to be anything you like; it&#8217;s just a variable name.</p>
<p>Next, in the page you are returning to (modalbox_test/index), add the following lines of PHP:</p>
<pre class="codeblock">&lt;?php
    if(stristr($_SERVER['REQUEST_URI'], 'updated=true')) { $updated = 1; }

    if(isset($updated)) {
        echo "&lt;div&gt;Your weblog entry was successfully updated.&lt;/div&gt;";
    }
?&gt;</pre>
<p>This snippet checks the URL for the segment we just added; if it finds it, then it displays a success message.</p>
<h3>Step 8. Add a dropdown menu</h3>
<p>In my last tutorial on inline editing, I didn&#8217;t touch the subject of dropdowns, since trying to get them to work with that script was impossible.</p>
<p>Luckily, we can use the SAEF with a bit of PHP to get what we need. Add the following where you&#8217;d like your dropdown to appear in the SAEF, being sure to replace the field IDs as needed:</p>
<pre>&lt;label for="dropdown"&gt;Dropdown List&lt;/label&gt;
<span class="punct">&lt;</span><span class="ident">select</span> <span class="ident">name</span><span class="punct">="</span><strong><span class="string">field_id_<span style="color: #ff0000;">XX</span></span></strong><span class="punct">"&gt;
    {</span><span class="ident">exp</span><span class="symbol">:query</span> <span class="ident">sql</span><span class="punct">="</span><span class="string">SELECT field_list_items FROM exp_weblog_fields WHERE field_id = '<span style="color: #ff0000;"><strong>XX</strong></span>' </span><span class="punct">"}</span>
        <span class="punct">&lt;?</span>php
            <span class="global">$items</span> <span class="punct">="</span><span class="string">{field_list_items}</span><span class="punct">";</span>
            <span class="global">$items</span> <span class="punct">=</span> <span class="ident">explode</span><span class="punct">("</span><span class="string"><span class="escape">\n</span></span><span class="punct">",</span> <span class="global">$items</span><span class="punct">);</span>
<span class="global">            $howmany</span> <span class="punct">=</span> <span class="ident">count</span><span class="punct">(</span><span class="global">$items</span><span class="punct">);</span>
            <span class="global">$i</span> <span class="punct">=</span> <span class="number">0</span><span class="punct">;</span> <span class="keyword">do</span> <span class="punct">{</span>
<span class="global">            $item_id</span> <span class="punct">=</span> <span class="global">$items</span><span class="punct">[</span><span class="global">$i</span><span class="punct">];</span>
        <span class="char">?&gt;</span>
        <span class="punct">&lt;</span><span class="ident">option</span> <span class="ident">value</span><span class="punct">="</span><span class="string">&lt;?=$item_id?&gt;</span><span class="punct">"&gt;&lt;</span><span class="char">?=</span><span class="global">$item_id</span><span class="char">?&gt;</span><span class="punct">&lt;/</span><span class="regex">option&gt;
        &lt;?php
            $i++; } while ($i &lt; $howmany);
        ?&gt;
    {</span><span class="punct">/</span><span class="ident">exp</span><span class="symbol">:query</span><span class="punct">}
&lt;/</span><span class="regex">select&gt;</span></pre>
<p>This bit of code will loop through all of your manually entered dropdown items, then display them.</p>
<h3>Step 9. Enjoy!</h3>
<p>Feel free to share your own experiences, or to suggest ways to improve the code I&#8217;ve presented here. Have a question? Got stuck and need help? Let me know!</p>
<h3>Postscript: Streamlining your implementation</h3>
<p>I was fortunate enough to receive some feedback from <a href="http://www.stolpmann.eu/">Markus Stolpmann</a>, a fellow EE user, on how to improve the modalbox implementation. The steps above are fine if you don&#8217;t mind including hidden divs in your code – but what if this isn&#8217;t your cup of tea?</p>
<p>It&#8217;s far easier to maintain your code if you include the SAEF in a separate template.</p>
<p>To begin, create a new template group (something like <strong>modalboxes </strong>works well). This new group will hold all of the content shown in your modal boxes. Our company intranet, for example, has templates like:</p>
<ul>
<li>modalboxes/add_prospect</li>
<li>modalboxes/add_invoice</li>
<li>modalboxes/edit_prospect</li>
<li>modalboxes/edit_invoice</li>
</ul>
<p>Each of these templates contains a SAEF with fields specific to the task (i.e., I won&#8217;t have an &#8220;invoice number&#8221; input box in my <strong>edit_prospect </strong>template). Here is an example of what my <strong>modalboxes/edit_prospect</strong> template looks like:</p>
<pre>{exp:weblog:entry_form weblog="prospects" return="prospects/prospect_added"}
    &lt;ul&gt;
        &lt;li&gt;
            &lt;label for="title"&gt;Prospect Name&lt;em&gt;*&lt;/em&gt;&lt;/label&gt;
            &lt;input type="text" name="title" id="title" value="{title}" maxlength="100" onkeyup="liveUrlTitle();" /&gt;
        &lt;/li&gt;
        &lt;li&gt;
            &lt;label for="email"&gt;Email&lt;/label&gt;
            &lt;input type="text" name="field_id_4" id="email" /&gt;
        &lt;/li&gt;
        ...
        &lt;li&gt;
            &lt;input type="submit" name="submit" value="Edit prospect" /&gt;&amp;nbsp;or &lt;a href="#" title="Close window" onclick="Modalbox.hide()"&gt;Cancel and close window&lt;/a&gt;
            &lt;input type="hidden" name="status" value="Prospect" /&gt;
            &lt;input type="hidden" name="url_title" value="{url_title}" maxlength="75" /&gt;
            &lt;input type="hidden" name="entry_date" value="&lt;?php echo date("Y-m-d h:i"); ?&gt;" /&gt;
            &lt;input type="hidden" name="allow_comments" value="y" {allow_comments} /&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
{/exp:weblog:entry_form}</pre>
<p>Go ahead and remove the divs we created in step 5, transferring them to your new template group. Then find your &#8220;edit&#8221; link (step 4) and replace it with the following:</p>
<pre>&lt;a onclick="Modalbox.show('{path=modalboxes/edit_prospect}{entry_id}', {title: this.title, width: 800}); return false;" title="{title} &amp;ndash; Edit details" href="#"&gt;</pre>
<p>This line of code passes each weblog entry&#8217;s ID to the &#8220;modalboxes&#8221; template group, where it&#8217;s picked up automatically and used to populate your SAEF.</p>
<p>You can now enjoy modalboxes without cluttering your main templates with hidden divs. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3roadsmedia.com/blog/use-a-modal-box-to-edit-content-inline-with-expressionengine/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Inline editing with ExpressionEngine and AJAX</title>
		<link>http://www.3roadsmedia.com/blog/inline-editing-with-expressionengine-and-ajax/</link>
		<comments>http://www.3roadsmedia.com/blog/inline-editing-with-expressionengine-and-ajax/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 17:53:40 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Developer's Toolbox]]></category>
		<category><![CDATA[ExpressionEngine]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.3roadsmedia.com/?p=214</guid>
		<description><![CDATA[0]]></description>
			<content:encoded><![CDATA[<p>Web developers are a demanding lot. We&#8217;re impatient for change, we wanted it yesterday, and we love shortcuts. I don&#8217;t mean the &#8220;cutting corners&#8221; type of shortcut. I mean the &#8220;this will make life easier&#8221; type of shortcut.</p>
<p>In this post, I&#8217;ll show you how you can use AJAX to edit your ExpressionEngine content on the front end, without a page refresh, and with a simple click of the mouse.</p>
<p><strong>NOTE: I recently wrote about an improved method for inline editing with EE using modal boxes. <a href="http://www.3roadsmedia.com/blog/use-a-modal-box-to-edit-content-inline-with-expressionengine/">Read the tutorial here</a>.</strong><span id="more-214"></span></p>
<h2>The Problem</h2>
<p>Making changes to front end content can be time consuming and confusing. Even if your templates are set to display WordPress-style &#8220;edit&#8221; links next to each weblog entry, you have to use the control panel (CP) to make changes. <strong>Many end users don&#8217;t feel comfortable</strong> using the CP, and many times you just want to make a quick change without leaving the front end.</p>
<p>The good news is that with a bit of AJAX, we can bypass the CP altogether, greatly simplifying the editing process.</p>
<h2>The Solution</h2>
<p>I took my inspiration from <a href="http://24ways.org/2005/edit-in-place-with-ajax">an old post on inline editing</a> at 24 ways. I&#8217;ve modified the code to work with ExpressionEngine, and will show you how you can get it to work with your own EE site.</p>
<h3>Step 1: Create a new EE weblog and template</h3>
<p>Create a new weblog and connect it to a custom field group with at least one textarea field (<strong>make sure the formatting is set to &#8220;none&#8221;</strong>). Enter a few sample entries, and then create a new template.</p>
<p>Enter the following HTML in your template, substituting your weblog name for <strong>ajax-test</strong> and your custom field name for <strong>{body}</strong>:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;title&gt;Edit-in-Place with Ajax&lt;/title&gt;
    &lt;link rel="stylesheet" type="text/css" href="{stylesheet=home/stylesheet}" /&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Editing Inline with ExpressionEngine and AJAX&lt;/h1&gt;

{if logged_in}
    {exp:weblog:entries disable="categories|member_data|pagination|trackbacks" weblog="ajax-test"}
        &lt;h2&gt;{title}&lt;/h2&gt;
        &lt;p&gt;{body}&lt;/p&gt;
    {/exp:weblog:entries}
{/if}

{if logged_out}&lt;p&gt;You must be logged in to view this page!&lt;/p&gt;{/if}
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>I recommend previewing your template to ensure the entries are displaying properly.</p>
<h3>Step 2: Grab the Prototype JavaScript library</h3>
<p>The script we&#8217;ll be using requires Prototype. <a href="http://www.prototypejs.org/download">Get the latest version of Prototype here</a>, upload it to your server, and add the following line to your template (inside the <code>&lt;head&gt;</code> tags):</p>
<pre>&lt;script src="http://path-to-your-scripts-folder/prototype.js" type="text/javascript"&gt;&lt;/script&gt;</pre>
<h3>Step 3: Grab the Script</h3>
<p>Here&#8217;s where all the magic happens. <a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/03/editinplace_basic.js">Grab the script here</a> and save it as <strong>editinplace.js</strong> (don&#8217;t upload it just yet). Be sure to place a call to the script in your template by adding this line:</p>
<pre>&lt;script src="http://path-to-your-scripts-folder/editinplace.js" type="text/javascript"&gt;&lt;/script&gt;</pre>
<p>I recommend leaving the script open in another window while you follow along here.</p>
<h3>Step 4: Get familiar with the script</h3>
<p>Let&#8217;s take a closer look at <strong>editinplace.js</strong>. The first line ensures the script won&#8217;t run until the page is fully loaded. The <code>init()</code> function defines which element ID we want to be editable &#8211; in this case, <strong>editTitle</strong>.</p>
<p>The <code>makeEditable()</code> function does three things:</p>
<ol>
<li><strong>On mouseclick</strong>, call the <code>edit()</code> function, which hides the editable text and displays a textarea and two buttons (&#8220;Save&#8221; and &#8220;Cancel&#8221;)</li>
<li><strong>On mouseover</strong>, add a CSS class to the editable area (this allows us to highlight it on hover)</li>
<li><strong>On mouseout</strong>, remove the CSS class from the editable area</li>
</ol>
<p>Notice that the <code>showAsEditable()</code> function is creating and removing a CSS class called <code>editable</code>. You can rename this to whatever you want, but <strong>be sure to add a declaration to your stylesheet</strong>.</p>
<p>The declaration I&#8217;m using on the demo page is:</p>
<pre>.editable { background:#ffffd3; cursor:pointer; }</pre>
<p>If a user clicks &#8220;Cancel,&#8221; the <code>cleanUp()</code> function is called; it clears the textarea and buttons and unhides the original text.</p>
<p>If a user clicks &#8220;Save,&#8221; the <code>saveChanges()</code> function is called; it posts the changes, displays a &#8220;Saving&#8230;&#8221; message, and returns the updated text.</p>
<h3>Step 5: Grab the PHP</h3>
<p>The script you just copied works in tandem with a small PHP script, which takes your changes and echoes them to the screen. Paste the script below into a new file:</p>
<pre>&lt;?php
    $id = $_POST['id'];
    $content = $_POST['content'];
    echo htmlspecialchars($content);
?&gt;</pre>
<p>Save this file as <strong>edit.php </strong>and upload it to your server. Update <strong>editinplace.js</strong> (line 53) to point to your PHP script, then upload this file too.</p>
<h3>Step 6: Put the script to work</h3>
<p>Now that we know what the scripts are doing, let&#8217;s put them to work. Editinplace.js is looking for an element with an ID of <strong>editTitle</strong>, but your template doesn&#8217;t currently have that. Let&#8217;s add it in.</p>
<p>Change the <code>&lt;h2&gt;</code> tag in your template to this:</p>
<pre>&lt;h2 id="editTitle"&gt;{title}&lt;/h2&gt;</pre>
<p>Save your template and preview it. Move your mouse over your <strong>first heading</strong>. Assuming you copied my CSS rules from above, you should see a highlighted box surround your heading, and your cursor should change to a pointer. Click the heading, edit the text, and click &#8220;Save&#8221; or &#8220;Cancel.&#8221;</p>
<p>If you try to edit your other headings, you&#8217;ll notice nothing&#8217;s happening.</p>
<p>Why is this? Remember that an ID is unique to a page, so if you have duplicate IDs, you&#8217;ll get strange results. In this case, <strong>only the first element of a given ID will be editable</strong>.</p>
<p>For most ExpressionEngine applications, you&#8217;ll be looping through a weblog several times, so this approach won&#8217;t work.</p>
<h3>Step 7: Making multiple items on the same page editable</h3>
<p>First, change the <code>init()</code> function in <strong>editinplace.js</strong> to this:</p>
<pre>function init() {
    var max = 50;
    for (var i = 1; i &lt;= max; i++) {
        makeEditable('editTitle_' + i);
    }
}</pre>
<p>Then, in your template, modify your <code>&lt;h2&gt;</code> tag like so:</p>
<pre>&lt;h2 id="editTitle<strong>_{count}</strong>"&gt;{title}&lt;/h2&gt;</pre>
<p>Refresh your template and you should be able to make changes to all of your headings.</p>
<h3>Step 8: Posting changes to your ExpressionEngine database</h3>
<p>Up to this point, we&#8217;ve only been echoing changes back to the screen. Now it&#8217;s time to make those changes permanent by posting them to a database.</p>
<p>The bulk of the work will come in <strong>edit.php</strong>, though before we start making changes to that file, we need to add some things to <strong>editinplace.js</strong>.</p>
<p>Update your <code>saveChanges()</code> function to look like this (changes are in <strong>bold</strong>):</p>
<pre>function saveChanges(obj) {
    var new_content = escape($F(obj.id+'_edit'));

    <strong>obj.preUpdate = obj.innerHTML</strong>
    obj.innerHTML = "Saving…";
    cleanUp(obj, true);

    var success = function(t){editComplete(t, obj);}
    var failure = function(t){editFailed(t, obj);}

    var url = 'http://path-to-your-scripts-folder/edit.php';
    var pars = 'id=' + obj.id + '&amp;content=' + new_content<strong> + '&amp;pre=' + obj.preUpdate</strong>;
    var myAjax = new Ajax.Request(url, {method:'post',
    postBody:pars, onSuccess:success, onFailure:failure});
}</pre>
<p>If you copy and paste from above, don&#8217;t forget to update the path to your PHP file.</p>
<p>Next, update <strong>edit.php</strong> to look like this:</p>
<pre>&lt;?php
    $id = $_POST['id'];
    $content = $_POST['content'];
    <strong>$pre = $_POST['pre'];</strong>
    echo htmlspecialchars($content);

<code><span class="html">    <strong>require_once("path-to-your/include.inc.php")</strong>;

</span></code><strong>    $sql = mysql_query("UPDATE exp_weblog_titles SET title = '$content' WHERE title = '$pre'");

    if(!$sql) {
        echo "&lt;p class='error'&gt;Unable to update the title!&lt;/p&gt;";
    }</strong>
?&gt;</pre>
<p>You&#8217;ll need to create an include file that contains the connection information for your database (<a href="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/03/sample-include.inc.txt">grab a sample include file here</a>).</p>
<p>Update the path to your include file, enter your database connection information, save all three files, upload them, and refresh your rendered template. Make some changes to the titles. Refresh the page again, and your changes should remain.</p>
<p>Congratulations &#8211; you&#8217;ve just made a direct change to your EE database with AJAX!</p>
<h2>Going a step further &#8211; editing more than just titles</h2>
<p>You probably noticed in <a href="http://www.3roadsmedia.com/ajax-demo.html">the demo</a> that the excerpt for each post was also editable. Here&#8217;s how you do it:</p>
<h3>Step 9: Create another editable element</h3>
<p>First, you&#8217;ll need to tell the script that you want to make another set of IDs editable. Modify the <code>init()</code> function in <strong>editinplace.js</strong> to look like this:</p>
<pre>function init() {
    var max = 50;
    for (var i = 1; i &lt;= max; i++) {
        makeEditable('editTitle_' + i);
        <strong>makeEditable('editBody_' + i);</strong>
    }
}</pre>
<p>Next, modify your template by adding the new ID:</p>
<pre>&lt;p<strong> id="editBody_{count}"</strong>&gt;{body}&lt;/p&gt;</pre>
<p>Finally, to post any changes to your paragraphs to the database, you&#8217;ll need to modify <strong>edit.php</strong>:</p>
<pre>&lt;?php
    $id = $_POST['id'];
    $content = $_POST['content'];
    $pre = $_POST['pre'];
    echo htmlspecialchars($content);

<code><span class="html">    require_once("path-to-your/include.inc.php");</span></code>

<strong>    if(stristr($id, 'Title') == true) {
        $sql = mysql_query("UPDATE exp_weblog_titles SET title = '$content' WHERE title = '$pre'");
    } elseif(stristr($id, 'Body') == true) {
        $sql = mysql_query("UPDATE exp_weblog_data SET field_id_65 = '$content' WHERE field_id_65 = '$pre'");
    }</strong>
?&gt;</pre>
<p>Since the PHP script is handling requests for both <code>editTitle</code> and <code>editBody</code>, we need to use the <code>stristr()</code> function to determine which ID is being passed in.</p>
<p><strong>Be sure that the field ID matches your custom field! </strong>In the example above, it is 65, but yours is likely different.</p>
<p>You can find your field ID by going into the CP, clicking &#8220;Admin,&#8221; selecting &#8220;Custom Weblog Fields,&#8221; and hovering your mouse over the field name on the left. The field ID will appear at the very end of the URL string at the bottom left of your browser.</p>
<h3>Step 10: Provide a textarea for paragraphs and a text input for titles</h3>
<p>You probably don&#8217;t want to be editing large hunks of text in a tiny input box. To get a textarea to show up when you click on a paragraph (while keeping a text input for your titles), modify the <code>edit()</code> function in <strong>editinplace.js</strong>:</p>
<pre>function edit(obj) {
    Element.hide(obj);

<strong>    if(obj.id.search(/Title/) != -1) {
        // show an input box if we're editing a header
        var textbox ='&lt;div class="edit-input" id="' + obj.id + '_editor"&gt;&lt;input name="' + obj.id + '" type="text" id="' + obj.id + '_edit" value="' + obj.innerHTML + '" /&gt;';
    } else {
        // else show a textarea
        var textbox ='&lt;div class="edit-area" id="' + obj.id + '_editor"&gt;&lt;textarea name="' + obj.id + '" id="' + obj.id + '_edit"&gt;' + obj.innerHTML + '"&lt;/textarea&gt;';
    }</strong>

    var button = '&lt;input type="button" value="SAVE" id="' + obj.id + '_save"/&gt; OR &lt;input type="button" value="CANCEL" id="' + obj.id + '_cancel"/&gt;&lt;/div&gt;';

    new Insertion.After(obj, textbox+button);

    Event.observe(obj.id+'_save', 'click', function(){saveChanges(obj)}, false);
    Event.observe(obj.id+'_cancel', 'click', function(){cleanUp(obj)}, false);
}</pre>
<h3>Step 11: Limiting edits to certain member groups</h3>
<p>Before you decide to go crazy with inline editing, remember that, without the proper checks, anyone who visits your site can make changes to your content.</p>
<p>For starters, you should wrap your editable areas in a <code>{if logged_in}</code> conditional. Once that&#8217;s done, you should also consider only allowing certain member groups to edit content inline. Here&#8217;s a quick fix:</p>
<pre>&lt;h2<strong>{if member_group == 1}</strong> id="editTitle_{count}"<strong>{/if}</strong>&gt;{title}&lt;/h2&gt;</pre>
<p>These conditionals allow you to specify who can edit which areas. You could, for example, allow members to edit your body text, but only allow admins to edit your titles.</p>
<h2>Limitations</h2>
<p>While working through this script, I came up against a few roadblocks:</p>
<ul>
<li>When making more than one element (e.g., headers <strong>and </strong>paragraphs) editable, you must have an equal number of each. In other words, if there are 3 headers on the page that you want to edit, you can&#8217;t have more than 3 paragraph blocks that are editable. Paragraphs beyond the 3rd won&#8217;t be clickable.</li>
<li>You have to pre-define a max number of editable fields (in my example, this is 50).</li>
<li>Inline editing doesn&#8217;t work well with headings that are also anchors</li>
</ul>
<h2>Conclusion</h2>
<p>This is my first attempt at getting inline editing to work with ExpressionEngine. I don&#8217;t profess to be a code guru, so it is my hope that a little bit of discussion can help improve the code here and make life easier for developers and end users everywhere.</p>
<p>I welcome your feedback, frustrations, and success stories. Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3roadsmedia.com/blog/inline-editing-with-expressionengine-and-ajax/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>10 useful ExpressionEngine extensions</title>
		<link>http://www.3roadsmedia.com/blog/10-useful-expressionengine-extensions/</link>
		<comments>http://www.3roadsmedia.com/blog/10-useful-expressionengine-extensions/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 23:46:38 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Developer's Toolbox]]></category>
		<category><![CDATA[ExpressionEngine]]></category>

		<guid isPermaLink="false">http://www.3roadsmedia.com/?p=186</guid>
		<description><![CDATA[0]]></description>
			<content:encoded><![CDATA[<p>I discovered <a href="http://expressionengine.com/">ExpressionEngine</a> (EE) back in 2007, and have since become a devoted user and a huge fan. In my humble opinion, it&#8217;s far and away the best content management system on the market.</p>
<p>Having worked with it for some time now, I&#8217;ve had a chance to work with a number of great <a href="http://expressionengine.com/docs/development/extensions.html">extensions</a>, which I&#8217;d like to share with you here. To fill out my list, I went through dozens of extensions I had <em>not </em>used, testing and then hand-picking my favorites.</p>
<p><span id="more-186"></span></p>
<p>Here they are, in no particular order:</p>
<h2>1. Edit Tab AJAX <a href="http://expressionengine.com/downloads/details/edit_tab_ajax/">(download)</a></h2>
<p>Edit Tab AJAX takes advantage of the <a href="http://www.ngenworks.com/software/ee/cp_jquery/">jQuery for the Control Panel</a> extension (bundled with the latest versions of EE).</p>
<p>You&#8217;ll notice it at work on the &#8220;Edit&#8221; screen. Out-of-the-box EE requires you to first select a search criteria from one of the dropdown menus and then click &#8220;Search.&#8221; With the Edit Tab extension enabled, all you have to do is <strong>select an option</strong> from the dropdown menu and the results are loaded below, <strong>without a page refresh</strong>.</p>
<div id="attachment_200" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-200" title="Edit Tab AJAX in action on the Edit screen" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_ajax.png" alt="Look ma, no refresh!" width="490" height="260" /><p class="wp-caption-text">Look ma, no refresh!</p></div>
<p>This might not seem like a big deal, but cutting out that extra page refresh on every search can save a bundle of time. The only downside: if you edit an entry, then click &#8220;back,&#8221; you&#8217;ll lose your initial search results.</p>
<h2>2. Playa <a href="http://brandon-kelly.com/apps/playa/">(download)</a></h2>
<p>One glaring limitation of EE&#8217;s custom fields is that <strong>you&#8217;re limited to a &#8220;one-to-one&#8221; comparison</strong> when relating entries.</p>
<p>For example, let&#8217;s say you have a &#8220;Featured Products&#8221; weblog, and you&#8217;d like to associate multiple products with a single &#8220;Featured Products&#8221; entry. Natively, you can&#8217;t — you&#8217;d have to create three separate weblog entries.</p>
<p>Enter Playa. <strong>Playa allows for a &#8220;one-to-many&#8221; comparison</strong>, so you can associate as many items as you want with a single weblog entry.</p>
<div id="attachment_198" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-198" title="Playa allows you to make many-to-many relationships with your weblog entries" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_playa.png" alt="Using Playa to associate a single weblog entry with several related entries" width="490" height="244" /><p class="wp-caption-text">Using Playa to associate a single weblog entry with several related entries</p></div>
<h2>3. Redirect After Login <a href="http://www.twomile.com/services/add-on/expression-engine-redirect-after-login">(download)</a></h2>
<p>This extension allows you to show or hide the default (read: ugly) login and logout screens, and to redirect your users to URLs of your choice after login and logout. This can come in very handy if you use EE to manage non-admin user accounts.</p>
<p>With this extension, you can easily redirect a user to his or her profile page after login.</p>
<div id="attachment_188" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-188" title="The Login Redirect settings screen" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_login-redirect.png" alt="The settings screen for the Redirect After Login extension" width="490" height="262" /><p class="wp-caption-text">The settings screen for the Redirect After Login extension</p></div>
<h2>4. MD Character Count <a href="http://www.masugadesign.com/the-lab/scripts/md-character-count/">(download)</a></h2>
<p>I came across this extension while looking for a way to show one of our clients how much space was left in a given field. This extension (one of my favorites) allows you to <strong>limit the number of characters in any of your custom fields</strong> (input or text area, of course). You can even control the message that appears below each field.</p>
<div id="attachment_189" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-189" title="MD Character Count gives you fine-tuned control over your custom fields" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_charcount.png" alt="You can specify different counts, count types, and messages for every custom field (text input or textarea) across all of your weblogs" width="490" height="170" /><p class="wp-caption-text">MD Character Count lets you specify different counts, count types, and messages for every custom field (text input or textarea) across all of your weblogs.</p></div>
<p>One nice feature is that you can specify a &#8220;hard&#8221; count (i.e., you absolutely <em>can&#8217;t</em> go over the specified number of characters) or a &#8220;soft&#8221; count (i.e., you <em>can </em>go over the specified limit, but you&#8217;ll get a visual cue that you&#8217;ve done so):</p>
<div id="attachment_190" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-190" title="A textarea field with a &quot;hard&quot; count" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_charcount-hard.png" alt="The character limit and characters remaining will appear below each field you specify" width="490" height="200" /><p class="wp-caption-text">The character limit and characters remaining will appear below each field you specify</p></div>
<div id="attachment_191" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-191" title="An example of a &quot;soft&quot; count type" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_charcount-soft.png" alt="If you specify a &quot;soft&quot; count type, you'll get a visual cue if you go over the limit" width="490" height="200" /><p class="wp-caption-text">If you specify a&quot;soft&quot; count type, you&#39;ll get a visual cue when you go over the limit</p></div>
<p>The only downside is that this extension doesn&#8217;t work with WYSIWYG fields.</p>
<h2>5. Gypsy <a href="http://brandon-kelly.com/apps/gypsy">(download)</a></h2>
<p>Gypsy eliminates the need to create custom field groups, and instead allows you to assign custom fields directly to whichever weblogs you choose.</p>
<div id="attachment_195" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-195" title="Creating a Gypsy field" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_gypsy.png" alt="You can elect whether or not to make a custom field a &quot;Gypsy&quot; field" width="490" height="290" /><p class="wp-caption-text">You can elect whether or not to make a custom field a &quot;Gypsy&quot; field</p></div>
<p>It&#8217;s incredibly useful for those times you need to reuse custom fields. If you have just <strong>one </strong>custom field that is different between two weblogs, regular EE requires you to create two field groups and duplicate most of the custom fields for the second group.</p>
<p>With Gypsy, <strong>you only need to worry about the fields, not the groups</strong>.</p>
<h2>6. Live Look <a href="http://leevigraham.com/cms-customisation/expressionengine/lg-live-look/">(download)</a></h2>
<p>If you&#8217;ve ever wondered why EE includes a &#8220;Preview&#8221; feature, know that you were not alone. Live Look enables accurate, live previews of your weblog entries from within the control panel.</p>
<div id="attachment_196" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-196" title="Live Look in action inside the control panel" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_live-look.png" alt="Live Look resides in a separate tab within the Publish Form" width="490" height="300" /><p class="wp-caption-text">I once was blind...but now I see</p></div>
<p>This extension is particularly valuable for clients, who appreciate seeing what their entries will <em>actually</em> look like before they go live.</p>
<h2>7. LG Data Matrix <a href="http://leevigraham.com/cms-customisation/expressionengine/lg-data-matrix/">(download)</a></h2>
<p>[[<strong>UPDATE 5 May 09:</strong> Brandon Kelly recently released an updated version of LG Data Matrix called <a href="http://wiki.github.com/brandonkelly/bk.fieldframe.ee_addon/ff-matrix">FF Matrix</a>. Unlike Data Matrix (which restricts you to certain field types), FF Matrix allows you to create custom field types. You can also easily convert your Data Matrix fields to FF Matrix fields.]]</p>
<p>This extension is a real life-saver, because it addresses a major shortcoming of EE: if you want to enter varying amounts of information for a custom field, you have to do one of two things:</p>
<ol>
<li>Create more custom fields</li>
<li>Create a new weblog and set up a relationship</li>
</ol>
<p>Let&#8217;s say you want to enter multiple tasks for a particular project. Normally, you&#8217;d set up a custom field named <strong>tasks </strong>and assign it to a weblog named <strong>projects</strong>. Then, you&#8217;d set the custom field to be a textarea, and enter all of your tasks in a big chunk.</p>
<p>But what if you want to associate more information with each task, like the date the task is due or to whom the task is assigned? If you&#8217;re like me, you hate &#8220;chunking&#8221; everything inside a textarea. It&#8217;s harder to format and rearrange data within a textarea, and it&#8217;s harder to read.</p>
<p>It would be nice if you could add and remove tasks without creating separate custom fields or an entirely separate &#8220;tasks&#8221; weblog.</p>
<p>That&#8217;s where LG Data Matrix comes in. With this extension, I can create a single &#8220;tasks&#8221; custom field, then create what are essentially <strong>sub-fields </strong>on the fly, as I need them.</p>
<div id="attachment_199" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-199" title="Data Matrix at work within the control panel" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_matrix.png" alt="This extension will change how you work with EE custom fields - note the icons for adding, removing, and rearranging your sub-fields" width="490" height="162" /><p class="wp-caption-text">This extension will change how you work with EE custom fields. Note the icons for adding, removing, and rearranging your sub-fields</p></div>
<h3><a href="http://www.masugadesign.com/the-lab/scripts/md-live-search/"></a></h3>
<h2>8. Cloner <a href="http://expressionengine.com/downloads/details/cloner/">(download)</a></h2>
<p>Cloner is a neat extension that can come in handy if you ever need to duplicate an entry.</p>
<div id="attachment_201" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-201" title="Cloner's extension settings" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_clone-settings.png" alt="Cloner allows you to specify a suffix for the cloned entry's title and URL title." width="490" height="200" /><p class="wp-caption-text">Cloner lets you specify a suffix to differentiate the cloned entry from the original</p></div>
<div id="attachment_202" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-202" title="Clone entries from the Edit screen" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_clone.png" alt="You can clone single" width="490" height="280" /><p class="wp-caption-text">You can clone entries one-at-a-time from the &quot;Edit&quot; screen</p></div>
<h2>9. File <a href="http://docs.markhuot.com/ee/extensions/file">(download)</a></h2>
<p>Anyone who has used EE knows that the built-in file upload functionality isn&#8217;t very user friendly. Mark Huot created <strong>File</strong> to make it easier to upload files using EE&#8217;s control panel.</p>
<p>File allows you to designate a custom field as a &#8220;File&#8221; type, which replaces the standard text input with a more user-friendly &#8220;Browse&#8221; button:</p>
<div id="attachment_204" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-204" title="My custom field after uploading two images and clicking Quick Save" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_file.png" alt="My custom field after uploading two images and clicking Quick Save" width="490" height="294" /><p class="wp-caption-text">My custom field after selecting two images and clicking &quot;Quick Save.&quot; I have enabled multiple uploads and thumbnails via Admin › Weblog Admin › File Upload Prefs</p></div>
<p>It would be nice if there were an upload button, since the extension requires you to quick save or submit before the files are uploaded. Otherwise, it&#8217;s stellar.</p>
<h2>10. MD Add Sitename <a href="http://masugadesign.com/the-lab/scripts/add-sitename/">(download)</a></h2>
<p>I wanted to include Masuga Design&#8217;s <a href="http://www.masugadesign.com/the-lab/scripts/md-live-search/">Live Search extension</a> here, but couldn&#8217;t get the latest version to work with my install. The screenshots and description alone had me sold.</p>
<p>This little extension is nonetheless very useful, especially for those developers who work with more than one EE site at a time. Once enabled, you will see the name of your site in the top left. Manipulating the font face, size, weight, color, and padding is a snap. You can also customize the site name if you don&#8217;t like the default.</p>
<div id="attachment_206" class="wp-caption aligncenter" style="width: 500px"><img class="size-full wp-image-206" title="Once enabled, your site's name will appear in the top left" src="http://www.3roadsmedia.com/blog/wp-content/uploads/2009/02/ee_sitename.png" alt="Once enabled, your site's name will appear in the top left" width="490" height="94" /><p class="wp-caption-text">Once enabled, your site&#39;s name will appear in the top left</p></div>
<p>Granted, the site name will be included in the forthcoming EE 2.0 release, but for the time being this is a good addition to your extensions arsenal.</p>
<p>Are there other EE extensions that you know and love? Feel free to share!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3roadsmedia.com/blog/10-useful-expressionengine-extensions/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>
