<?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>Monday By Noon &#187; WordPress</title>
	<atom:link href="http://mondaybynoon.com/category/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://mondaybynoon.com</link>
	<description>A resource for Web designers and developers to read about and discuss their craft.</description>
	<lastBuildDate>Mon, 06 Sep 2010 18:50:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>WordPress Archive Pages Based on Custom Taxonomy</title>
		<link>http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/</link>
		<comments>http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 17:25:56 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Custom Post Types]]></category>
		<category><![CDATA[permalinks]]></category>
		<category><![CDATA[rewrite]]></category>
		<category><![CDATA[slug]]></category>
		<category><![CDATA[Taxonomies]]></category>
		<category><![CDATA[taxonomy]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1253</guid>
		<description><![CDATA[Customizing and segmenting Custom Taxonomy archive pages can be a bit difficult until you determine what exactly is going on under the hood and implementing from there. Custom Taxonomies in WordPress are a very powerful feature, let's figure out how to make some nice looking archive pages for them.]]></description>
			<content:encoded><![CDATA[<p class="update"><strong>Note:</strong> This article is an extension of <a href="http://mondaybynoon.com/2010/09/06/custom-post-types-taxonomies-permalinks-wordpress/">Custom Post Types, Custom Taxonomies, and Permalinks in WordPress 3.0</a> which discusses the Custom Post Type and Custom Taxonomy implementation we&#8217;ve setup thus far. While a summary is offered here, please know that some details discussed herein reflect the <a href="http://mondaybynoon.com/2010/09/06/custom-post-types-taxonomies-permalinks-wordpress/">implementation discussed previously</a>.</p>
<p>In order to set up front end visible archive pages for Custom Taxonomies, everything begins with the rewrite slug attached to your Custom Taxonomy. This can be edited using the Custom Rewrite Slug field provided by <a href="http://wordpress.org/extend/plugins/custom-post-type-ui/">Custom Post Type UI</a>. Some planning is required on your part, but the plan must take into consideration the Page structure currently implemented.</p>
<p>So far, we&#8217;ve based our Cameras Custom Post Type on the slug of <code>/cameras/</code>. This works out well as our Custom Post Type houses information based on DSLR Cameras. We&#8217;ve set up an index-style page that sits at <code>/cameras/</code>, and our single pages are stored under <code>/cameras/%postname%/</code>. We&#8217;ve just now included a Custom Taxonomy, and we&#8217;d like to include that in the mix as well.</p>
<h2>Out of the box taxonomy permalinks</h2>
<p>By default, a Custom Taxonomy rewrite slug is based on the Taxonomy Name. Considering our Brands Custom Taxonomy, we might expect the Taxonomy listing would be made available at <code>/cameras/brands/%taxonomyname%/</code>; unfortunately that&#8217;s not the case. Given the Taxonomy being a default implementation, we&#8217;d actually find the listing at <code>/brands/%taxonomyname%/</code>. You&#8217;ll also note that any Cameras we&#8217;ve marked under a particular brand will show up in the listing. For example, if we navigated to <code>http://wordpress/cpt/brands/canon/</code>, we&#8217;d be faced with a page resembling:</p>
<p><img class="alignnone size-full wp-image-1256" title="01-default-listing" src="http://mondaybynoon.com/wp-content/uploads/2010/09/01-default-listing.jpg" alt="Default post listing based on taxonomy" width="1020" height="1130" /></p>
<p>This listing behaves just like a regular Posts archive page would, and that&#8217;s because it&#8217;s literally based on the <code>archive.php</code> template file of your theme. While it works, it&#8217;s not ideal. Thinking ahead, if you have multiple Custom Post Types along with WordPress posts, there isn&#8217;t much segmentation when it comes to actually viewing archive pages on the front end.</p>
<p>Take into consideration the possibility of us expanding our content by also including a Custom Post Type for Flashes. If we were to use a Custom Taxonomy for Flash Brands (as opposed to Camera Brands) with that Custom Post Type as well, we&#8217;d have overlapping entries and it would quickly become unorganized as results for both flashes and cameras would turn up when viewing <code>http://wordpress/cpt/brands/canon/</code> which isn&#8217;t always desirable.</p>
<p>At this point it&#8217;s important to note the specificity of a Custom Post Type/Custom Taxonomy implementation. There is a strong possibility that you very well may want to merge Canon flashes and cameras in your archive pages, but you may not. For the purpose of example, we&#8217;re going to deem it necessary to segment the two. To accomplish that, you&#8217;ll need to beef up the rewrite slug for your Custom Taxonomies.</p>
<h2>Customizing your Custom Taxonomy template</h2>
<p>When dealing with taxonomies, WordPress looks for specific theme files. As with other theme files, templates for Custom Taxonomies can be based on the taxonomy name, in this case <code>brands</code>. Create a file called <code>taxonomy-brands.php</code> in your theme directory, WordPress checks for this file before hitting <code>archive.php</code> which can allow you to make the front end more custom. As an example, we&#8217;ll use the following for our <code>taxonomy-brands.php</code>:</p>
<pre class="sh_php"><code>&lt;?php get_header(); ?&gt;

  &lt;?php $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); ?&gt;
  &lt;div id="container"&gt;
    &lt;div id="content" role="main"&gt;

      &lt;h1 class="page-title"&gt;&lt;?php echo $term-&gt;name; ?&gt; Archives&lt;/h1&gt;

      &lt;?php if (have_posts()) : ?&gt;
        &lt;?php while (have_posts()) : the_post(); ?&gt;

          &lt;div class="post type-post hentry"&gt;
            &lt;h2 class="entry-title"&gt;
              &lt;a href="&lt;?php echo get_permalink(); ?&gt;" title="&lt;?php the_title(); ?&gt;" rel="bookmark"&gt;
                &lt;?php the_title(); ?&gt;
              &lt;/a&gt;
            &lt;/h2&gt;

            &lt;div class="entry-meta"&gt;
              &lt;span class="meta-prep meta-prep-author"&gt;Posted on&lt;/span&gt;
              &lt;a href="&lt;?php echo get_permalink(); ?&gt;" title="&lt;?php the_time( 'g:i a' ); ?&gt;" rel="bookmark"&gt;
              &lt;span class="entry-date"&gt;&lt;?php the_time( 'F j, Y' ); ?&gt;&lt;/span&gt;&lt;/a&gt;
            &lt;/div&gt;&lt;!-- .entry-meta --&gt;

            &lt;div class="entry-summary"&gt;
              &lt;?php the_excerpt(); ?&gt;
            &lt;/div&gt;&lt;!-- .entry-summary --&gt;
          &lt;/div&gt;

        &lt;?php endwhile; ?&gt;
      &lt;?php endif; ?&gt;

    &lt;/div&gt;&lt;!-- #content --&gt;
  &lt;/div&gt;&lt;!-- #container --&gt;

  &lt;?php get_sidebar(); ?&gt;
&lt;?php get_footer(); ?&gt;</code></pre>
<p>This file is based on <code>category.php</code> with a few modifications. First is the call to <code>get_term_by()</code> which uses <code>get_query_var()</code> to determine what Custom Taxonomy term we&#8217;re working with. From there, we carry on through The Loop as normal, outputting the information we&#8217;d like to use and where.</p>
<p>The only lasting problem here, is the fact that we&#8217;re still sitting at <code>http://wordpress/cpt/brands/canon/</code>. I&#8217;d much rather have this page available at <code>http://wordpress/cpt/<strong>cameras</strong>/brands/canon/</code> as to differentiate it from other Custom Post Types and their Custom Taxonomies.</p>
<h2>Correctly identifying your rewrite slug</h2>
<p><a href="http://wordpress.org/extend/plugins/custom-post-type-ui/">Custom Post Type UI</a> makes it really easy to modify our Custom Rewrite Slug, which controls this change entirely. As mentioned earlier, a rewrite slug, unless otherwise defined, is based on the Custom Taxonomy name itself, hence our current <code>/brands/%taxonomyname%/</code> result. We simply need to change our Custom Rewrite Slug to include the URL structure we&#8217;re looking for, in this case <strong>cameras/brands</strong>:</p>
<p><img class="alignnone size-full wp-image-1257" title="02-new-slug" src="http://mondaybynoon.com/wp-content/uploads/2010/09/02-new-slug.jpg" alt="Refining the slug used for a taxonomy archive page" width="393" height="221" /></p>
<p>Saving the change to our Custom Taxonomy rewrite slug will push the permalink change and we&#8217;ll finally be able to hit our more appropriate <code>http://wordpress/cpt/<strong>cameras</strong>/brands/canon/</code> URL, right? <strong>Not quite</strong>. It turns out that if we hit <code>http://wordpress/cpt/cameras/brands/canon/</code> WordPress thinks we&#8217;re trying to hit a single post from our Cameras Custom Post Type and redirects us to the closest match.</p>
<p>In order to get our final archives-style pages to load properly, we&#8217;re going to have to modify our Custom Post Type Custom Rewrite Slug to differentiate a request for a single post entry versus our archive-style pages. To do that, we&#8217;ll need to change the slug from <code>cameras</code> to something more appropriate like <code>cameras/body</code> which could signify that we&#8217;re viewing a camera body.</p>
<p>With that change in place, we&#8217;re in business! We&#8217;re now able to hit <code>http://wordpress/cpt/cameras/brands/canon/</code> and view the Posts that have been marked as Canon Posts, using our custom permalink as well as our custom template file. You can repeat this process with additional taxonomies by creating appropriate rewrite slugs in conjunction with new <code>taxonomy-%taxonomyname%.php</code> template files.</p>
<h2>Adding links to Taxonomy archives in the sidebar</h2>
<p>Many of the WordPress-native functions can be adapted for use with Custom Post Types and Custom Taxonomies. To add links to your newly created Custom Taxonomy archive pages, you could add something like this snippet to your <code>sidebar.php</code>:</p>
<pre class="sh_php"><code>&lt;li id="camera-brands" class="widget-container"&gt;
  &lt;h3 class="widget-title"&gt;Camera Brands&lt;/h3&gt;
  &lt;?php $cam_brands = get_terms('brands', 'hide_empty=1'); ?&gt;
  &lt;ul&gt;
    &lt;?php foreach( $cam_brands as $brand ) : ?&gt;
      &lt;li&gt;
        &lt;a href="&lt;?php echo get_term_link( $brand-&gt;slug, 'brands' ); ?&gt;"&gt;
          &lt;?php echo $brand-&gt;name; ?&gt;
        &lt;/a&gt;
        &lt;ul&gt;
          &lt;?php
            $wpq = array( 'post_type' =&gt; 'cameras', 'taxonomy' =&gt; 'brands', 'term' =&gt; $brand-&gt;slug );
            $brand_posts = new WP_Query ($wpq);
          ?&gt;
          &lt;?php foreach( $brand_posts-&gt;posts as $post ) : ?&gt;
            &lt;li&gt;
              &lt;a href="&lt;?php echo get_permalink( $post-&gt;ID ); ?&gt;"&gt;
                &lt;?php echo $post-&gt;post_title; ?&gt;
              &lt;/a&gt;
            &lt;/li&gt;
          &lt;?php endforeach ?&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;?php endforeach ?&gt;
  &lt;/ul&gt;
&lt;/li&gt;</code></pre>
<p>While a bit of the markup is specific to Twenty Ten&#8217;s <code>sidebar.php</code> we can dissect what&#8217;s going on here:</p>
<ol>
<li>Pull our brands</li>
<li>Create a list item for our brand</li>
<li>Pull all posts that have been marked as being that brand (via the <code>taxonomy</code> and <code>term</code> arguments)</li>
<li>Loop through each post within that defined Custom Taxonomy entry and dump out what we&#8217;d like to use</li>
<li>Repeat until finished with all Custom Taxonomy entries</li>
</ol>
<p>When incorporated into the sidebar, we&#8217;ll get something like this:</p>
<p><img class="alignnone size-full wp-image-1258" title="03-sidebar" src="http://mondaybynoon.com/wp-content/uploads/2010/09/03-sidebar.jpg" alt="Customized sidebar based on Custom Post Types and Custom Taxonomies" width="228" height="440" /></p>
<p>As you can imagine, that sidebar listing would quickly grow to an unmanageable size, but the example illustrates just what&#8217;s possible using a few WordPress native functions and your Custom Post Types/Custom Taxonomies.</p>
<h3>Custom Post Types and Custom Taxonomies are powerful</h3>
<p>These changes in WordPress 3.0 are more than welcome, as they&#8217;re going to set the stage for much more <strong>traditional</strong> CMS-like behavior. The implementation discussed in this short series of articles is quite specific but hopefully outlines one of the many ways to work with Custom Post Types and Custom Taxonomies, all the while keeping a prettier permalink structure throughout your sites.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom Post Types, Custom Taxonomies, and Permalinks in WordPress 3.0</title>
		<link>http://mondaybynoon.com/2010/09/06/custom-post-types-taxonomies-permalinks-wordpress/</link>
		<comments>http://mondaybynoon.com/2010/09/06/custom-post-types-taxonomies-permalinks-wordpress/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 15:54:48 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Custom Post Types]]></category>
		<category><![CDATA[Taxonomies]]></category>
		<category><![CDATA[WordPress 3.0]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1236</guid>
		<description><![CDATA[Custom Post Types are a huge boon to everything WordPress. The feature has been long awaited, and lays a nice foundation for WordPress becoming more of a CMS to those still convinced it's merely a blogging engine.]]></description>
			<content:encoded><![CDATA[<p><a href="http://codex.wordpress.org/Custom_Post_Types">Custom Post</a> Types are a <em>huge</em> boon to everything WordPress. The feature has been long awaited, and lays a nice foundation for WordPress becoming more of a <abbr title="Content Management System">CMS</abbr> to those still convinced it&#8217;s <strong>merely a <em>blogging</em> engine</strong>.</p>
<p>Custom Post Types, for those not familiar, is basically a templated content type based at their core off of WordPress&#8217; Posts. There are a number of optional fields you can include within a Custom Post Type, and you can also build in your own. It opens the door to building a refined UI for data storage within WordPress given custom circumstances.</p>
<p>That said, you may be curious how that effects other systems such as <a href="http://podscms.org/">Pods</a>. If you haven&#8217;t had a chance, I <a href="http://mondaybynoon.com/2010/05/31/wordpress-custom-post-types-pods/">discussed WordPress 3.0 and Pods</a> in detail and have concluded that Custom Post Types and Pods achieve different goals at this point, and working with Pods gives you a level of control Custom Post Types currently do not (and in part do not strive to) achieve.</p>
<p>As full disclosure, I&#8217;ve recently been accepted as a <a href="http://podscms.org/about/">Pods Core Developer</a> but hope to express that circumstance having no effect or any biased opinions toward Custom Post Types. The Pods team wouldn&#8217;t exist without WordPress, and we&#8217;re all <em>super thrilled</em> about the existence of Custom Post Types.</p>
<p>In this walkthrough, I&#8217;d like to cover a fully top-to-bottom implementation of Custom Post Types, specifically targeting the task of ensuring a pretty permalink structure for your <code>single</code> pages. A follow-up article will take into consideration custom taxonomies for archive-style pages.</p>
<h2>Up and running with Custom Post Types</h2>
<p>Perhaps the biggest outstanding learning curve with Custom Post Types is the implementation itself. While programmers will love it, less experienced theme developers are likely to become quickly frustrated with the initial setup of Custom Post Types. While there is a lot of information in the always useful Codex, Custom Post Types still require an understanding of WordPress established conventions for implementation.</p>
<p>I&#8217;m a stickler for understanding the ins and outs of a system in which you work professionally, but I also understand that WordPress is a fantastic platform for tinkering. That said, if you&#8217;re a professional you&#8217;re looking to save as much time as possible. If you&#8217;re a tinkerer you&#8217;re looking to get up and running as quickly as possible so (hopefully) you can dissect how it happened. Given that, a really nice way to rapidly set up your Custom Post Types is the <a href="http://wordpress.org/extend/plugins/custom-post-type-ui/">Custom Post Type UI</a> WordPress plugin. Custom Post Type UI completely removes the tediousness of setting up Custom Post Types by providing an interface within the WordPress admin to do so. I&#8217;ve been using it on all of my recent projects and it&#8217;s a <em>huge</em> time saver. I do recommend though, that prior to using the plugin, you take the time to really understand what Custom Post Types are and how they fit into the big picture.</p>
<p>For the purposes of this walkthrough, we&#8217;ll set up an informational DSLR site with some information about a few cameras. Using Custom Post Type UI, we&#8217;ll set up a Cameras Custom Post Type:</p>
<p><img class="alignnone size-full wp-image-1237" title="01-initial-setup" src="http://mondaybynoon.com/wp-content/uploads/2010/09/01-initial-setup.jpg" alt="Initial setup of the Custom Post Type" width="469" height="541" /></p>
<p>While you can create a Custom Post Type filling out just the fields above, we&#8217;re working for a full implementation here, so we&#8217;re going to fill in the Advanced Label Options too:</p>
<p><img class="alignnone size-full wp-image-1238" title="02-label-options" src="http://mondaybynoon.com/wp-content/uploads/2010/09/02-label-options.jpg" alt="Setting label options" width="472" height="718" /></p>
<p>If these fields are not populated, defaults will be used based on the initial labels used to set up the Custom Post Type. In this particular case, using those defaults would have worked out just fine, but there will be circumstances where a revised nomenclature will be much more meaningful to clients.  We&#8217;re also going to customize the Advanced Options offered by Custom Post Types/Custom Post Types UI:</p>
<p><img class="alignnone size-full wp-image-1239" title="03-advanced-options" src="http://mondaybynoon.com/wp-content/uploads/2010/09/03-advanced-options.jpg" alt="Setting Advanced Options" width="454" height="619" /></p>
<p>Using these fields we&#8217;re able to further refine the attributes of our Custom Post Type. Many of these can be left as default, but we&#8217;ll pay particular attention to both the Custom Rewrite Slug as well as the Supports areas. Built-in Taxonomies are also important, but we&#8217;re going to revisit that later. The Custom Rewrite Slug is responsible for ensuring your permalink structure remains accurate and in tact. More on that during implementation.  Now that our options are set, clicking <strong>Create Custom Post Type</strong> will add our Custom Post type to the admin UI:</p>
<p><img class="alignnone size-full wp-image-1240" title="04-ui" src="http://mondaybynoon.com/wp-content/uploads/2010/09/04-ui.jpg" alt="Custom Post Type in the admin UI" width="149" height="224" /></p>
<p>Adding a new entry will provide a familiar, but customized content entry view:</p>
<p><img class="alignnone size-full wp-image-1241" title="05-add-new" src="http://mondaybynoon.com/wp-content/uploads/2010/09/05-add-new.jpg" alt="Adding a new Camera" width="971" height="756" /></p>
<p>Once we&#8217;ve added some entries, we&#8217;ll begin building our library of content:</p>
<p><img class="alignnone size-full wp-image-1242" title="06-content-list" src="http://mondaybynoon.com/wp-content/uploads/2010/09/06-content-list.jpg" alt="Content added to Custom Post Type" width="983" height="507" /></p>
<p>With Custom Post Types comes all of the built in content management functionality of WordPress, but at this point, we&#8217;ve got nothing to show for it within our theme; these pages are nowhere in sight on the front end. Our first option could be to use WordPress 3.0 Menus and manually build out a navigation system with a series of Custom Links, but that would quickly become overbearing given the fact that we&#8217;re hoping to build a website with hundreds (or thousands) of content pages.</p>
<h2>Structuring WordPress for Custom Post Types</h2>
<p>Custom Post Types are just that, they&#8217;re a collection of content. For the sake of organization as well as user experience, there should be some sort of hierarchy that incorporates your Custom Post Types. Currently, if you were to hit one of our Camera pages using the Permalink outlined on the edit page, you&#8217;d see the content included in the post:</p>
<p><img class="alignnone size-full wp-image-1243" title="07-view" src="http://mondaybynoon.com/wp-content/uploads/2010/09/07-view.jpg" alt="Viewing an entry" width="663" height="128" /></p>
<p><img class="alignnone size-full wp-image-1244" title="08-stock-page" src="http://mondaybynoon.com/wp-content/uploads/2010/09/08-stock-page.jpg" alt="Custom Post on the front end" width="1020" height="1222" /></p>
<p>For the purpose of this example, the permalink we&#8217;re working with is <code>http://wordpress/cpt/cameras/canon-7d/</code> which is just fine; I like the way it&#8217;s structured. The trouble creeps in when, by experience, we want to view an index page by stripping off the last URL segment and trying to hit <code>http://wordpress/cpt/cameras/</code>. Out of the box we&#8217;re slammed with a <code>404</code> error. As a fix, I&#8217;d suggest creating a WordPress Page called Cameras (with the proper slug) to ensure we no longer hit that <code>404</code>.</p>
<p>This ties into my philosophy of structuring WordPress sites; WordPress Pages should dictate the overall structure (for both content and URLs) and be the foundation of everything built on top of it. To our benefit, Custom Post Types work within thsi philosophy.</p>
<p>With our <code>http://wordpress/cpt/cameras/</code> URL now properly resolving, we could create a custom Page template to pull in all of our Cameras. There are two approaches here, you can either set the Page Template in the Page Attributes sidebar on the edit screen, or simply name your template file using the Page slug. We&#8217;ll take the latter approach and create a new file within our theme directory called <code>page-cameras.php</code> consisting of:</p>
<pre class="sh_php sh_html"><code>&lt;?php

/* Template Name: Cameras index */

get_header(); ?&gt;

  &lt;div id="container"&gt;
    &lt;div id="content" role="main"&gt;

      &lt;?php
        query_posts( 'post_type=cameras' );
        get_template_part( 'loop' ); // looks for loop.php which is specific to Twenty Ten
        wp_reset_query();
      ?&gt;

    &lt;/div&gt;&lt;!-- #content --&gt;
  &lt;/div&gt;&lt;!-- #container --&gt;

  &lt;?php get_sidebar(); ?&gt;

&lt;?php get_footer(); ?&gt;</code></pre>
<p><strong>Note:</strong> The call <code>get_template_part()</code> looks for <code>loop.php</code>, a template file specific to Twenty Ten, the stock theme that ships with WordPress 3.0</p>
<p>What we&#8217;re doing in this template is simply querying all posts for our <code>cameras</code> Custom Post Type and sending that data to The Loop. Last, we reset to the original query fired during page creation which will prevent any funkyness with sidebar and/or footer logic. What results is a page that mimics a default Posts entry view in Twenty Ten:</p>
<p><img class="alignnone size-full wp-image-1245" title="09-cameras" src="http://mondaybynoon.com/wp-content/uploads/2010/09/09-cameras.jpg" alt="Cameras index page" width="1020" height="4897" /></p>
<p>While the implementation so far is great for including the data stored in our Custom Post Type, it&#8217;s not very organized.</p>
<h2 id="custom-taxonomies">Organizing Custom Post Type data using a Custom Taxonomy</h2>
<p>Closely related to Custom Post Types are Custom Taxonomies. To our benefit, the <a href="http://wordpress.org/extend/plugins/custom-post-type-ui/">Custom Post Type UI</a> plugin handles the creation and maintenance of Custom Taxonomies as well. We&#8217;re going to organize our Cameras Custom Post Type by attaching a few Taxonomies:</p>
<p><img class="alignnone size-full wp-image-1246" title="10-taxonomy-brand" src="http://mondaybynoon.com/wp-content/uploads/2010/09/10-taxonomy-brand.jpg" alt="Taxonomy setup" width="406" height="377" /></p>
<p><img class="alignnone size-full wp-image-1247" title="11-taxonomy-price-range" src="http://mondaybynoon.com/wp-content/uploads/2010/09/11-taxonomy-price-range.jpg" alt="Taxonomy settings" width="406" height="377" /></p>
<p>When creating them, we&#8217;ve attached the Taxonomies to our Custom Post Type, and they now show up as expected:</p>
<p><img class="alignnone size-full wp-image-1248" title="12-taxonomy-ui" src="http://mondaybynoon.com/wp-content/uploads/2010/09/12-taxonomy-ui.jpg" alt="Custom Taxonomies in the UI" width="154" height="270" /></p>
<p>Out of the box, Custom Taxonomies behave like tags. Depending on how you&#8217;d like to use your Taxonomy, tags might be an applicable solution. In this case, however, I&#8217;d like to offer a choice-based system for my client. To do that, and therefore make your Taxonomy behave more like a WordPress Category, you&#8217;ll need to edit the Advanced Options of the Taxonomy:</p>
<p><img class="alignnone size-full wp-image-1249" title="13-hierarchical" src="http://mondaybynoon.com/wp-content/uploads/2010/09/13-hierarchical.jpg" alt="Hierarchy option" width="401" height="239" /></p>
<p>By setting your Taxonomy to being hierarchical you&#8217;ll provide a listing of all existing entries as well as a check/uncheck interaction:</p>
<p><img class="alignnone size-full wp-image-1250" title="14-taxonomies" src="http://mondaybynoon.com/wp-content/uploads/2010/09/14-taxonomies.jpg" alt="Taxonomies" width="291" height="652" /></p>
<p>As with most things Custom Post Type, while you&#8217;re able to add/edit/remove the data, it doesn&#8217;t do much out of the box on the front end. Viewing the Canon 7D page we just edited on the front end results in no visible change. We&#8217;re going to use our Custom Taxonomy to provide category-style archive listings.</p>
<h3>The end of the basics</h3>
<p>This walkthrough sets the stage for the more difficult task of <a href="http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/">setting up Custom Taxonomy-based archive-style pages using appropriate permalinks</a>. If you&#8217;d like to take the next step in pushing your Custom Taxonomies to the front end of your site check out <a href="http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/">WordPress Archive Pages Based on Custom Taxonomies</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/09/06/custom-post-types-taxonomies-permalinks-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress Custom Post Types &amp; PHPurchase: Best Cart Ever – Part 2</title>
		<link>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-2/</link>
		<comments>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-2/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 05:28:09 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Favorites]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Workbench]]></category>
		<category><![CDATA[Custom Post Types]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[PHPurchase]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1197</guid>
		<description><![CDATA[After discussing the benefits of using WordPress 3.0+, Custom Post Types, and PHPurchase over other available e-commerce solutions, this article will walk you through the installation of PHPurchase and integration with Custom Post Types for your product listings.]]></description>
			<content:encoded><![CDATA[<p class="update">If you haven&#8217;t read <a href="http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-1/">part 1</a> I took some time to outline why I feel that the combination of PHPurchase and Custom Post Types can result in the best e-commerce solution for WordPress.</p>
<p>In <a href="http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-1/">part 1</a> I examined the current WordPress cart plugin landscape and outlined a number of reasons I feel that <a href="http://www.phpurchase.com/">PHPurchase</a> is currently the leading solution for an e-commerce solution, especially with the arrival of Custom Post Types. I&#8217;d like to share how and why using Custom Post Types works so well for a WordPress shopping cart.</p>
<h2>Setting up and prepping WordPress</h2>
<p>The first step will be to get your WordPress 3.0+ install up and running. That&#8217;s the extent of detail we&#8217;ll cover there. The next step will be to obtain and install a copy of <a href="http://www.phpurchase.com/">PHPurchase</a>. There are a number of purchase options available, but this walkthrough will cover functionality available under all licenses of PHPurchase.</p>
<p>The installation of PHPurchase is as straightforward as any other plugin. Once you&#8217;ve uploaded the plugin files and activated the plugin, you&#8217;ll need to enter your PHPurchase order number on the Settings screen:</p>
<p><img class="alignnone size-full wp-image-1198" title="cart.01.phpurchase.settings" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.01.phpurchase.settings.png" alt="Screenshot: PHPurchase settings" width="926" height="447" /></p>
<p>After validating your order number, the reminder to do so will disappear and you&#8217;ll be able to enter in your PayPal, Authorize.net, or Quantum Gateway payment settings. These details aren&#8217;t <em>required</em> at this point, but until that information is entered, the plugin won&#8217;t let you check out. For now, those are the only details we&#8217;ll cover as far as setup is concerned. Using the PHPurchase menu in the WordPress admin, you can begin adding products.</p>
<p><img class="alignnone size-full wp-image-1227" title="cart.02.phpurchase.add_.product.2" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.02.phpurchase.add_.product.2.png" alt="Screenshot: Adding a product to PHPurchase" width="926" height="724" /></p>
<p><img class="alignnone size-full wp-image-1200" title="cart.03.phpurchase.products" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.03.phpurchase.products.png" alt="Screenshot: PHPurchase product listing" width="953" height="245" /></p>
<p>As it stands PHPurchase will automatically implement a number of system Pages it will use to handle the cart view and checkout process for purchases.</p>
<p><img class="alignnone size-full wp-image-1202" title="cart.04.phpurchase.pages" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.04.phpurchase.pages_1.png" alt="Screenshot: PHPurchase default Pages" width="967" height="554" /></p>
<p>While these pages are an extremely important part of the overall e-commerce implementation, none of the products we just added are made available out of the box.</p>
<p><img class="alignnone size-full wp-image-1203" title="cart.05.store.no.products" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.05.store_.no_.products.png" alt="Screenshot: No products displayed in the WordPress theme" width="1128" height="842" /></p>
<p>By editing the Store page, you can quickly add a number of products using the PHPurchase icon in the editor toolbar:</p>
<p><img class="alignnone size-full wp-image-1204" title="cart.06.store.add.product.1" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.06.store_.add_.product.1.png" alt="Screenshot: Adding a product via PHPurchase, step 1" width="649" height="433" /></p>
<p><img class="alignnone size-full wp-image-1205" title="cart.07.store.add.product.2" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.07.store_.add_.product.2.png" alt="Screenshot: Adding a product via PHPurchase, step 2" width="582" height="347" /></p>
<p><img class="alignnone size-full wp-image-1206" title="cart.08.store.add.product.3" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.08.store_.add_.product.3.png" alt="Screenshot: Adding a product via PHPurchase, step 3" width="646" height="435" /></p>
<p><img class="alignnone size-full wp-image-1207" title="cart.09.store.one.product" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.09.store_.one_.product.png" alt="Screenshot: Product visible on Store page" width="1128" height="842" /></p>
<p>At this point, you can feel to proceed as normal. Using this Store page you could add every product you have available as well as apply some style and content using imagery, product copy, and links to relevant information. You could take it a step further and also create child pages with the Store as the parent and dedicate a product detail page to each of your products.</p>
<p>While helpful, you&#8217;ll quickly discover missing features that are very commonly found in other e-commerce platforms. Features such as browsing products by category and providing additional information about products in the form of multiple product shots and/or PDF downloads aren&#8217;t directly built into PHPurchase. The beauty lies in the fact that you can customize WordPress in all the usual ways to add these features as you see fit.</p>
<p>With the arrival of WordPress 3.0, however, there is an entire layer of additional functionality found in Custom Post Types that makes working with these features a breeze.</p>
<h2>Using Custom Post Types for your PHPurchase Store</h2>
<p><a href="http://codex.wordpress.org/Custom_Post_Types">Custom Post Types</a> are sometimes intimidating to more novice developers. Out of the box in WordPress 3.0 you need to manually register and set up your Custom Post Types. As with many developer-heavy tasks at hand, there is a plugin to make life easier when it comes to Custom Post Types; <a href="http://wordpress.org/extend/plugins/custom-post-type-ui/">Custom Post Type UI</a>.</p>
<p>Custom Post Type UI gives WordPress admins the ability to create, edit, and manage all of the Custom Post Types available within the WordPress Install:</p>
<p><img class="alignnone size-full wp-image-1210" title="cart.10.custom.post.type.add" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.10.custom.post_.type_.add_.png" alt="Screenshot: Adding a Custom Post via Custom Post Type UI" width="489" height="579" /></p>
<p>Using the plugin you can easily create a Custom Post Type to handle all of your product pages in PHPurchase. You&#8217;re able to customize the phrasing used throughout and viewing the Advanced Label Options gives you even more to work with. On top of these Custom Post Type Settings, you can also set up custom taxonomies which can be used in this specific case for a set of categories limited to your store products and separate from your Post categories.</p>
<p>Once you&#8217;ve created your Custom Post Type, a new menu item will be made available in the main navigation:</p>
<p><img class="alignnone size-full wp-image-1213" title="cart.11.custom.post.type.menu-1" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.11.custom.post_.type_.menu-1.png" alt="Screenshot: Custom Post Type Menu" width="156" height="334" /></p>
<p>Using the links available you can go ahead and set up your categories as well as add your products.</p>
<p><img class="alignnone size-full wp-image-1214" title="cart.12.custom.post.add.product" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.12.custom.post_.add_.product.png" alt="Screenshot: Adding a Custom Post Type product" width="949" height="775" /></p>
<p><img class="alignnone size-full wp-image-1215" title="cart.13.custom.post.products" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.13.custom.post_.products.png" alt="Screenshot: Products added to the Custom Post Type" width="953" height="457" /></p>
<p>Once your products have been added to your Custom Post Type, you can view the page on the front end:</p>
<p><img class="alignnone size-full wp-image-1216" title="cart.14.custom.product.in.theme" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.14.custom.product.in_.theme_.png" alt="Screenshot: Product page on website" width="1128" height="1745" /></p>
<h3>Integrating Custom Post Types into your Menu</h3>
<p>Now that your products have been added, you&#8217;ll want to make browsing your products as easy as possible. There are a number of things you can do, the primary two being including links to your product pages within your site navigation and using your Custom Post Type taxonomy (product categories).</p>
<p>Menus were also a big addition to WordPress in 3.0 and the update comes in handy at this point in our PHPurchase setup. The Menus are smart enough to recognize your Product Pages and allow you to integrate them directly within your site navigation:</p>
<p><img class="alignnone size-full wp-image-1217" title="cart.15.nav.menu" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.15.nav_.menu_.png" alt="Screenshot: Menus main screen" width="954" height="1054" /></p>
<p><img class="alignnone size-full wp-image-1218" title="cart.15.nav.menu.2" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.15.nav_.menu_.2.png" alt="Screenshot: Store navigation" width="647" height="695" /></p>
<p>Using the Menus you&#8217;re able to mix and match your Product Pages, your Product Categories, as well as your WordPress Pages themselves. You can custom build any structure you wish using the menus and the available entries. By default, linking to a Product Category will direct readers to pages resembling those of your other category pages, likely using category.php from your theme. You can customize this to any degree as you would normally when developing your custom WordPress theme.</p>
<p><img class="alignnone size-full wp-image-1219" title="cart.16.nav.menu.on.site" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.16.nav_.menu_.on_.site_.png" alt="Screenshot: Custom Store navigation" width="1128" height="783" /></p>
<h3>Integration with plugins</h3>
<p>Another significant advantage to using Custom Post Types and PHPurchase to power your WordPress based e-commerce website is the direct integration with many of your favorite plugins. One of the downfalls to a number of other WordPress store plugins is a lack of attention to search engine optimization. When working with product pages powered by Custom Post Types you can continue to use the SEO plugin working to optimize the rest of your website.</p>
<p>Additionally, you&#8217;ll be able to use plugins that enhance your ability to make additional product assets available to readers. Plugins like Attachments will let you add multiple product images for use in a product image viewer, PDFs including additional product details, as well as any available product details that may exist.</p>
<p><img class="alignnone size-full wp-image-1220" title="cart.17.plugins" src="http://mondaybynoon.com/wp-content/uploads/2010/08/cart.17.plugins.png" alt="Screenshot: Product page integration with plugins" width="951" height="886" /></p>
<h4>This is just the beginning</h4>
<p>These are just the basics of getting up and running with WordPress 3.0+, Custom Post Types, and <a href="http://phpurchase.com">PHPurchase</a> in an effort to get the best possible e-commerce shop up and running quickly and easily. While it&#8217;s a bit more work to get a large volume of products added and available on your website, I really feel that PHPurchase is a great choice when considering available e-commerce solutions for WordPress.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>WordPress Custom Post Types &amp; PHPurchase: Best Cart Ever &#8211; Part 1</title>
		<link>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-1/</link>
		<comments>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-1/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 05:27:51 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[PHPurchase]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Shopp]]></category>
		<category><![CDATA[WP e-Commerce]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1189</guid>
		<description><![CDATA[If I had to choose one thing that's been most frustrating about building websites throughout the course of my career it'd have to come down to one thing: shopping carts. I'm not sure why, but finding a shopping cart that's going to support your needs as well as support genuine customization can be a daunting task.]]></description>
			<content:encoded><![CDATA[<p>If I had to choose one thing that&#8217;s been most frustrating about building websites throughout the course of my career it&#8217;d have to come down to one thing: <strong>shopping carts</strong>. I&#8217;m not sure why, but finding a shopping cart that&#8217;s going to support your needs <em>as well as</em> support genuine customization can be a daunting task.</p>
<h2>The WordPress cart landscape</h2>
<p>When it comes to WordPress, there are actually a number of shopping carts available. I think we can all cringe a bit when <a href="http://www.instinct.co.nz/e-commerce/">WP e-Commerce</a> gets brought up. It&#8217;s arguably the oldest, most widely used e-commerce platform for WordPress today. I don&#8217;t have an official stance on the platform though. I&#8217;ve tried to install it a few times now and each time either not made it to, or not made it very far passed activation.</p>
<p>Not too long ago, a new kid showed up on the block: <a href="http://shopplugin.net/">Shopp</a>. I was really impressed from a &#8216;book cover&#8217; stance and took the time to check it out. A few minutes into it I felt that the developers deserved some support for taking a WordPress e-commerce plugin seriously. I snagged myself a single site license and gave it a whirl. I really liked what I saw. The plugin did its part in mirroring design conventions established in WordPress itself, something I feel is very important to plugin development. On top of that, the bit I played around with it showed that it had a great balance of functionality and customization capability.</p>
<p>Shopp followed in WordPress&#8217; footsteps by providing theme files and hooks to work with, something we all love about WordPress. The <a href="http://docs.shopplugin.net/">documentation</a> looked to be actively defined and I was convinced I had my go-to plugin for e-commerce the next time it came up. I even pitched the plugin to a number of friends, some of which had cart projects on their plate and were in the market for a new plugin to check out.</p>
<p>I didn&#8217;t have any e-commerce plugins crop up over time, but I saw a few friends make a post here or there about some frustrations they were having with Shopp. To be as specific as I can without firsthand knowledge, it sounded like there may have been a few bugs to squash when it came to actual payment processing. Shortly after that, the Shopp team announced that the plugin was to undergo a full rewrite in an effort to stabilize the payment processing and other bugs that had been reported in the forums. As it stands, Shopp <a href="http://shopplugin.net/updates/1-1-progress-report/">is in 1.1 beta</a> and looks to be continuing progress.</p>
<p>As I was shopping alternative carts, a Google search brought me to another commercial e-commerce plugin I hadn&#8217;t heard of before: <a href="http://www.phpurchase.com/">PHPurchase</a>. It took all of two seconds for me to realize that something stood out about this plugin. Beyond it being hot off the press, it bragged of such features as PCI compliance and the ability to pass the <a href="http://www.mcafeesecure.com/us/">McAfee Security Test</a>. I liked that. As I dug deeper I took a few minutes to research <a href="http://www.phpoet.com/">PHPoet</a>, the company behind PHPurchase and continued to find bits and pieces that I liked.</p>
<p>As I looked around further, I noticed that <a href="http://www.phpurchase.com/">PHPurchase</a> took a partially different approach to e-commerce in WordPress. Instead of auto-generating product grids and product detail pages, PHPurchase takes care of product entry and the other details surrounding the cart setup, and then leaves it up to you to populate your site.</p>
<p>To be more precise, PHPurchase lets you enter all of your payment gateway details, enter products into the products database, as well as customize a number of additional (and expected) options when it comes to e-commerce. It leaves it up to you, though, to populate the shopping area of your site. Instead of template-based shopping pages, PHPurchase offers a product entry button in the WYSIWYG editor that injects a <a href="http://codex.wordpress.org/Shortcode_API">shortcode</a> which, when processed, outputs a price, quantity field, and a buy button. The rest is <strong>completely up to you</strong>.</p>
<h3>It&#8217;s more work, but it&#8217;s more custom</h3>
<p>That was the driving point for me with PHPurchase. Instead of accommodating a template structure of the cart plugin itself, I could go about my day and code a theme template file as though I were doing that for any other page on the site. On top of that, each and every other plugin I&#8217;ve come to know and love (e.g. <a href="http://wordpress.org/extend/plugins/all-in-one-seo-pack/">All in One SEO Pack</a>) would work like a charm, <em>out of the box</em>. PHPurchase was scoring <strong>major points</strong> the more I thought about it.</p>
<p>All of this took place as we were catching a more public wind about WordPress&#8217; <a href="http://codex.wordpress.org/Custom_Post_Types">Custom Post Types</a>. Custom Post Types are a flagship when it comes to evaluating WordPress as a <abbr title="Content Management System">CMS</abbr> vs. a blogging engine. Here&#8217;s where my mind started racing. The combination of Custom Post Types and PHPurchase is game changing when it comes to WordPress based e-commerce.</p>
<p>Before Custom Post Types, product pages would be set up as any WordPress Page tree would. You&#8217;d create your Pages, populate your content, insert your shortcodes, and end up with a fully functioning e-commerce solution; fully integrated with your favorite plugins. Custom Post Types, though, give you the ability to <em>custom tailor</em> your data fields as well.</p>
<p>Custom Post Types allow you to populate your content as normal, but also give you the ability to set up custom taxonomies (e.g. product categories) as well as tags. You&#8217;re also able to custom code the theme file used for your Custom Post Types as though you were writing it for a built in WordPress Page. Instead of working with (or having to rewrite) product templates, you&#8217;re instead building your cart from the ground up with PHPurchase.</p>
<p>Without a doubt, it&#8217;s more work to get a populated cart up and running with PHPurchase compared to a templated e-commerce plugin. When I think about it though, I build WordPress themes from the ground up for every client (aside from a &#8220;new site&#8221; framework) and I do that because I believe in hand crafted websites. Why should a cart be any different? I think we&#8217;ve been in part complacent to the current cart solutions out there and I&#8217;m glad PHPurchase has changed the game for me. My clients will love it too.</p>
<h4>Implementing PHPurchase with Custom Post Types</h4>
<p><a href="http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-2/">Part 2</a> of this two part series will consist of a walkthrough outlining how I work with WordPress, Custom Post Types, PHPurchase, and a number of plugins that will help make your cart stand out from the rest.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/08/09/wordpress-custom-post-types-phpurchase-cart-part-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress Custom Post Types &amp; Pods: What&#8217;s Next?</title>
		<link>http://mondaybynoon.com/2010/05/31/wordpress-custom-post-types-pods/</link>
		<comments>http://mondaybynoon.com/2010/05/31/wordpress-custom-post-types-pods/#comments</comments>
		<pubDate>Mon, 31 May 2010 14:10:38 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Custom Post Types]]></category>
		<category><![CDATA[Pods]]></category>
		<category><![CDATA[WordPress 3.0]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1126</guid>
		<description><![CDATA[On more than on occasion I've been asked about my future with Pods specifically given the immanent release of WordPress 3.0 featuring Custom Post Types. On the spot, I didn't have to ponder too much, but I did want to let things seep in for a while before explaining my stance in full.]]></description>
			<content:encoded><![CDATA[<p>On more than on occasion I&#8217;ve been asked about my future with Pods specifically given the <a href="http://wordpress.org/development/2010/05/wordpress-3-0-release-candidate/">immanent release of WordPress 3.0</a> featuring Custom Post Types. On the spot, I didn&#8217;t have to ponder too much, but I did want to let things seep in for a while before explaining my stance in full. There&#8217;s a lot to consider with both Custom Post Types and Pods and also a lot of theory and philosophy behind each, in my opinion. I&#8217;m going to avoid the technical details in this overview and keep it simple.</p>
<h2>What are Custom Post Types?</h2>
<p>First and foremost we need to understand what Custom Post Types <em>are</em>. I&#8217;ll try to do my best to sum them up as quickly and as easily as possible in my own words.</p>
<p>Custom Post Types defines our new ability to better organize more advanced content structures within our WordPress sites. That is to say, using Custom Post Types will allow us to create groups of content in addition to the stock Posts and Pages. Subsequently, we&#8217;re also able to <strong>define the data fields</strong> used in each group. Further, we&#8217;re able to take advantage of many standard features built into WordPress such as creating custom taxonomies (used for categorization among other things) and more.</p>
<p>If I had to label one final stake in the ground that WordPress is fantastically stating that it is no longer a &#8220;blogging&#8221; platform and instead a content platform, it would be Custom Post Types.</p>
<p>Custom Post Types have got a ton of attention lately, and as such deserves it. I can&#8217;t emphasize how much of a game changer this is on a platform level not only for WordPress developers, but for users as well. We&#8217;re going to see a lot of changes on the theme level which in turn will spread the word about WordPress&#8217; adaptiveness.</p>
<h2>Where does Pods fit in?</h2>
<p>Custom Post Types sound great, but what about <a href="http://podscms.org/">Pods</a>? If you want the short version: <a href="http://mondaybynoon.com/tag/pods/">I love Pods</a> and I don&#8217;t see it going anywhere anytime soon as a result of Custom Post Types.</p>
<p>Now for the extended version.</p>
<p>Pods and Custom Post Types, although they have some overlapping functionality, don&#8217;t directly compete with one another top to bottom. Custom Post Types open a lot of doors, and I plan on using those doors as often as possible. Pods, however, is functionally superior to Custom Post Types in ways that I&#8217;ve been taking advantage of on nearly every project in recent memory.</p>
<p>The superiority lies in the fact that instead of being a new group of Custom Posts or Pages, Pods focuses on <strong>the relationship</strong> factor by keeping the doors wide open when it comes to how the data is displayed, how users interact with it, and <em>how you use it</em>. Additionally, the Pods developers are <em>super focused</em> on performance. That&#8217;s not to say that I&#8217;ve noticed a performance problem with WordPress, but it&#8217;s great to read that they&#8217;re focused on speed and integrity to the level of creating one-off database tables every time Pods needs one for your content types.</p>
<p>Pods takes a different approach entirely when it comes to the database level. WordPress Custom Post Types simply append your new content groups to the Posts table and under the hood are using Custom Fields to take care of your custom data. This is nowhere near magic to anyone who has written a plugin before that accomplishes the same thing. <a href="http://mondaybynoon.com/wordpress-attachments/">Attachments</a>, for example, uses that philosophy to function.</p>
<p>Don&#8217;t take me wrong, I don&#8217;t think that&#8217;s <em>wrong</em> to do, not by any means. I always try to <a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> and I think Custom Post Types do the same thing. I also appreciate, though, that Pods focuses on performance at its root.</p>
<p>Pods also offers more when it comes to <em>functionality offered</em>. Custom Post Types leave things pretty open-ended for you to get done what you&#8217;d like, but I&#8217;m not sure how easy it will be to relate one Post to another, or multiple for that matter in that group. What about relating that Post to a Post from a completely different group? What if you want to limit that list of available Posts to include a certain number of Posts from one group, and more from another? Pods has you covered out of the box.</p>
<p>I&#8217;ve also become addicted to the way <a href="http://ui.podscms.org/">Pods UI</a> lets you present the Pods you&#8217;ve created. You&#8217;re able to organize and group your content types in such a way that it makes perfect sense when your client needs to hop in the driver&#8217;s seat. Pods UI is founded on built-in WordPress functions and I&#8217;m not sure to what extent it can be replicated with Custom Post Types at this stage, but I&#8217;m smitten with Pods UI and hopefully that functionality can eventually find its way to Custom Post Types.</p>
<p>I&#8217;ve become very comfortable with the advanced features offered by Pods, especially when <a href="http://ui.podscms.org/">Pods UI</a> comes into play, and I won&#8217;t backtrack at this point just to take advantage of built-in functionality (my personal preference by default). I think Pods still stands on its own two feet by a long shot.</p>
<h3>Will they blend?</h3>
<p>That said, I plan on using a combination of Custom Post Types and Pods until a new catalyst enters which will cause me to reevaluate the situation at that point. I have a set of rules that help me build sites on top of WordPress and incorporate Pods all to make things as easy as possible for my clients to <strong><em>use</em></strong> and I will continue with that school of thought now that Custom Post Types are here.</p>
<p>I&#8217;ve got a lot to learn about Custom Post Types and what&#8217;s technically functional, possible, and stable. You can be sure I&#8217;ll be posting my findings along the way. I feel that Pods and Custom Post Types make a good team and will continue to do so beyond the launch of WordPress 3.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/05/31/wordpress-custom-post-types-pods/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Making your Pods Input Helpers a Bit More Helpful</title>
		<link>http://mondaybynoon.com/2010/05/10/pods-helpful-input-helpers/</link>
		<comments>http://mondaybynoon.com/2010/05/10/pods-helpful-input-helpers/#comments</comments>
		<pubDate>Mon, 10 May 2010 13:55:01 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Clients]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Input Helper]]></category>
		<category><![CDATA[Pods]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1095</guid>
		<description><![CDATA[Input Helpers in Pods really enhance the usability of Pods in WordPress. They work to modify data represented to the user in such a way to make it more useful or more valuable. I think that's an important factor to take into account when setting up a Pods powered WordPress site for your clients.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always based my opinions of content management systems on ease of use not only when it comes to implementation on my part, but more-so on the usability for the client once I&#8217;ve handed over the keys. What good is a CMS that your client can&#8217;t use? You&#8217;ll be spending more time tutoring than you will working on the next (billable) job.</p>
<p>That&#8217;s one of the reasons I really like <a href="http://podscms.org/">Pods</a>. While one inescapable argument I&#8217;ve had with myself since discovering Pods is the fact that clients are very likely to become confused with the implementation at a certain point. Not by the fault of Pods itself, but the way it&#8217;s bound to be used. This is where the conversation bridges itself into the <em>philosophy</em> of combining Pods and WordPress for the benefit of your client; an up-and-coming article that isn&#8217;t ready quite yet. There&#8217;s just as much to be said about implementation as there is the tool, and I&#8217;m really looking forward to having that conversation with you soon enough. For the time being though, I digress.</p>
<p>Circling back to usability, out of the box Pods has a leg forward by simply being. It gives an interface consisting of elements strictly defined as being applicable when viewed. Awesome. While putting together a client site recently I couldn&#8217;t help but notice a usability issue I 	<strong>knew</strong> would come up sooner or later. For the sake of privacy, I&#8217;ll make the example a bit more generic, but equally applicable.</p>
<p>For example&#8217;s sake, we&#8217;ll say that I&#8217;m working on a photography history website. There is a section of the website consisting of famous photographers, a bit of information about the person, and of course some work examples. My plan is to have one Pod for the photographers, one Pod for the photographs, and <a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">use Pods UI to relate the two</a> very easily.</p>
<h2>The problem</h2>
<p>With the game plan in place, we&#8217;ll first set up our two Pods:</p>
<p><img class="alignnone size-full wp-image-1096" title="01-photographers" src="http://mondaybynoon.com/wp-content/uploads/2010/05/01-photographers.jpg" alt="Adding a new Pod" /></p>
<p>Define the data columns:</p>
<p><img class="alignnone size-full wp-image-1097" title="02-photographers" src="http://mondaybynoon.com/wp-content/uploads/2010/05/02-photographers.jpg" alt="Adding data columns" /></p>
<p>When setting up the Photographs Pod, we&#8217;re going to <a href="http://mondaybynoon.com/2010/01/11/how-to-use-pick-columns-relationships-in-pods/">set up a pick column</a> to pull from our newly created Photographers Pod:</p>
<p><img class="alignnone size-full wp-image-1098" title="03-photographs" src="http://mondaybynoon.com/wp-content/uploads/2010/05/03-photographs.jpg" alt="Adding a Pod" /></p>
<p>In particular, pay attention to the way the pick column is structured</p>
<p><img class="alignnone size-full wp-image-1099" title="04-photographs" src="http://mondaybynoon.com/wp-content/uploads/2010/05/04-photographs.jpg" alt="Setting up your pick column" /></p>
<p>The final Pod:</p>
<p><img class="alignnone size-full wp-image-1100" title="05-photographs" src="http://mondaybynoon.com/wp-content/uploads/2010/05/05-photographs.jpg" alt="The final Pod data columns" /></p>
<p>We can now begin populating some photographers:</p>
<p><img class="alignnone size-full wp-image-1101" title="06-add-photog" src="http://mondaybynoon.com/wp-content/uploads/2010/05/06-add-photog.jpg" alt="Adding some data to the Pod" /></p>
<p><img class="alignnone size-full wp-image-1102" title="07-photog-listing" src="http://mondaybynoon.com/wp-content/uploads/2010/05/07-photog-listing.jpg" alt="Pods data that has been entered" /></p>
<p>Then we&#8217;ll add some photos:</p>
<p><img class="alignnone size-full wp-image-1103" title="08-add-photo" src="http://mondaybynoon.com/wp-content/uploads/2010/05/08-add-photo.jpg" alt="Displaying the pick column data" /></p>
<p>Here&#8217;s where I discovered that a problem was a brewin&#8217;. As it stands, we&#8217;re using the <code>name</code> column alongside a <code>first_name</code> column therefore resulting in the last name controlling the <code>slug</code>. What happens when you add a second photographer with the same last name? You&#8217;ll be faced with a duplicate entry and your client will be left to guess, save, and check to make sure they guessed right. A possible solution would have been to re-structure the Pod from the start and use the <code>name</code> column for the photographer&#8217;s full name, but what if you wanted to pull data ordered by <em>last</em> name only?</p>
<p>Given the current situation, we might be in a bit of a pickle. Pods can help with that!</p>
<h2>The solution</h2>
<p><a href="http://mondaybynoon.com/2010/03/22/input-helpers-pods-cms-wordpress/">Input Helpers</a> are quickly becoming a favorite feature of mine when it comes to Pods. As is the case with this particular situation, data columns aren&#8217;t quite cutting it, even when they&#8217;re as awesome as pick relationships.</p>
<p>The solution I cam up with to solve this problem of data integrity was to simply make the data itself that much more valuable. It would be great if we could simply append the first name alongside the last name to help decipher which dupe is which when choosing our photographer. Input Helpers to the rescue.</p>
<p>We&#8217;re going to write a quick Input Helper that expands upon the information originally available with a stock pick column. As it stands, when invoked, pick columns will display all of the (extremely valuable) associated data columns you already set up with your Pod. In the case of Photographers, we&#8217;re provided with the following:</p>
<ul>
<li><code>id</code></li>
<li><code>first_name</code></li>
<li><code>origin</code></li>
<li><code>copy</code></li>
<li><code>slug</code></li>
</ul>
<p>All of the <a href="http://podscms.org/codex/input_helpers">additional data that comes with an Input Helper</a> is also available. What&#8217;s most interesting here is the fact that we can pull data from the Pod itself, specifically the <strong>first_name</strong>.</p>
<pre class="sh_php"><code>&lt;select id=&quot;&lt;?php echo $css_id; ?&gt;&quot; class=&quot;form pick1 &lt;?php echo $name; ?&gt; pods_field pods_field_&lt;?php echo $name; ?&gt; pods_coltype_pick&quot;&gt;
  &lt;option value=&quot;&quot;&gt;-- Select One --&lt;/option&gt;
  &lt;?php if ( !empty( $value ) ) : ?&gt;
    &lt;?php foreach ($value as $key =&gt; $val) : ?&gt;

      &lt;?php
        // check to see if this is the chosen value
        $selected = empty($val[&#x27;active&#x27;]) ? &#x27;&#x27; : &#x27;selected&#x27;;

        // check to see if we have a full name
        $photog_name = $val[&#x27;name&#x27;];
        if( !empty( $val[&#x27;first_name&#x27;] ) )
        {
          $photog_name .= &#x27;, &#x27; .  $val[&#x27;first_name&#x27;];
        }
        ?&gt;

      &lt;option value=&quot;&lt;?php echo $val[&#x27;id&#x27;]; ?&gt;&quot;&lt;?php echo $selected; ?&gt;&gt;&lt;?php echo $photog_name; ?&gt;&lt;/option&gt;
    &lt;?php endforeach ?&gt;
  &lt;?php endif ?&gt;
&lt;/select&gt;</code></pre>
<p>As with writing any Input Helper, we want to start by examining the markup provided by the <em>original input field</em>. That way we can replicate and elaborate upon what&#8217;s made available to our user.</p>
<p>The take home notes with this Input Helper revolve around the conditional that checks to see if we have a full name. We simply check to see if <code>first_name</code> has been defined, and if it has, we&#8217;ll append it to the last name and provide a much more straightforward experience for our user:</p>
<p><img class="alignnone size-full wp-image-1104" title="09-enhanced" src="http://mondaybynoon.com/wp-content/uploads/2010/05/09-enhanced.jpg" alt="A more helpful Input Helper" /></p>
<p>Not only does this help to prevent confusion when handing over the keys to your client, it really helps to polish the overall experience by being that much more straightforward and useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/05/10/pods-helpful-input-helpers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Upgrading Pods to use TinyMCE instead of NicEdit</title>
		<link>http://mondaybynoon.com/2010/03/30/upgrading-pods-to-use-tinymce-instead-of-nicedit/</link>
		<comments>http://mondaybynoon.com/2010/03/30/upgrading-pods-to-use-tinymce-instead-of-nicedit/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 20:24:12 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Workbench]]></category>
		<category><![CDATA[Input Helper]]></category>
		<category><![CDATA[NicEdit]]></category>
		<category><![CDATA[Pods]]></category>
		<category><![CDATA[TinyMCE]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1044</guid>
		<description><![CDATA[WYSIWYG is trouble, but I've come to like TinyMCE the most out of anything. Pods has had one hand tied behind its back due to a the_editor() bug plaguing multiple instances of TinyMCE on the same page, but this quick Input Helper should help get us by until they're officially supported in core.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had my <a href="http://mondaybynoon.com/2008/11/10/i-have-a-huge-problem-with-wysiwyg-editors/">share of troubles with WYSIWYG</a> editors. I&#8217;ve had even more trouble with <a href="http://nicedit.com/">NicEdit</a>. Due to a <a href="http://core.trac.wordpress.org/ticket/11862">nasty little bug</a> in WordPress, <a href="http://podscms.org">Pods</a> hasn&#8217;t been able to use <a href="http://tinymce.moxiecode.com/">TinyMCE</a> as WordPress itself does.</p>
<p>NicEdit was frustrating clients left and right, but TinyMCE wasn&#8217;t. Some time ago I wrote a plugin that is in dire need of an upgrade called <a href="http://mondaybynoon.com/wordpress-post-notes/">Post Notes</a> that appended any number of WYSIWYG editors for any Post or Page and let you reference them as you wished. I was hoping I could use the same passive method of including TinyMCE in Pods that I had used for Post Notes.</p>
<p>WordPress has come along nicely since I first wrote that plugin, and I&#8217;m happy to say that I&#8217;ve come up with a working solution to upgrading your NicEdit WYSIWYG columns in Pods to use TinyMCE by adding an <a href="http://mondaybynoon.com/2010/03/22/input-helpers-pods-cms-wordpress/">Input Helper</a>. Here she is:</p>
<p class="single_link"><a class="download" href="http://podscms.org/packages/tinymce-for-paragraph-text/">TinyMCE for Paragraph Text</a></p>
<h2>Input Helper explained</h2>
<p>As a really brief walkthrough what the Input Helper does is modify the markup used to dump out the base <code>textarea</code> that holds our actual data. That&#8217;s the standard part. The exiting bit is contained in the conditional at the top of the Helper. The conditional basically checks to make sure that it&#8217;s not executed repeatedly for each Paragraph Text column used.</p>
<p>When the time is right the helper will fire <code>wp_tiny_mce()</code> which is a nearly undocumented WordPress function that resembles <code>wp_enqueue_script()</code> on steroids. It will pull in all the necessary scripts for TinyMCE as well as properly initialize them.</p>
<p>The first parameter dictates the TinyMCE theme to use. If set to <code>true</code> the full (advanced) theme will be used, setting it to <code>false</code> results in a stripped down (simple) theme which I prefer to use in this case. The <code>array</code> passed as the second parameter tells <code>wp_tiny_mce()</code> which <code>class</code> to hook, <strong>you do not need to edit it</strong>. The <a href="http://podscms.org/packages/tinymce-for-paragraph-text/">Package available for download</a> includes both a simple and an advanced TinyMCE Input Helper.</p>
<p>The JavaScript segment of this helper actually hijacks Pods&#8217; <code>saveForm()</code> function call as we need to force TinyMCE to fire <code>triggerSave()</code> which forces the TinyMCE content to be applied to our original <code>textarea</code> which is <strong>super important</strong>.</p>
<h3>Installation</h3>
<p>You can <a href="http://podscms.org/packages/tinymce-for-paragraph-text/">snag the TinyMCE Upgrade</a> Input Helper Package from the Pods website. Once downloaded, go ahead and log into the WordPress admin and hit the Package Manager link under the Pods heading:</p>
<p><img class="alignnone size-full wp-image-1045" title="01-package-manager" src="http://mondaybynoon.com/wp-content/uploads/2010/03/01-package-manager.jpg" alt="" /></p>
<p>Then you can hit the Import tab since we&#8217;re not Exporting anything:</p>
<p><img class="alignnone size-full wp-image-1046" title="02-import-tab" src="http://mondaybynoon.com/wp-content/uploads/2010/03/02-import-tab.jpg" alt="" /></p>
<p>Just paste the Helper in the provided text box and click Proceed to Confirmation</p>
<p><img class="alignnone size-full wp-image-1047" title="03-proceed" src="http://mondaybynoon.com/wp-content/uploads/2010/03/03-proceed.jpg" alt="" /></p>
<p>After Pods validates the Helper you can go ahead and Finalize:</p>
<p><img class="alignnone size-full wp-image-1048" title="04-finalize" src="http://mondaybynoon.com/wp-content/uploads/2010/03/04-finalize.jpg" alt="" /></p>
<p>Pods will let you know it&#8217;s <strong>All done!</strong> Your Input Helper is ready to go. Now you can browse to the Paragraph Text Column you&#8217;d like to edit which used to look like this:</p>
<p><img class="alignnone size-full wp-image-1049" title="05-nicedit" src="http://mondaybynoon.com/wp-content/uploads/2010/03/05-nicedit.jpg" alt="" /></p>
<p>and update the Input Helper field for the applicable column by first clicking the Edit icon next to your column and then defining the Input Helper by choosing <strong>tinymce</strong> from the <code>select</code>. <strong>Be sure to click Save</strong> to ensure the Input Helper is properly defined:</p>
<p><img class="alignnone size-full wp-image-1050" title="06-add-input-helper" src="http://mondaybynoon.com/wp-content/uploads/2010/03/06-add-input-helper.jpg" alt="" /></p>
<p>When you go back to edit your Pod, you&#8217;ll see a brandy new instance of TinyMCE instead of NicEdit:</p>
<p><img class="alignnone size-full wp-image-1051" title="07-tinymce" src="http://mondaybynoon.com/wp-content/uploads/2010/03/07-tinymce.jpg" alt="" /></p>
<p><strong>Please make sure</strong> you&#8217;re running the latest versions of both <a href="http://podscms.org">Pods</a> and <a href="http://ui.podscms.org">Pods UI</a> before working with this Input Helper.</p>
<h3>Known Issues</h3>
<p>I&#8217;m currently trying to work with <a href="http://twitter.com/sc0ttkclark">Scott Kingsley Clark</a> on a few details but there may be some problems with using this Input Helper along with a <a href="http://podscms.org/codex/publicform"><code>publicForm</code></a>. Please avoid using this Input Helper on any Pod you plan on using in conjunction with <code>publicForm</code> until it can be better tested. More info coming as soon as possible!</p>
<p><strong>Update</strong>: As of March 31, 2010 I can confirm that there is a problem with the Helper if your Pod has not been made Top Level and you&#8217;re not using Pods UI for the Pod. If at all possible, making it either Top Level or using Pods UI should achieve the desired results. We&#8217;ll keep working away at a fix ASAP!</p>
<p><strong>Update</strong>: Version 1.0.2 forces each editor instance to be of a certain height and also disables the resize handle due to it acting up in certain circumstances.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/03/30/upgrading-pods-to-use-tinymce-instead-of-nicedit/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Using Input Helpers in Pods CMS for WordPress</title>
		<link>http://mondaybynoon.com/2010/03/22/input-helpers-pods-cms-wordpress/</link>
		<comments>http://mondaybynoon.com/2010/03/22/input-helpers-pods-cms-wordpress/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 13:36:40 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Workbench]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[Input Helper]]></category>
		<category><![CDATA[Pages]]></category>
		<category><![CDATA[Pods]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=1000</guid>
		<description><![CDATA[Input Helpers in Pods CMS for WordPress allow you to work with and manipulate the data available to your clients on a per-input-field basis. In this walkthrough we'll discuss limiting the WordPress Pages available in a Pick column as a method of applying a custom background image to the selected pages.]]></description>
			<content:encoded><![CDATA[<p>Pods CMS really aims to be a framework in the sense that you can do <strong>anything you want</strong> with it. The approach of the developers always seems to keep that in mind, which is sometimes the most difficult thing to do when writing software.</p>
<p>I&#8217;d like to review <a href="http://podscms.org/codex/input_helpers">Input Helpers</a> a bit. Out of the box, Pods offers a number of <a href="http://podscms.org/codex/column_types">column types</a> including date field, number, boolean, paragraph text, and more. We also can&#8217;t forget about one of the more unique column types offered; <a href="http://mondaybynoon.com/2010/01/11/how-to-use-pick-columns-relationships-in-pods/">Pick columns</a>.</p>
<h2>Applying Input Helpers to Pick columns</h2>
<p>On a recent project (like many projects) I found myself using a Pick column set to <code>WP Page</code> that automagically pulls a list of all WordPress Pages when the Pod entry form is displayed.</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/03/01-pages-1.jpg"><img class="alignnone size-full wp-image-1012" title="01-pages-1" src="http://mondaybynoon.com/wp-content/uploads/2010/03/01-pages-1.jpg" alt="Setting up a WP Page Pick column in Pods" width="327" height="406" /></a></p>
<p>The goal with this Pod was to allow the client to dynamically define a background image for their website on a per-page basis. Out of the box, the solution worked as expected:</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/03/02-stock-pod.jpg"><img class="alignnone size-full wp-image-1002" title="02-stock-pod" src="http://mondaybynoon.com/wp-content/uploads/2010/03/02-stock-pod.jpg" alt="The default output of a Pick column in Pods CMS" /></a></p>
<p>There was a problem though. I didn&#8217;t want the client to have full control over each and every page of the site. There were a number of pages on which it wouldn&#8217;t make sense to have a custom background. This is one of the many cases where <a href="http://podscms.org/codex/input_helpers">Input Helpers</a> come to the rescue.</p>
<h3>The basics of Input Helpers</h3>
<p>Input Helpers were designed to do one thing:</p>
<blockquote cite="http://podscms.org/codex/input_helpers"><p>An Input Helper lets you completely customize the appearance of any input field.</p>
</blockquote>
<p>What this means is we&#8217;re given the opportunity to both <em>hook</em> and <strong><em>manipulate</em></strong> the data pulled to an input field before it is displayed on screen. Input Helpers are applied on a <strong>per-column basis</strong> (as opposed to a Pod as a whole). The possibilities here are literally endless. If you have a requirement for the options available in an input field, Input Helpers are where you&#8217;d start.</p>
<p>As mentioned in <a href="http://podscms.org/codex/input_helpers">the Codex</a>, Input Helpers have a number of variables available to use. Each variable is well explained in the Codex, and depending on the column type, you can use and interact with each of these variables at your will in an effort to obtain your desired result.</p>
<p>Input Helpers are created using the Helpers tab in the admin panel. When naming your Input Helper, ensure the title is comprised of <strong>all lowercase (non-special) characters, no dashes, and no spaces</strong>. Also be sure to define the helper as <strong>Input</strong>.</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/03/03-input-helper-init.jpg"><img class="alignnone size-full wp-image-1003" title="03-input-helper-init" src="http://mondaybynoon.com/wp-content/uploads/2010/03/03-input-helper-init.jpg" alt="Screenshot outlining how to create an Input Helper in Pods CMS" /></a></p>
<p>After the Helper is created, you&#8217;re provided with a code editor. Here&#8217;s where the magic happens. Using this editor, you can manipulate your data using a combination of straight PHP and the variables outlined in <a href="http://podscms.org/codex/input_helpers">the Codex</a>.</p>
<p>After you&#8217;re done writing the PHP needed to manipulate the values available in your input column, the last step is to actually <em>apply</em> the Helper to your Input:</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/03/04-apply-helper.jpg"><img class="alignnone size-full wp-image-1004" title="04-apply-helper" src="http://mondaybynoon.com/wp-content/uploads/2010/03/04-apply-helper.jpg" alt="Applying an Input Helper to an input column in Pods CMS" /></a></p>
<p><strong>Note:</strong> due to AJAX, you&#8217;ll need to refresh the page <em>before</em> attempting to apply your Input Helper.</p>
<h3>Limiting WordPress Pages with an Input Helper</h3>
<p>Circling back to our single use case, we&#8217;ll go ahead and write a quick and dirty Input Helper that&#8217;s going to limit our WP Page Pick column to only a select few Pages I want to make available to my client. Writing an Input Helper might require a bit of initial legwork in inspecting the default markup used for the existing (out of the box) data available. In this example we&#8217;re working a multiple Pick, so the markup is as follows:</p>
<pre class="sh_html"><code>&lt;div class=&quot;leftside pages&quot;&gt;
  &lt;label for=&quot;pods_form0_pages&quot;&gt;
    Page(s)
    &lt;span class=&quot;red&quot;&gt;*&lt;/span&gt;
  &lt;/label&gt;
&lt;/div&gt;
&lt;div class=&quot;rightside pages&quot;&gt;
  &lt;div class=&quot;form pick pages&quot; id=&quot;pods_form0_pages&quot;&gt;
    &lt;div class=&quot;option&quot; value=&quot;2&quot;&gt;About&lt;/div&gt;
    ...
    &lt;div class=&quot;option&quot; value=&quot;18&quot;&gt;Team&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>The snippet has been truncated, but we can see how the Pick column is structured. We simply need to recreate that markup as we filter through the data supplied to the field:</p>
<pre class="sh_php"><code>&lt;?php
  $applicable_pages = array( 2, 31, 18, 23 );
?&gt;
&lt;div class=&quot;form pick &lt;?php echo $name; ?&gt;&quot;&gt;
  &lt;?php if ( !empty( $value ) ) : ?&gt;
    &lt;?php foreach ($value as $key =&gt; $val) : ?&gt;
      &lt;?php if( in_array( $val[&#x27;id&#x27;], $applicable_pages ) ) : ?&gt;

        &lt;?php
          $pagename = $val[&#x27;name&#x27;];
          $active= empty($val[&#x27;active&#x27;]) ? &#x27;&#x27; : &#x27; active&#x27;;
        ?&gt;
        &lt;div class=&quot;option&lt;?php echo $active; ?&gt;&quot; value=&quot;&lt;?php echo $val[&#x27;id&#x27;]; ?&gt;&quot;&gt;
          &lt;?php echo $pagename ; ?&gt;
        &lt;/div&gt;

      &lt;?php endif ?&gt;
    &lt;?php endforeach ?&gt;
  &lt;?php endif ?&gt;
&lt;/div&gt;</code></pre>
<p>What we&#8217;re doing with this Helper is first defining <code>$applicable_pages</code> which contains an array of the Page <code>ids</code> we&#8217;re permitting to show up for use. We then loop through <code>$value</code> (provided by Pods as per the Codex) and check to see if the current Page id is in our array. If it is, we&#8217;ll go ahead and make it available, else we move on to the next. What results is our refined list of available WordPress pages:</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/03/05-refined-pages.jpg"><img class="alignnone size-full wp-image-1005" title="05-refined-pages" src="http://mondaybynoon.com/wp-content/uploads/2010/03/05-refined-pages.jpg" alt="Screenshot illustrating that our WP Page Pick column has indeed been filtered" /></a></p>
<p>A word of warning with this implementation: it&#8217;s tied to a single WordPress install. Additionally, problems will come up should the site be migrated to a new WordPress installation without a complete database export/import. WordPress Page ids are not retained using WordPress&#8217; import/export features. Keep that in mind as you write your Helpers.</p>
<h3>Input Helpers raise the bar</h3>
<p>Input Helpers open a ton of new doors when it comes to Pods. We&#8217;ve just scratched the surface with the example above, and as with pretty much anything &#8220;Pods&#8221; the possibilities are <strong>endless</strong>.</p>
<p>Another great resource you&#8217;ll want to bookmark is the <a href="http://podscms.org/packages/">Packages</a> section of the Pods CMS website. You can find a ton of available Helpers that have been made available by the community, some of which may come in handy straight away. The section isn&#8217;t limited to Helpers, but you can easily peruse the titles and poke around when you&#8217;ve got a minute.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/03/22/input-helpers-pods-cms-wordpress/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Building a Store Locator with WordPress and Pods</title>
		<link>http://mondaybynoon.com/2010/02/22/store-locator-wordpress-pods/</link>
		<comments>http://mondaybynoon.com/2010/02/22/store-locator-wordpress-pods/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 16:43:08 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Favorites]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Workbench]]></category>
		<category><![CDATA[directory]]></category>
		<category><![CDATA[location]]></category>
		<category><![CDATA[Pods]]></category>
		<category><![CDATA[proximity]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=835</guid>
		<description><![CDATA[I've always been curious about adding a location based proximity search powered by ZIP code and desired radius. It's actually quite easy to do using WordPress, Pods, and some crazy MySQL queries. This walkthrough shows you how to add a PHP/MySQL based store finder powered by WordPress and Pods.]]></description>
			<content:encoded><![CDATA[<p>Truth be told I was always a bit intimidated by proximity searches. That is to say the &#8220;Find <strong>X</strong> within <strong>Y</strong> miles&#8221; implementations we see everywhere. There was always a bit of magic behind how that worked and I&#8217;ve had a long time itch to figure out exactly how it worked.</p>
<p>Luckily enough, a client need came through which included such a feature. What better time to teach yourself something? Other programmers at my company had implemented proximity searches in the past, but I wasn&#8217;t involved on the projects and didn&#8217;t want to simply peruse their code and see what I could pull from it. I sat down with one of the guys as I began working on the feature to discuss past implementations. There were two ways to go about it:</p>
<ol>
<li>Piggyback on Google Maps</li>
<li>Do things the hard way</li>
</ol>
<p>It took me about zero seconds to determine that I wanted to do things the hard way. It&#8217;s not that I don&#8217;t enjoy working with Google Maps. Quite the contrary in fact. I just don&#8217;t want to depend on it too much in the day to day, especially for something as generic as a proximity search. Additionally, it just adds another layer of complexity with remote calls, API limits, and the other issues associated with using any other third party service. Hard way it is.</p>
<h2>Pods setup</h2>
<p>The first thing we&#8217;ll do is create a &#8216;stores&#8217; Pod. If you&#8217;re not familiar with creating Pods, take a few minutes to read the beginner series, starting with <a href="http://mondaybynoon.com/2010/01/04/pods-basics-installation-and-setup/">Pods Basics: Installation and Setup</a>. I&#8217;m going to use the following columns:</p>
<ul>
<li>name (txt)</li>
<li>slug (slug)</li>
<li>address (txt)</li>
<li>city (txt)</li>
<li>state (PICK state)</li>
<li>zipcode (txt)</li>
</ul>
<p>We&#8217;re also going to simply make this Pod a Top Level Menu. If you&#8217;re looking to make things even nicer, go ahead and <a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">include Pods UI</a> where applicable.</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/02/stores-pod-2.jpg"><img class="alignnone size-full wp-image-846" title="stores-pod-2" src="http://mondaybynoon.com/wp-content/uploads/2010/02/stores-pod-2.jpg" alt="" width="462" height="380" /></a></p>
<p>I&#8217;ve made every column required data, as an address isn&#8217;t very useful without complete information. I segmented the addresses as such simply because the proximity search I&#8217;ll be implementing is based on ZIP code, and having that data in a separate column will help with server load. Lastly, I chose to use a txt column for the <code>zipcode</code> instead of a Number because many ZIP codes begin with one (or more) zeros, which would cause a bit of trouble.</p>
<p>As a last step, we&#8217;ll go ahead and add a few test store listings using various ZIP codes you&#8217;re familiar with. The more variance the better, as you&#8217;ll be able to see whether the proximity aspect of the search is working properly or not.</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/02/sample-single.jpg"><img class="alignnone size-full wp-image-840" title="sample-single" src="http://mondaybynoon.com/wp-content/uploads/2010/02/sample-single.jpg" alt="" width="551" height="267" /></a></p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/02/sample-listing.jpg"><img class="alignnone size-full wp-image-841" title="sample-listing" src="http://mondaybynoon.com/wp-content/uploads/2010/02/sample-listing.jpg" alt="" width="337" height="410" /></a></p>
<p>Once you&#8217;ve added a few samples, it&#8217;s time to integrate.</p>
<h2>WordPress setup</h2>
<p>For the sake of brevity, this location based search will sit on its own WordPress Page, using a template we&#8217;ll put together. We&#8217;ll continue working with the WordPress default theme, and add a new template; <code>store-locator.php</code> which includes the following:</p>
<pre class="sh_php"><code>&lt;?php

/* Template Name: Store Locator */

get_header(); ?&gt;

  &lt;div id="content" class="narrowcolumn" role="main"&gt;

    &lt;?php the_post(); ?&gt;
    &lt;div class="post" id="post-&lt;?php the_ID(); ?&gt;"&gt;
    &lt;h2&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
      &lt;div class="entry"&gt;

        &lt;?php the_content(); ?&gt;

        &lt;form action="" method="post"&gt;

          &lt;p&gt;
            &lt;label for="mbn_zipcode"&gt;&lt;small&gt;Your ZIP&lt;/small&gt;&lt;/label&gt;
            &lt;input type="text" name="mbn_zipcode" id="mbn_zipcode" value="&lt;?php echo $_POST['mbn_zipcode']; ?&gt;" size="5" tabindex="1" /&gt;
          &lt;/p&gt;

          &lt;p&gt;
            &lt;label for="mbn_distance"&gt;&lt;small&gt;Within (miles)&lt;/small&gt;&lt;/label&gt;
            &lt;select name="mbn_distance" id="mbn_distance" tabindex="2"&gt;
              &lt;option value="5"&lt;?php if( empty( $_POST['mbn_distance'] ) || $_POST['mbn_distance'] == "5" ) : ?&gt; selected="selected"&lt;?php endif ?&gt;&gt;5&lt;/option&gt;
              &lt;option value="10"&lt;?php if( $_POST['mbn_distance'] == "10" ) : ?&gt; selected="selected"&lt;?php endif ?&gt;&gt;10&lt;/option&gt;
              &lt;option value="25"&lt;?php if( $_POST['mbn_distance'] == "25" ) : ?&gt; selected="selected"&lt;?php endif ?&gt;&gt;25&lt;/option&gt;
              &lt;option value="50"&lt;?php if( $_POST['mbn_distance'] == "50" ) : ?&gt; selected="selected"&lt;?php endif ?&gt;&gt;50&lt;/option&gt;
              &lt;option value="100"&lt;?php if( $_POST['mbn_distance'] == "100" ) : ?&gt; selected="selected"&lt;?php endif ?&gt;&gt;100&lt;/option&gt;
            &lt;/select&gt;
          &lt;/p&gt;

          &lt;p&gt;&lt;input name="submit" type="submit" id="submit" tabindex="3" value="Submit" /&gt;&lt;/p&gt;

        &lt;/form&gt;

      &lt;/div&gt;
    &lt;/div&gt;

  &lt;/div&gt;

&lt;?php get_sidebar(); ?&gt;

&lt;?php get_footer(); ?&gt;</code></pre>
<p>Nothing exciting happening here, we&#8217;re simply setting the stage with the basic form we&#8217;ll use to search our store directory by location.</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/02/basic-form.jpg"><img class="alignnone size-full wp-image-842" title="basic-form" src="http://mondaybynoon.com/wp-content/uploads/2010/02/basic-form.jpg" alt="" width="497" height="182" /></a></p>
<p>Now that we&#8217;ve got our Page using our template, we&#8217;ll implement the location search functionality via Pods.</p>
<h2>Setting up the location search</h2>
<p>Our first step will be to add a conditional that checks to see if the form has been submitted. In this case, I&#8217;ll simply add a hidden <code>input</code> to track the current action:</p>
<pre class="sh_html"><code>&lt;input type="hidden" name="mbn_action" value="search" /&gt;</code></pre>
<p>With this action in place, we can include our conditional:</p>
<pre class="sh_php"><code>&lt;?php if( !empty( $_POST['mbn_action'] ) ) : ?&gt;
  &lt;p&gt;List our results&lt;/p&gt;
&lt;?php endif ?&gt;</code></pre>
<p>Here&#8217;s where everything happens. Once we find ourselves in the conditional, we&#8217;ll need to do a bit of work:</p>
<ol>
<li>Sanitize our data</li>
<li>Retrieve search results</li>
<li>Display data</li>
</ol>
<p>Our conditional will expand to be:</p>
<pre class="sh_php"><code>&lt;?php
  if( !empty( $_POST['mbn_action'] ) )
  {
    if( !is_numeric( $_POST['mbn_zipcode'] ) )
    {
      $the_zip = '0';
    }
    else
    {
      $the_zip = $_POST['mbn_zipcode'];
    }

    $the_distance = intval( $_POST['mbn_distance'] );

    $stores = mbn_get_stores_by_location( $the_zip, $the_distance );
    $stores_total = count( $stores );
  ?&gt;

    &lt;?php if( $stores_total &gt; 0 ) : ?&gt;
      &lt;h3&gt;Search Results&lt;/h3&gt;
      &lt;ol&gt;
        &lt;?php foreach( $stores as $store ) : ?&gt;
          &lt;?php $store_address = $store['address'] . ' ' . $store['city'] . ', ' . $store['state'][0]['name'] . ' ' . $store['zipcode'] ; ?&gt;
          &lt;li&gt;&lt;dl&gt;
            &lt;dt&gt;Name&lt;/dt&gt;&lt;dd&gt;&lt;?php echo $store['name']; ?&gt;&lt;/dd&gt;
            &lt;dt&gt;Address&lt;/dt&gt;&lt;dd&gt;&lt;?php echo $store_address; ?&gt;&lt;/dd&gt;
            &lt;dt&gt;Distance&lt;/dt&gt;&lt;dd&gt;&lt;?php echo $store['distance']; ?&gt; miles&lt;/dd&gt;
          &lt;/dl&gt;&lt;/li&gt;
        &lt;?php endforeach ?&gt;
      &lt;/ol&gt;
    &lt;?php endif ?&gt;

&lt;?php } ?&gt;</code></pre>
<p>You&#8217;ll notice that there&#8217;s no reference to Pods anywhere in that conditional, but there is a new function to take a look at; <code>mbn_get_stores_by_location()</code>.</p>
<h3>Implementing the proximity aspect</h3>
<p>This new function, <code>mbn_get_stores_by_location()</code>, will take care of all the work including:</p>
<ol>
<li>Determine the latitude and longitude of the source ZIP code</li>
<li>Use triginomitry to determine which additional ZIP codes fall within the chosen radius</li>
<li>Retrieve all Pods entries matching the pool of ZIP codes</li>
<li>Return an array of results, ordered by distance</li>
</ol>
<p>The quickest and easiest way to implement the function will be adding it to <code>functions.php</code> in your theme. Before we implement the function, however, you&#8217;ll need to add a new table to your database. This table is going to include a listing of all US-based ZIP codes and acts as an integral piece for this function. The table is used to determine the latitude and longitude of applicable ZIP codes, and is used with each search submission. There are a number of places to obtain a ZIP code database, the one I&#8217;ve used in the past is made available for free from <a href="http://www.populardata.com/zipcode_database.html">PopularData.com</a>. It&#8217;s made available as a <abbr title="Comma Separated Value">CSV</abbr> file weighing in at about 700k. There is a donation button available on the download page, and I&#8217;d suggest showing your appreciation to the provider should you use the database for any commercial work.</p>
<p>You&#8217;ll need to set up a new table in your WordPress database and be sure to name it something unique. You&#8217;ll need to remember both the table name and column names as you implement the location search. Once you&#8217;ve added the table and verified its integrity, we can go ahead and implement <code>mbn_get_stores_by_location()</code> in <code>functions.php</code>:</p>
<pre class="sh_php"><code>&lt;?php

function mbn_get_stores_by_location( $zip, $radius )
{
  global $wpdb;
  $radius = intval( $radius );

  // we first need to get the source coordinates
  $sql = "SELECT `latitude`, `longitude` FROM `mbn_zip_codes` WHERE `zipcode` = '$zip'";
  $coords = $wpdb-&gt;get_row( $sql );

  // now we'll get the other ZIP codes within the radius, ordered by distance
  $sql = "SELECT mbn_zip_codes.zipcode, ( 3959 * acos( cos( radians( $coords-&gt;latitude ) ) * cos( radians( mbn_zip_codes.latitude ) ) * cos( radians( mbn_zip_codes.longitude ) - radians( $coords-&gt;longitude ) ) + sin( radians( $coords-&gt;latitude ) ) * sin( radians( mbn_zip_codes.latitude ) ) ) )  AS distance FROM mbn_zip_codes HAVING distance &lt;= $radius OR distance IS NULL ORDER BY distance";

  $nearby_zips = $wpdb-&gt;get_results( $sql );

  // we need to store the zips in order to build the Pods query
  $target_zips = array();
  foreach ($nearby_zips as $nearby_zip)
  {
    array_push($target_zips, $nearby_zip-&gt;zipcode);
  }

  // we're going to store the results as we go
  $store_results = array();

  if( count( $target_zips &gt; 0 ) )
  {
    $final_target_zips = implode(',', $target_zips);

    if( strlen( $final_target_zips &gt; 0 ) )
    {
      // let's snag the data
      $stores = new Pod('stores');
      $stores-&gt;findRecords('id ASC', 9, 't.zipcode IN (' . $final_target_zips . ')');

      $store_data = array();

      while ( $stores-&gt;fetchRecord() )
      {
        $store_data['id']       = $stores-&gt;get_field('id');
        $store_data['name']     = $stores-&gt;get_field('name');
        $store_data['slug']     = $stores-&gt;get_field('slug');
        $store_data['address']  = $stores-&gt;get_field('address');
        $store_data['city']     = $stores-&gt;get_field('city');
        $store_data['state']    = $stores-&gt;get_field('state');
        $store_data['zipcode']  = $stores-&gt;get_field('zipcode');

        foreach ($nearby_zips as $nearby_zip)
        {
          if( $store_data['zipcode'] == $nearby_zip-&gt;zipcode )
          {
            $store_data['distance'] = intval( $nearby_zip-&gt;distance );
          }
        }

        array_push( $store_results, $store_data );
        unset( $store_data );
      }

      usort( $store_results, "mbn_cmp" );
    }

  }
    return $store_results;
}

?&gt;</code></pre>
<p>Quite a bit is going on in this function. Once our <code>globals</code> are set and our data sanitized, we&#8217;re going to query the new table we set up to retrieve the coordinates of the submitted ZIP code. Once we have those coordinates, we&#8217;re going to perform a lengthy query on that same table to determine what other ZIP codes fall within the submitted radius:</p>
<pre class="sh_sql"><code>SELECT mbn_zip_codes.zipcode, ( 3959 * acos( cos( radians( $coords-&gt;latitude ) ) * cos( radians( mbn_zip_codes.latitude ) ) * cos( radians( mbn_zip_codes.longitude ) - radians( $coords-&gt;longitude ) ) + sin( radians( $coords-&gt;latitude ) ) * sin( radians( mbn_zip_codes.latitude ) ) ) )  AS distance FROM mbn_zip_codes HAVING distance &lt;= $radius OR distance IS NULL ORDER BY distance</code></pre>
<p>You will need to be sure that table and column names are appropriately updated. There are a number of formulas which use trigonometry to solve proximity equations, but I&#8217;ve found the above to suit my needs well in this application.</p>
<p>Once we&#8217;ve got our nearby ZIP codes ordered by date, we query our Pod for any entries with ZIP codes that match our results. Instead of using <code>get_field()</code> to echo the display directly, we&#8217;ll instead use it to store the data in an <code>array</code> consisting of all returned results.</p>
<p>Once we&#8217;ve processed the results, our last step will be to use <a href="http://www.php.net/usort"><code>usort</code></a> to ensure our results are actually sorted by distance:</p>
<pre class="sh_php"><code>usort( $store_results, "mbn_cmp" );</code></pre>
<p><code>usort</code> uses a custom function to determine the comparison result, and we&#8217;ll need to add that to <code>functions.php</code> as well:</p>
<pre class="sh_php"><code>function mbn_cmp($a, $b)
{
  $a = intval( $a['distance'] );
  $b = intval( $b['distance'] );
  if( $a &lt; $b )
  {
    return -1;
  }
  elseif( $a &gt; $b )
  {
    return 1;
  }
  else
  {
    return 0;
  }
}</code></pre>
<p>Note that the comparison function uses a specific array key to generate a result. If you change the distance key, you&#8217;ll need to update this function as well.</p>
<p>That takes all the magic out of it. If we return to our submission form and search for a ZIP code that is known to produce results, we&#8217;ll see the functionality at work:</p>
<p><a href="http://mondaybynoon.com/wp-content/uploads/2010/02/results.jpg"><img class="alignnone size-full wp-image-843" title="results" src="http://mondaybynoon.com/wp-content/uploads/2010/02/results.jpg" alt="" width="445" height="540" /></a></p>
<p>I realize the explanation is a bit lengthy, but I hope it helps to explain how a proximity search can work on a smaller scale.</p>
<h3>Alternative implementations</h3>
<p>As I researched location based proximity searches, I found a number of alternative solutions using PHP and MySQL. Some of which included stored procedures, and other advanced uses of MySQL. I&#8217;m nearly positive other implementations would require less computing power and run a bit faster, but I chose not to take that path because I wanted to keep the functionality as lightweight and portable as possible.</p>
<p>The queries used in the search function are performing quite a bit of math, and probably won&#8217;t scale extremely well. If you&#8217;re only looking to implement a location search on a smaller set of data (under 10,000 or so) I think using something like this will work for you as well.</p>
<h3>Other uses</h3>
<p>With Pods making a location based ZIP code search so easy, I&#8217;m hoping to implement it on more client projects since it won&#8217;t affect the budget very much. Some initial use cases that come to mind are:</p>
<ul>
<li>Member directory searches</li>
<li>Service area searches</li>
<li>Geographic zone searches</li>
<li>Event listings</li>
</ul>
<p>The next step I&#8217;d take with an implementation such as this would be to remove the requirement of entering your ZIP code manually altogether and instead use <a href="http://en.wikipedia.org/wiki/Geoip">geolocation</a> to automatically generate a starting point for the visitor.</p>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/02/22/store-locator-wordpress-pods/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>The Last of the Pods Basics: Pagination and Sorting</title>
		<link>http://mondaybynoon.com/2010/01/25/pods-pagination-sorting/</link>
		<comments>http://mondaybynoon.com/2010/01/25/pods-pagination-sorting/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 14:57:57 +0000</pubDate>
		<dc:creator>Jonathan Christopher</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Workbench]]></category>
		<category><![CDATA[pagination]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Pods]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://mondaybynoon.com/?p=736</guid>
		<description><![CDATA[To wrap up the Basics of Pods in January, I'd like to cover the last couple items I feel are almost essential in having the user experience of Pods come full circle for both you and your user. Pods offers both pagination and sorting out of the box, and each can be very helpful when it comes to working with the plugin.]]></description>
			<content:encoded><![CDATA[<p>The Series on Pods has been quite a success so far. I&#8217;ve had some back and forth with lots of new people who were itching to give Pods a try, and the series has been quite a bit of help to newcomers. I&#8217;m super happy about that, and I&#8217;d like to close out the initial push on the series with what I&#8217;ll call The Last of the Pods Basics. That is to say, I&#8217;d like to go over the last few bits that will really get you up and running with Pods in such a way that you can do even more with both your data as well as your user experience.</p>
<p>As a quick recap, if you haven&#8217;t read the first five articles in The Series, you will probably find this article a bit confusing. That said, please make sure you&#8217;ve read: <a href="http://mondaybynoon.com/2010/01/04/introduction-to-pods-cms-wordpress/">An Overview of and Introduction to Pods CMS for WordPress</a>, <a href="http://mondaybynoon.com/2010/01/04/pods-basics-installation-and-setup/">Pods Basics: Installation and Setup</a>, <a href="http://mondaybynoon.com/2010/01/04/pulling-pods-data/">Pods Basics: Pulling Pods Data to your Theme</a>, <a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">Pods UI: The Latest and Greatest Addition to Pods</a>, and <a href="http://mondaybynoon.com/2010/01/11/how-to-use-pick-columns-relationships-in-pods/">How to use Pick Columns (Relationships) in Pods</a>. Being up to speed is essential with this article, as it&#8217;s going to build on the system we&#8217;ve put in place using the previously published articles. You won&#8217;t need to recreate the structure set up in the earlier walk throughs, but knowing the existing implementation will help these instructions remain clear.</p>
<h2>Paginated content in Pods</h2>
<p>Pods comes with pagination <em>built right in</em>, it&#8217;s just a matter of getting it to work the way you want. We&#8217;ll begin by flooding the Team Pod we set up previously with a large group of entries. In addition to the Pod setup, I also added <a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">Pods UI</a> to help manage the content.</p>
<p><img src="http://mondaybynoon.com/images/pods/paging/01-team-listing.jpg" alt="Our new Team listing" /></p>
<p>If we were to check out our Team page now, we&#8217;d see that the listing has been limited to the <strong>default</strong> 15 records:</p>
<p><img src="http://mondaybynoon.com/images/pods/paging/02-limited-no-warning.jpg" alt="Team listing" /></p>
<p>Also by default, Pods doesn&#8217;t include any sort of warning that content wasn&#8217;t listed. It shouldn&#8217;t do that, because Pods does what you tell it to do. You have a few options here. The first would be to change the way we pull the original data. As it stands, we&#8217;re using:</p>
<pre class="sh_php"><code>&lt;?php
  $team = new Pod(&#x27;team&#x27;);
  $team-&gt;findRecords(&#x27;name ASC&#x27;);
?&gt;</code></pre>
<p>As it turns out, <a href="http://pods.uproot.us/codex/findrecords"><code>findRecords</code></a> has more parameters to work with, one of which is the <code>LIMIT</code> we want to use. You can change the default of 15 by defining the <code>$rows_per_page</code> parameter:</p>
<pre class="sh_php"><code>&lt;?php
  $team = new Pod(&#x27;team&#x27;);
  $team-&gt;findRecords(&#x27;name ASC&#x27;, 20);
?&gt;</code></pre>
<p>If we were to make that change, we&#8217;d see all 16 records we have entered, but would also have the same problem once we breached the new limit of 20. A better solution is to include pagination. We&#8217;ll revert back to the default limit of 15, and include our pagination links below the Team listing. It&#8217;s even easier than it sounds. After you&#8217;ve defined your Pod, you can fire the following anywhere:</p>
<pre class="sh_php"><code>&lt;?php echo $team-&gt;getPagination(); ?&gt;</code></pre>
<p><code>getPagnination()</code> basically takes care of everything, and will include the pagination controls where <code>echo</code>&#8216;d:</p>
<p><img src="http://mondaybynoon.com/images/pods/paging/03-pagination.jpg" alt="Pagination controls" /></p>
<p>Here&#8217;s the best part, <strong>that&#8217;s all you&#8217;ve got to do</strong>. Clicking the second page appends a couple of <code>$_GET</code> variables, reloads the page, and shows you all of your new data. <em>You&#8217;re done</em>. There are a few more details concerning <a href="http://pods.uproot.us/codex/getpagination"><code>getPagination()</code></a> which will be covered in a subsequent article.</p>
<h2>Sorting Pods entries</h2>
<p>I&#8217;m really excited that the Pods developers are taking so much care with <a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">Pods UI</a>. Beyond the inherent user experience improvements it makes, they&#8217;re adding features that you can&#8217;t even find in WordPress yet. One of my most welcomed additions as of late with Pods UI is the inclusion of drag and drop sorting of Pods entries. Before the functionality was implemented, you had to make a <code>number</code> column in your Pod, and instruct users to use that field to manually order the Pods entries. It was a replication of the limited functionality WordPress offers with Pages. The Pods developers did one better and included such functionality in <a href="http://ui.podscms.org/">Pods UI</a>. As with every other aspect of Pods, it&#8217;s <em>super easy to integrate</em>, we&#8217;ll walk through it quickly.</p>
<p>The first step carries over from the old way of doing things, you&#8217;ll need to add a <code>number</code> column to your Pod. We&#8217;ll continue working with our Team Pod:</p>
<p><img src="http://mondaybynoon.com/images/pods/sorting/01-displayorder-col.jpg" alt="Adding our number column" /></p>
<p>Once the column is added, we&#8217;re going to need to modify our theme template to <code>ORDER BY</code> that column as opposed to the <code>name</code> column it&#8217;s currently using:</p>
<pre class="sh_php"><code>&lt;?php
  $team = new Pod(&#x27;team&#x27;);
  $team-&gt;findRecords(&#x27;displayorder ASC&#x27;);
  $total_members = $team-&gt;getTotalRows();
?&gt;</code></pre>
<p>Easy enough. You could actually leave things as is, and your user could manually edit each of the <code>displayorder</code> columns for each Pod entry, but Pods UI makes that so much easier. We&#8217;ll need to modify our custom UI plugin and include a few choice flags that will tell Pods UI the details it needs to enable drag and drop sorting. Our <strong>revised</strong> plugin is as follows:</p>
<pre class="sh_php"><code>&lt;?php
/*
Plugin Name: Team Pods UI
Plugin URI: http://example.com/
Description: Customized Pods UI
Version: 0.1
Author: Jonathan Christopher
Author URI: http://jchristopher.me/
*/

function pods_ui_team()
{
  $icon = &#x27;&#x27;;
  add_object_page(&#x27;Team&#x27;, &#x27;Team&#x27;, &#x27;read&#x27;, &#x27;team&#x27;, &#x27;&#x27;, $icon);
  add_submenu_page(&#x27;team&#x27;, &#x27;Team&#x27;, &#x27;Team&#x27;, &#x27;read&#x27;, &#x27;team&#x27;, &#x27;team_page&#x27;);
}

function team_page()
{
  $object = new Pod(&#x27;team&#x27;);
  $add_fields = $edit_fields = array(
        &#x27;name&#x27;,
        &#x27;position&#x27;,
        &#x27;photo&#x27;,
        &#x27;bio&#x27;,
        &#x27;permalink&#x27;,
        &#x27;eom&#x27;);
  $object-&gt;ui = array(
        &#x27;title&#x27;   =&gt; &#x27;Team&#x27;,
        &#x27;reorder&#x27; =&gt; &#x27;displayorder&#x27;,
        &#x27;reorder_columns&#x27; =&gt; array(
             &#x27;name&#x27;      =&gt; &#x27;Name&#x27;,
             &#x27;position&#x27;  =&gt; &#x27;Position&#x27;),
        &#x27;columns&#x27; =&gt; array(
             &#x27;name&#x27;      =&gt; &#x27;Name&#x27;,
             &#x27;position&#x27;  =&gt; &#x27;Position&#x27;,
             &#x27;created&#x27;   =&gt; &#x27;Date Created&#x27;,
             &#x27;modified&#x27;  =&gt; &#x27;Last Modified&#x27;
             ),
        &#x27;add_fields&#x27;  =&gt; $add_fields,
        &#x27;edit_fields&#x27; =&gt; $edit_fields
		);
  pods_ui_manage($object);
}

add_action(&#x27;admin_menu&#x27;,&#x27;pods_ui_team&#x27;);

?&gt;</code></pre>
<p>While it looks very similar to the Pods UI plugin we developed earlier, you&#8217;ll want to note the subtle difference:</p>
<pre class="sh_php"><code>&#x27;reorder&#x27; =&gt; &#x27;displayorder&#x27;,
&#x27;reorder_columns&#x27; =&gt; array(
     &#x27;name&#x27;      =&gt; &#x27;Name&#x27;,
     &#x27;position&#x27;  =&gt; &#x27;Position&#x27;),</code></pre>
<p>These new entries are very important, as they enable the sorting itself, as well as tell Pods which column to use when applying the new sort order. When you break it down it&#8217;s quite simple. You define <code>reorder</code> with the <code>number</code> column you set up and would like to use to control the sort order, and <code>reorder_columns</code> are the table columns that appear on the reorder page in the WordPress admin. After modifying your plugin with the following, a new element will be included on the listing page:</p>
<p><img src="http://mondaybynoon.com/images/pods/sorting/02-reorder-button.jpg" alt="Our new Reorder button" /></p>
<p>Clicking that button will reload the page and bring the user to a page dedicated to managing the order of the Pods entries:</p>
<p><img src="http://mondaybynoon.com/images/pods/sorting/03-reorder-page.jpg" alt="Our new Reorder page" /></p>
<p><strong>Beautiful!</strong> Our user can drag and drop to reorder their entries on the fly, click Update Order at the bottom, and everything is taken care of for us.</p>
<h2>Pods never disappoints</h2>
<p>I hope that these last couple basic features give you enough information to really get started working with Pods. The developers have really put a lot of time, effort, love, <strong>and thought</strong> into the implementation and I can&#8217;t thank them enough. If you&#8217;ve found yourself embracing Pods, please take a moment and <a href="http://pods.uproot.us/">donate to the project</a> as I know for a fact they&#8217;re working night and day to make Pods that much better with every release.</p>
<h4>The Pods CMS Series on <abbr title="Monday By Noon">MBN</abbr></h4>
<p>This article is the <strong>sixth</strong> in a series for Monday By Noon dedicated to <a href="http://pods.uproot.us/">Pods CMS</a>.</p>
<ol>
<li><a href="http://mondaybynoon.com/2010/01/04/introduction-to-pods-cms-wordpress/">An Overview of and Introduction to Pods CMS for WordPress</a></li>
<li><a href="http://mondaybynoon.com/2010/01/04/pods-basics-installation-and-setup/">Pods Basics: Installation and Setup</a></li>
<li><a href="http://mondaybynoon.com/2010/01/04/pulling-pods-data/">Pods Basics: Pulling Pods Data to your Theme</a></li>
<li><a href="http://mondaybynoon.com/2010/01/04/pods-ui-intro/">Pods UI: The Latest and Greatest Addition to Pods</a></li>
<li><a href="http://mondaybynoon.com/2010/01/11/how-to-use-pick-columns-relationships-in-pods/">How to use Pick Columns (Relationships) in Pods</a></li>
<li><a href="http://mondaybynoon.com/2010/01/25/pods-pagination-sorting/">The Last of the Pods Basics: Pagination and Sorting</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://mondaybynoon.com/2010/01/25/pods-pagination-sorting/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk (enhanced) (user agent is rejected)
Database Caching 9/15 queries in 0.010 seconds using disk

Served from: mondaybynoon.com @ 2010-09-09 12:54:27 -->