Pods Basics: Pulling Pods Data to your Theme

Posted: January 04, 2010 Comments(65)

NOTE: This tutorial series is extremely out of date, please see http://pods.io/tutorials/

If you haven’t had a chance to read the first two articles in the series, I would definitely suggest taking a few minutes to read both An Overview of and Introduction to Pods CMS for WordPress as well as Pods Basics: Installation and Setup. There are details discussed in each article explaining how we’ve worked our way to this stage, pulling data from Pods into our theme.

Pods Pages

Pods comes standard with a feature called Pods Pages baked right in. There is a ton of documentation available in the User Guide, and an entire section set up in the Pods admin screens:

Pods Pages in the Pods admin

While I’m really impressed with the Pods Pages implementation, I actually prefer not to use it. Instead, I like to integrate Pods itself into my theme files. I like to work with my hands a bit dirty when it comes to plugins, and would rather work with PHP itself in my favorite text editor the way I normally would when developing a WordPress theme. Thankfully, Pods has done a fantastic job with supporting developers like me. For the time being, we’re going to skip the Pages section of the Pods admin, and crack open our template files themselves.

Setting up our Team page

For the purposes of this example, I’m going to work with the default WordPress theme that ships with every download. I’m going to create a really generic template that we can work with:

<?php

/* Template Name: Team */

get_header(); ?>

  <div id="content" class="narrowcolumn" role="main">

    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <div class="post" id="post-<?php the_ID(); ?>">
    <h2><?php the_title(); ?></h2>
      <div class="entry">
        
        <?php the_content(); ?>
        
        <h2>Our Team</h2>
        
        <?php
          $team = new Pod('team');
          $team->findRecords('name ASC');       
          $total_members = $team->getTotalRows();
        ?>
        
        <?php if( $total_members>0 ) : ?>
          <?php while ( $team->fetchRecord() ) : ?>
            
            <?php
              // set our variables
              $member_id        = $team->get_field('id');
              $member_name      = $team->get_field('name');
              $member_position  = $team->get_field('position');
              $member_photo     = $team->get_field('photo');
              $member_bio       = $team->get_field('bio');
              $member_eom       = $team->get_field('eom');

              // data cleanup
              $member_bio       = wpautop( $member_bio );
              $member_photo     = $member_photo[0]['guid'];
            ?>
            
            <div class="member" id="member<?php echo $member_id; ?>">
              <h3><?php echo $member_name; ?></h3>
              <h4><?php echo $member_position; ?></h4>
              <?php if( !empty( $member_photo ) ) : ?>
                <img src="<?php echo $member_photo; ?>" alt="Photo of <?php echo $member_name; ?>" />
              <?php endif ?>
              <?php echo $member_bio; ?>
            </div>
            <!-- /member -->
            
          <?php endwhile ?>
        <?php endif ?>
          
      </div>
    </div>
    <?php endwhile; endif; ?>
  
  </div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

At first glance, it may look like there is a ton going on here but once we break it down, you won’t be very intimidated, I promise!

From a really high level, we’re working with a very basic WordPress template file here. The interesting bits begin with:

$team = new Pod('team');

This is huge! What we’re doing here is defining $team as a Pods object, ready to interact with the data we’ve entered. When we fire:

$team->findRecords('name ASC');

We’re calling a Pods function that lets us directly work with the existing data. If you check out the User Guide for findRecords you’ll discover the various parameters available to us. We can control the order in which the data is returned, the number of records per page, limit the returned data based on certain criteria, and even use our own SQL to pull the data. In this example, the only parameter we’re passing orders the returned data by our name column. A ton of power lies in findRecords, and subsequent articles will cover much of what you can do when pulling your Pods data.

When we fire:

$total_members = $team->getTotalRows();

We’re giving ourselves a reference to check against that tells us just how many records are in the current Pod. This allows us to run a conditional to check whether we even need to continue any further:

if( $total_members>0 )
{
	// work with our data
}

Once we’ve established that we do indeed have data with which to work, we get to the other really exciting part of Pods:

<?php while ( $team->fetchRecord() ) : ?>
            
  <?php
    // set our variables
    $member_id        = $team->get_field('id');
    $member_name      = $team->get_field('name');
    $member_position  = $team->get_field('position');
    $member_photo     = $team->get_field('photo');
    $member_bio       = $team->get_field('bio');
    $member_eom       = $team->get_field('eom');
  
    // data cleanup
    $member_bio       = wpautop( $member_bio );
    $member_photo     = $member_photo[0]['guid'];
  ?>

<?php endwhile ?>

We’re running a couple of Pods-specific functions here that you’ll want to become familiar with:

fetchRecord
Retrieves the next record from our $team object
get_field
Retrieves the data for a specific column (referenced by its given name when the Pod was created)

So what we’re doing with this while is looping through all available records in our Team Pod. We’ve only hit this loop because of the preceding conditional that checked to make sure there was at least one record in the first place. Each field is assigned to a variable for future reference. We’re also able to format the data should the need arise. For example, when it comes to paragraph columns, I like to fire wpautop to ensure the markup is cleaned up a bit prior to my use.

Note: File upload columns return an array no matter what when get_field is fired. The array consists of a number of fields, guid being the actual location of the file, and more than likely the most common field you’ll be using.

As it stands, we’ve defined all the variables we’d like to work with, so it’s a matter of dumping them out as you would any other time:

<div class="member" id="member<?php echo $member_id; ?>">
  <h3><?php echo $member_name; ?></h3>
  <h4><?php echo $member_position; ?></h4>
  <?php if( !empty( $member_photo ) ) : ?>
    <img src="<?php echo $member_photo; ?>" alt="Photo of <?php echo $member_name; ?>" />
  <?php endif ?>
  <?php echo $member_bio; ?>
</div>
<!-- /member -->

Giving each Team member a dedicated page

While it’s great that we can pull all this data in any way we’d like, Pods lets us take things even further by taking advantage of the slug column we set up and implemented. First, you’ll need to confirm that you’ve properly set up your .htaccess file, and permalinks are working properly. This is essential. The next thing we’ll need to do is make a quick change to our (now) Team index page:

<?php

/* Template Name: Team */

get_header(); ?>

  <div id="content" class="narrowcolumn" role="main">

    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <div class="post" id="post-<?php the_ID(); ?>">
    <h2><?php the_title(); ?></h2>
      <div class="entry">

        <?php the_content(); ?>

        <h2>Our Team</h2>

        <?php
          $team = new Pod('team');
          $team->findRecords('name ASC');       
          $total_members = $team->getTotalRows();
        ?>

        <?php if( $total_members>0 ) : ?>
          <ul>
            <?php while ( $team->fetchRecord() ) : ?>

              <?php
                // set our variables
                $member_id        = $team->get_field('id');
                $member_name      = $team->get_field('name');
                $member_position  = $team->get_field('position');
                $member_slug      = $team->get_field('permalink');
              ?>

              <li>
                <a href="<?php echo get_permalink(); ?><?php echo $member_slug; ?>/">
                  <?php echo $member_name; ?> - <?php echo $member_position; ?>
                </a>
              </li>

            <?php endwhile ?>
          </ul>
        <?php endif ?>

      </div>
    </div>
    <?php endwhile; endif; ?>

  </div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Instead of looping through our data and dumping out everything on a single page, we’ll now have an unordered list including list items containing the team member name and position, linking to his unique URL by using the automatically generated slug Pods has provided. If you save this revised template, you’ll see that the team members are listed properly, but clicking his link results in a 404 page not found. That’s because we haven’t told Pods to take over when it comes to these links. This is where we’ll return to Pods Pages.

Click Pods in the left hand WordPress admin navigation, and select Pages from the top of the resulting page, we’re going to Add new page:

Adding a new Pods Page

Giving your Pods Page the proper name is essential, so mind your spelling, and make sure your page name is acceptable. Of particular note here is the /* portion of our Page name. Since team/ has already been claimed, we’re going to let WordPress have it. We only want to use this Pods Page when we’re trying to view a particular Team member page, hence the wildcard. When naming Pages with a wildcard, Pods will recognize that it should look for anything with team/ in the URL, followed by another URL segment.

Once you’ve created the team/* page, we’ll need to create a new WordPress template.

Alternative Pods Pages setup

In this case, I opted to set up the Team index page as a WordPress page. Alternatively, we could have set up a new Pods Page named team, defined our template file, and continued without problem. I sometimes prefer to add the ‘index’ type pages as WordPress pages depending on the client, as well as the other pages of the site. I’ll usually create an index page as a WordPress page so I can still make use of the user defined title and content, and dump out the Pods data after that. Sometimes, however, you won’t want the client adding their own content to the page. If that’s the case, it would make sense to create the index page as a Pods Page instead of a WordPress Page.

Setting up our Team member template

We’ve got our Team index template, but we haven’t yet told Pods which template to use for our team/* page. Let’s create it:

<?php

/* Template Name: Team - Member */

get_header(); ?>

  <?php

    $found_member = false;

    global $pods;
    $member_slug  = pods_url_variable(-1);
    $member       = new Pod('team', $member_slug);

    if( !empty( $member->data ) )
    {
      $found_member = true;

      // set our variables
      $member_id         = $member->get_field('id');
      $member_name       = $member->get_field('name');
      $member_position   = $member->get_field('position');
      $member_photo      = $member->get_field('photo');
      $member_bio        = $member->get_field('bio');
      $member_eom        = $member->get_field('eom');
      
      // data cleanup
      $member_bio        = wpautop( $member_bio );
      $member_photo      = $member_photo[0]['guid'];
    }
  ?>

  <div id="content" class="narrowcolumn" role="main">

    <?php if( $found_member ) : ?>

      <div class="post" id="post-<?php echo $member_id; ?>">
        <h2><?php echo $member_name; ?></h2>
        <div class="entry">
          <h4><?php echo $member_position; ?></h4>
          <?php if( !empty( $member_photo ) ) : ?>
            <img src="<?php echo $member_photo; ?>" alt="Photo of <?php echo $member_name; ?>" />
          <?php endif ?>
          <?php echo $member_bio; ?>
        </div>
      </div>

    <?php else: ?>
	
      <div class="post">
	    <h2>Team Member Not Found</h2>
	    <div class="entry">
	      <p>Sorry, that Team member could not be found!</p>
	    </div>
	  </div>
	
    <?php endif ?>
  
  </div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Save this as a new template file. As a result of the AJAX nature of Pods, we’ll need to ‘cycle’ the Pods Pages page by hitting Pods in the sidebar, choosing Pages from the tabs up top, and choosing our newly created team/* from the dropdown. Our Page will load, and the field we’ll need to pay particular attention to is the -- Page Template -- dropdown in the lower right. Select our newly created Team - Member entry and click Save changes:

Adding a new Pods Page

You can now head back to our team index, hit a link in our Team list, and check out the new one-off page for each Team member!

A few new things are happening in this template. We’ll focus on the following snippet:

global $pods;
$member_slug  = pods_url_variable(-1);
$member       = new Pod('team', $member_slug);

First, we need to bring in the global $pods; variable; we’ll need it. Pods has a nice function available called pods_url_variable() that lets us pull URL segments and use them as variables. We know that the last segment on this page is going to be our Team member slug, so we’ll go ahead and set that.

When we fire:

global $pods;
$member_slug  = pods_url_variable(-1);
$member       = new Pod('team', $member_slug);

We’re passing that slug as a parameter when initially defining our Pods object. Under the hood, Pods is pulling a record from the database that has a permalink that matches the string we’re passing. Wicked handy. Since we’re basing our data on the passed slug, we’re going to need to consider the possibility of an invalid URL, we can use a quick conditional:

if( !empty( $member->data ) )
{
  // dump our data
}

There are a number of ways you can check to see if a record is returned, just make sure you have a fallback in place. Once we know that we have data to work with, we can fire get_field() and pull whatever we need. Easy peasy.

The Pods CMS Series on MBN

This article is the third in a series for Monday By Noon dedicated to Pods CMS.

  1. An Overview of and Introduction to Pods CMS for WordPress
  2. Pods Basics: Installation and Setup
  3. Pods Basics: Pulling Pods Data to your Theme
  4. Pods UI: The Latest and Greatest Addition to Pods
  5. How to use Pick Columns (Relationships) in Pods
  6. The Last of the Pods Basics: Pagination and Sorting

Get my newsletter

Receive periodic updates right in the mail!

  • This field is for validation purposes and should be left unchanged.

Comments

  1. This series is very handy, so thanks!

    I am in the process of building a portfolio site using WordPress with cateogries separating each item type (blog posts, portfolio entries, featured items and so on). This is quickly becoming a nightmare to manage and I find I am laying hack upon hack to keep everyting in line — pagination on a category page view, archive views for different categories etc. It will be much simpler to keep the posts section for posts and separate other content types accordingly.

    I was aware of pods, but had never really looked into it — these posts are just the push I needed.

  2. Jon,

    Thanks for the awesome series. I wanted to ask how you would handle pagination with this implementation. I realized that folks are adding more data then I thought so the page is getting super long.

    Thanks!
    Andrej

  3. That’s such a great tutorial. I’ve just read these first three and I’ve already got a pod set up and working in my theme that I know my client will be able to maintain.

    Thanks so much for making it so accessible!

  4. Like Andrej, I too returned here looking for info on “how you would handle pagination with this implementation.”

    It would make a nice addition / follow-up to the “Pulling Pods Data to your Theme” section of this awesome series.

    Thanks for the great tutorial!

  5. Let me get this straight, if I go to my Dreamweaver and make a template page (similar to what you have above) then upload it to my server, all I will have to do is go to the Pods Pages area, create my new Page (“products”), leave the large writing area blank, leave the pre-code blank, and choose my template from the dropdown box and hit save…right?

    Then for my products/* page (detail page) I do the exact same thing. So, essentially, I never make a Template inside the PODS area right?

  6. This page has been my constant companion for the last week. Thanks for putting together such a clear and informative tutorial. Your hard efforts are really appreciated.

  7. I didn’t really hook into it, it just works because technically the team ‘index’ page is still a WordPress page. Perhaps this is bad practice in the long run, though.

  8. wow, this has been amazing helping me going with pods. Whole new worlds are opening up! This is great!

    I have a question though, the code you use above to display the picture:

    $community_pic = $community_pic[0][‘guid’];

    this isn’t pulling any image for me, I am using this code to display it:

    Photo of

    I read your note about the file upload field, but I’m not sure what I’m missing…

  9. I am curious to know how you could incorporate a Pods into a javascript based content area? I already know how I will integrate this bit of code into my WordPress theme using the javascript and CSS:

    http://www.dynamicdrive.com/dynamicindex5/overlapcontent.htm

    Trouble is, the content area is going to have a width lock on it, making it no wider than 400px. How would I make sure that the pods doesnt exceed 400px, ruining the look of the content area?

  10. Great tutorial. I’ve almost got what I need to get done on my site as a Trip log. One of the things i have done is used a file field, similar to your image field.
    However the issue is is I try to wrap the echo $filename in an tag it strips the slashes and instead creates double quotes, breaking the ability for me t link to the file.

    Code is as follows: Elevation and Distance Profile:<A HREF"

    The output comes out like this:
    Elevation and Distance Profile:http://www.tiredofit.ca/wp-content/uploads/2009/11/2009-09-14T17_0.gpx</a>

    Any idea on how to fix?

  11. Hi everyone, I’m glad you have questions! I’d love to help answer them, but if we can post all questions (as opposed to comments) on the Pods CMS forums the answers will be saved in the most central place for other people to check out. Thanks so much in advance!

  12. Hi, thanks for the great tuts. I was looking for this for a long time now.

    I have a question..

    I used your example above to make a page. But now i want the thumbnail to show instead of the ‘normal’ image. I uploaded a picture, wordpress automatically creates a thumbnail for it. How can i pull it from the library. I first thought it was simple: just at: -150×150.jpg (wp generated this) after . But then the path will be http://pathtoimage/imagename.jpg-150×150.jpg.

    Hope you can help me. I installed a package called “image sizes” it generates 4 display helpers. When i select one nothing happens.

    You can check my template here: http://pastebin.com/mH30ckSU

  13. I was hoping that this would stick to Pod “basics”…..and not delve into php coding.

    Oh well, one man’s basics is another man’s misfortune.

    Back to the drawing board…

  14. Just thought I’d chip in with how useful I’ve found the series up to now and this post in particular. I will probably be using Pods for a very simple events listing for a client of mine. I’m looking forward to finding out more and implementing it.

    I have loads of questions so I’m headed over to the Pods forums now. Cheers, Jonathan!

  15. I was wondering how you handled Image Resizing in Pods. I did play around with the Image Sizes package developed by sc0ttclark but it doesn’t seem to work with this example. Any thoughts?

  16. This is just what I’ve been looking for. I spent days reading books on PHP and MySQL only to realise hard core programming is not the best use of my time – I’m a journalist not a developer.

  17. For the main ‘Team’ page im not seeing any content within the

    How could this be?
    The Team Member pages work fine btw/

  18. Great article Jonathan – thanks for making it super clear.

    Link at the top is 404:
    /2010/01/04/pods-basics-installation-setup/

    Should be
    /2010/01/04/pods-basics-installation-and-setup/

  19. Wow Jonathan — this is an amazingly helpful tutorial! Thank you so much for taking the time to put this together.

    (Love your site by the way — it looks great)

  20. Jonathan,

    How would I combine both the list and the view on one page? In other words, if you wanted to list the team members in a side nav on the left and display the current team member within the main content to the right.

    BTW, stumbling across your 6 part series is the only reason I even gave Pods a chance and it’s doubtful I’ll do it any other way. Excellent resource you’ve shared here!

  21. Hi Lee,

    That’s no problem, although you’ll have to get a bit creative here. What I would suggest is pulling all of the team members and instead of outputting data as per the example above, saving that data to a new associative array. From there, you’d loop through your new array when dumping out the list of team members, and when you’re on the ‘content’ side you’d loop through again and only output the applicable team member. One way to do that would be to simply use a conditional that compares pods_url_variable(-1); to the array key in which you’ve stored the member slug. Does that make sense?

    Very glad you’re finding the tutorials useful!

  22. Thanks for the quick response!

    I’ll give it my best! I’m definitely a designer and front-end developer first and foremost. Would you be able to recommend anyone familiar with Pods that could write an example of this for me? Paid work, of course.

  23. I’ve spent the last couple of years hacking various sites int WordPress, but I’ve been jumping through hoops trying to accomplish what Pods has let me do in a 3 very quick tutorials.

    Thank you so much.

  24. Excellent Jonathan. Your turorial are very clear and easy to understand.
    Pods are surely going to make WP the true CMS it should be for developers who want more than a simple blog with some CMS capabilities. Instead of hacking and bashing to make it fit we will be able to develope custom solutions with eaze as and when required.

    Lee

  25. In your Team template you begin with the standard WordPress loop:

    <?php if (have_posts()) : while (have_posts()) : the_post();

    Can you explain why you would do that? I don't understand what posts you are trying to pull in. I had to remove the loop in order for the template would work for me.

  26. Same here. Works fine without The Loop, and I can’t figure any reason why it would be there.

  27. Hey guys, I left that bit in there because I was using a WordPress page for that template which pulled in Pods data. This gives the client the ability to use the regular WordPress page content area to have some content above the team listing if they want.

  28. One more question. Have you used this with the Thematic theme framework? I can’t get the theme hooks (like theamatic_sidebar()) to work in page templates used in this way with Pods. If I use the same template with WP pages, it works fine. I’ve posted the question on the Pods Q&A, but no responses yet.

  29. No, unfortunately I don’t have any experience with Thematic, I’ll make a note to poke around a bit though. Pods pages aren’t WordPress Pages which could be causing the Thematic hooks to be failing. I’ll try to reach out to the Thematic devs as soon as I can.

  30. Thanks for your help. I would imagine this is an issue for any theme that creates its own hooks. I’m hoping there’s some way I can specifically register these hooks (perhaps in the precode?), but I don’t know WordPress well enough to sort that out.

  31. Ok, one more update to this problem. After poking around a bit, it appears that the Thematic hooks are called, but any Thematic hook that uses widgets will not show up. Hooks like thematic_header() and thematic_navigation_above() seem to work normally.

  32. One more comment about this. I’ve decided to move over to the Carrington JAM framework, which is a very different kind of theme framework (not a parent / child configuration). In my initial tests, widget sidebars work normally on Pod pages using this system.

    But I think this is an issue that will come up more and more, as Thematic seems to be gaining popularity and has committed developers.

  33. I am familiar with adding pagination to the team page, but am clueless on how to handle it for the individual team members.

    For the team member template, how could you implement pagination (or atleast some sort of a ‘back’ / ‘next’ function), to quickly go to the next member?

    Great series by the way

  34. I love PODS and have page templates to pull the data to my theme, but we now use a different theme for mobile, so those pages show no content when viewed on a mobile device. Are there ways to display PODS data other than page templates to make the data theme independent?

  35. You could either copy the theme files into your mobile theme, or alternatively you could put your theme file code directly into Pods itself using the provided code area.

  36. I’m trying to display (in the new pods version) a paragraph text. It seems to insert between each line, even if I process it with wpautop(). I just want it to display the text with at double line breaks, no divs. Help?

  37. First off… Killer article! However I suck. I just realized after many hours that the permalinks don’t like integers. I am using the latest PODS and everything is working fine. But when I try to use numbers e.g. /1234/ it goes straight to the else statement. Any ideas?

  38. I seem to be having the same issue. For some reason, the page doesn’t exist but I can create the http://localhost:8888/team page but the detail page doesn’t work. I’ve successfully created both the list and detail pages using the Pods templates and pages. For some reason the code isn’t pulling the data from the database.

  39. I followed your instruction step by step, and thanks everything works perfectly.

    Just one problem so far, here’s the recap:
    1. I left blank the “slug” for every item i created in the pods area, so it would be named by default.
    2. I followed all your instruction above without error, i can see all the items within my page.
    3. I created a page for each item.

    Now, here’s the problem: i checked at the all items page, i noticed that the slug is blank (is there something wrong here?) even when i try to check it out by php echo item_slug, it’s still blank.

    But when i check the page for each item, for example: “my website.com”/all-products/item1 … there’s no error, i can see the product, i can see the picture, so on.

    And one thing, if i put wrong item on the url, for exampe “my website.com”/all-products/item-1000 (there’s no item here for example), it returned with “sorry the product couldn’t be found” (just like i copy-paste from your script above”.

    Any idea what’s going on with my pods?

    Thanks,
    Rio

  40. No #3 is the step where I go to the Pods menu and created a page with wild card ( “all-products”/*)

    But thank you, last night i have managed to solve this problem, seems that it’s all because of my fault, i didn’t see that the field in your sample for slug named as “permalink”, but in my Pods it’s named as slug.

    So when i changed the script to “slug” everything now works in order.

    Thank you.

  41. great tutorials jonathan. i hate feeling like a newbie again, but your articles are helping me get a grip on pods. any chance you’ll be writing some new ones? i’d love to see how to tie it all together into a plugin that you can easily install on multiple sites instead of manually setting up the pod every time. specifically, i am trying to import the pod data on activation, most of the UI stuff I figured out from looking at the Eventbright Pods plugin and reading your series. Next I need to get templates going. I tried making one when I got to that part of the series, but it was in my child theme and didn’t show up in the templates drop-down list. probably better to make it a pod page ‘package’ anyway so the plugin can be whole. thanks for all the help!

  42. Hi Kathy, yes, I do plan on writing some more Pods-focused tutorials. The next few I have planned are a bit more specific in nature and discuss more specialized implementations to accomplish a specific task, but they’re coming! I imagine I’ll nearly re-write the series when Pods 2.0 releases as well.

  43. Awesome series, won me over to use pods. I am trying to concatenate the slug with the Name which is required and another field. Any suggestions on that?

    So for example the name is Someones First Name and the second field would be last_name giving me a url of

    example.com/pod/firstname-lastname

Leave a Reply

Your email address will not be published. Required fields are marked *