post

Best Plugins for Creating Custom Post Types

Content Types

Understanding WordPress Custom Post Types

Do you hate coding and simply want a graphical user interface to create custom post types? Or would you rather use a plugin to save time to create custom post types? While I personally believe hand coding the custom post types and the metaboxes are easier, there are some really good plugins that will help you accomplish all that you want to accomplish with Custom Post Types.

So here are my Top Custom Post Type Creating Plugins.

Premium

  1. Easy Content Types: Easy Content Types provides an extremely easy to use and intuitive interface for creating custom post types, taxonomies, and meta boxes. It allows for custom categories, custom tags, and custom input fields.
  2. GD Custom Posts And Taxonomies Tools: Can be used to expand custom taxonomies and custom post types support. Plugin adds many tools including custom post types and taxonomies management and widget for taxonomies terms cloud.
  3. Post Type Constructor Kit: PCK is a suite of plugins consisting of the post type constructor kit, meta boxes kit, role manager kit, and widget kit giving the possibility of 15 different types of metaboxes including text, WYSIWYG, radio, checkbox, select box, image, file, date and time, tab, gallery, panorama viewer, contact form, comments, youtube, and Google map. This plugin also has a forum support channel apart from WordPress.
  4. WPMU Dev’s CustomPress: The ultimate plugin for transforming WordPress from a blogging platform into a full blown CMS system using your own custom post, taxonomies and custom field creator. And combine this with the Recent Custom Post Type Widget for even further usability.

Free

  1. Custom Post Type UI: Great interface, ability to create taxonomies, good support community. Lacks custom field creation functionality; however, only free plugin to export to proper universal PHP code. Plugin Site.
  2. More Types: Integrates perfectly with More Taxonomies, to create additional taxonomies besides Categories and Tags, and More Fields, to create additional input fields easily. More Types has the ability to assign additional features beyond the typical WordPress supports to include theme based features like genesis-seo, etc. While More Types is a standalone plugin, combined with the suite of More Plugins, it is robust and powerful. More Plugins Site.
  3. WP Easy Post Types: Can select columns to show. In-built custom field creation (albeit limited) that will be attached to your new custom post type, and each field will be saved in the WordPress database as a custom field to take advantage of the WordPress query rules. However, it has a somewhat “confusing” Admin menu and support is not free. This could be a premium plugin.
  4. Ultimate Post Type Manager: This is an Easy to use Plugin to Create, Customize, Manage Custom Post Type. Do all you want to do with you Posts. It can also be used with Ultimate Taxonomy Manager.
  5. Content Types: Content Types is a WordPress plugin that helps you create custom content types in WordPress. It allows for custom categories, custom tags, and custom input fields. From what I can tell, this is the only plugin that makes some metabox/custom fields required for posting.
  6. WP Post Type UI: Inspired by “Custom Post Type UI” this plugin that gives you what have always wanted for creating dynamic post types and custom taxonomies in WordPress. The UI is made in true WP style, with a smooth integration to give nice and easy access to create and edit post types and taxonomies.
  7. GD Custom Posts And Taxonomies Tools: Can be used to expand custom taxonomies and custom post types support. Plugin adds many tools including custom post types and taxonomies management and widget for taxonomies terms cloud. For a comparison with the pro version: see the comparison chart.
  8. Simple Custom Post Types: Makes managing custom post types even simpler, removing the need for you to write any code. Excerpt update your theme. This plugin provides a nice interface and easy access. The plugin provides almost all the parameters of the WordPress CPT API. It is possible to manage the permissions of custom post types such as articles or pages. Or create a full set of custom permissions.
  9. Custom Content Type Manager: Create custom content types (AKA post types), standardize custom fields for each type, including dropdowns and images. This gives WordPress CMS functionality making it easier to use WP for eCommerce or content-driven sites. Plugin Site.
  10. Custom Press: Custom Press allows you to easily add your own custom post types and custom taxonomies into WordPress, which you can also toggle on and off more advanced options for creating custom post types and custom taxonomies. It also features an ‘Embed Code’ option is available if you would prefer to put your custom post types and custom taxonomies directly into a theme or plugin.
  11. CMS Press: CMS Press opens up the ability to create and manage custom content types and taxonomies for your WordPress site. It adds the flexibility to have more than just posts and pages for content by allowing the user to register their own post_types that can use their separate theming from the post and page template along with its own permalink structure.
post

Helpful Custom Post Type and Custom Taxonomy Functions

Understanding WordPress Custom Post Types

Here are two great posts regarding custom post types’ functions: An Important Update: WordPress 3.0 Post Types And Taxonomies, from New2WP written by  Jared (@Tweeaks), and Custom Post Types in WordPress from Justin Tadlock (@justintadlock). that I wanted to reproduce in part in this series.

The following are functions you can use for various things related to post types. The function name is linked to the line in /wp-includes/post.php where it is created for those that would like to check out the source code which makes them work. I’ve also added a short description for each that is used in the source to describe them [slightly modified by Travis Smith].

Post Type Functions:

  • is_post_type() – Checks to see if current post is of a specified post type.
    [php]<?php
    if ( is_post_type( ‘zombie’, $post_id ) )
    echo ‘This is a not a blog post. It is a zombie!’;
    else
    echo ‘This is not a zombie. [insert sad face]‘;[/php]
  • get_post_types( $post ) – Get a list of all registered post type objects.
    • $args - An array of key => value arguments to match against the post type objects.
    • $output - The type of output to return, either post type ‘names’ or ‘objects’. ‘names’ is the default.
    • $operator - The logical operation to perform. ‘or’ means only one element from the array needs to match; ‘and’ means all elements must match. The default is ‘and’.
    • Returns an array listing post type names or objects.
  • get_post_type_object() – Retrieves a post type object by name
    [php]$post_type = get_post_type_object( ‘zombie’ );

    if ( $post_type->show_ui )
    custom_function_name();
    [/php]

  • register_post_type() – Register a post type. Do not use before init.
    • A simple function for creating or modifying a post type based on the parameters given.
    • The function will accept an array (second optional parameter), along with a string for the post type name.
  • get_post_type_capabilities() – Builds an object with all post type capabilities out of a post type object.
  • Accepted keys of the capabilities array in the post type object:
    • edit_post - The meta capability that controls editing a particular object of this post type. Defaults to “edit_ . $capability_type” (edit_post).
    • edit_posts - The capability that controls editing objects of this post type as a class. Defaults to “edit_ . $capability_type . s” (edit_posts).
    • edit_others_posts - The capability that controls editing objects of this post type that are owned by other users. Defaults to “edit_others_ . $capability_type . s” (edit_others_posts).
    • publish_posts - The capability that controls publishing objects of this post type. Defaults to “publish_ . $capability_type . s” (publish_posts).
    • read_post - The meta capability that controls reading a particular object of this post type. Defaults to “read_ . $capability_type” (read_post).
    • read_private_posts - The capability that controls reading private posts.Defaults to “read_private . $capability_type . s” (read_private_posts).
    • delete_post - The meta capability that controls deleting a particular object of this post type. Defaults to “delete_ . $capability_type” (delete_post).
  • get_post_type_labels( $post_type_object ) – Builds an object with all post type labels out of a post type object.
  • Accepted keys of the label array in the post type object:
    • name - general name for the post type, usually plural. The same and overriden by $post_type_object->label. Default is Posts/Pages
    • singular_name - name for one object of this post type. Default is Post/Page
    • add_new - Default is Add New for both hierarchical and non-hierarchical types.
    • add_new_item - Default is Add New Post/Add New Page
    • edit_item - Default is Edit Post/Edit Page
    • new_item - Default is New Post/New Page
    • view_item - Default is View Post/View Page
    • search_items - Default is Search Posts/Search Pages
    • not_found - Default is No posts found/No pages found
    • not_found_in_trash - Default is No posts found in Trash/No pages found in Trash
    • parent_item_colon - This string isn’t used on non-hierarchical types. (In hierarchical ones the default is Parent Page)
  • _get_custom_object_labels() – Builds an object with custom-something object (post type, taxonomy) labels out of a custom-something object
  • add_post_type_support( $post_type, $feature ) – Register support of certain features for a post type.
  • All features are directly associated with a functional area of the edit screen, such as the editor or a meta box:
    • ‘title’,
    • ‘editor’,
    • ‘comments’,
    • ‘revisions’,
    • ‘trackbacks’
    • ‘author’,
    • ‘excerpt’,
    • ‘page-attributes’,
    • ‘thumbnail’,
    • ‘custom-fields’

    Additionally, the ‘revisions’ feature dictates whether the post type will store revisions, and the ‘comments’ feature dicates whether the comments count will show on the edit screen.

  • set_post_type( $post_id = 0, $post_type = ‘post’ ) – Updates the post type for the post ID.
    • $post_id Post ID to change post type. Not actually optional.
    • $post_type Optional, default is post. Supported values are ‘post’ or ‘page’ to name a few.
    • Return int Amount of rows changed. Should be 1 for success and 0 for failure.
  • get_posts() – Retrieve list of latest posts or posts matching criteria.
  • The defaults are:
    • ‘numberposts’ - Default is 5. Total number of posts to retrieve.
    • ‘offset’ - Default is 0. See { WP_Query::query() } for more.
    • ‘category’ - What category to pull the posts from.
    • ‘orderby’ - Default is ‘post_date’. How to order the posts.
    • ‘order’ - Default is ‘DESC’. The order to retrieve the posts.
    • ‘include’ - See { WP_Query::query() } for more.
    • ‘exclude’ - See { WP_Query::query() } for more.
    • ‘meta_key’ - See { WP_Query::query() } for more.
    • ‘meta_value’ - See { WP_Query::query() } for more.
    • ‘post_type’ - Default is ‘post’. Can be ‘page’, or ‘attachment’ to name a few.
    • ‘post_parent’ - The parent of the post or post type.
    • ‘post_status’ - Default is ‘published’. Post status to retrieve.

Functions For Taxonomies You Should Know About

The following are functions which you can use when working with taxonomies. I’m not going to link to the line of each function or include descriptions of each since the file which contains them is way smaller than posts.php where the post type functions are, so if you’re interested in viewing the source of these you should’ve have a hard time finding the line they are on.

The functions which make up taxonomies are located in /wp-includes/taxonomy.php of the WordPress source.

post

How to Change the Title Text for Your Custom Post Type

Understanding WordPress Custom Post Types

Have you ever wanted to use the Title section, but didn’t want to call it Title? Surely, many of you have wanted to change the text in the title entry bar from the standard ‘Enter title here’ to something more specific for your custom post type. Well, WordPress has a filter for it.

[php]<?php
// Change ‘Enter Title Here’ text for a CPT
function wps_change_default_title( $title ){
$screen = get_current_screen();
$wps_cpt = ‘wps_mycpt’;

if ( $wps_cpt == $screen->post_type ) {
$title = ‘Enter Staff Members Name Here’; //change this to whatever you’d like
}

return $title;
}

add_filter( ‘enter_title_here’, ‘wps_change_default_title’ );
[/php]

post

Example Custom Post Type Tutorials

Understanding WordPress Custom Post Types

In my researching, studying, and writing about custom post types, I have located the following sample custom post types. Some are example tutorials and some aren’t. Some are complete and some aren’t. However, regardless of the state of the various custom post types, it will serve as a good starting point for many of your custom post types. Please feel free to contact me with any more you may know about! This list does not include any custom post types that have been built into plugins that utilize custom post types. For example, Norcross‘s FAQ plugin utilizes custom post types for FAQ’s or Travis Ballard’s TB Testimonials. Plugins are a great place to research and learn more about the manifold purpose that custom post types can take.

My list below includes custom post types on portfolios, events, galleries, photos, podcasts, FAQs, movies, videos, client quotes/praises/testimonials, newsletters, products, before/after images, books, dogs, recipes, coupons, cars, zombies, artists, properties, websites, bookmarks, templates, and even presented as PHP classes. Surely one or some of these will be beneficial for at least one of your projects.

Portfolio:
1. http://www.ashbluewebdesign.com/2010/09/wordpress-portfolio-tutorial-custom-post-types/
2. http://thinkvitamin.com/code/create-your-first-wordpress-custom-post-type/
3. http://www.wpcode.net/how-to-create-wordpress-custom-post-type-1.html/ && http://www.wpcode.net/how-to-create-wordpress-custom-post-type-2.html/
4. http://www.astronautdesigns.com/2010/06/wordpress-3-custom-post-types/
5. http://www.vooshthemes.com/blog/wordpress-tip/create-a-professional-portfolio-using-wordpress-3-0-custom-post-types/
6. http://pippinspages.com/tutorials/stellar-wordpress-portfolio-control-with-custom-post-meta-types/
7. http://redlettersstudio.com/blog/2010/11/29/customizing-wordpress-part-three/

Events:
1. http://www.noeltock.com/web-design/wordpress/custom-post-types-events-pt1/ && http://www.noeltock.com/web-design/wordpress/how-to-custom-post-types-for-events-pt-2/
2. http://wptheming.com/2010/08/how-to-make-an-events-custom-post-type/
3. http://www.problogdesign.com/wordpress/events-list-with-custom-post-types-and-taxonomies/
4. http://headwaythemes.com/tutorials/how-to-create-an-events-page-with-custom-post-types/
5. http://www.designjuices.co.uk/2010/06/tutorial-wordpress-custom-post-types/
6. http://cmstutorials.org/tutorial/view/events_list_with_custom_post_types_and_taxonomies
7. http://sixrevisions.com/wordpress/wordpress-custom-post-types-guide/

Gallery
1. http://www.morgadinho.org/2011/03/01/skeleton-custom-post-type-week4/
2. http://shibashake.com/wordpress-theme/add-custom-post-type-columns & http://shibashake.com/wordpress-theme/modify-custom-post-type-icons & http://shibashake.com/wordpress-theme/add-metabox-custom-post-type

Photo
1. http://wordpress.stackexchange.com/questions/639/creating-an-image-centric-custom-post-type

Podcasts:
1. http://kovshenin.com/archives/extending-custom-post-types-in-wordpress-3-0/
2. http://eastbaywp.com/2010/09/september-2010-meetup-slides-custom-post-type-case-study-podcast/

FAQ:
1. http://net.tutsplus.com/tutorials/wordpress/creating-an-interactive-faq-with-wordpress-and-jquery-ui/ & http://www.code-pal.com/how-to-create-a-faq-page-with-wordpress-and-custom-post-types/ && http://www.freewebgallerys.com/2010/12/04/create-faq-page-wordpress-custom-post-types/

Movies:
1. http://wpengineer.com/1969/impressions-of-custom-post-type/
2. http://mikedance.com/2011/03/how-to-create-custom-post-type-archives-in-wordpress-3-1/

Videos:
1. http://wpworks.wordpress.com/2011/02/15/wordpress-custom-post-types-registering-and-displaying-in-a-very-easy-way/
2. http://wordpress.stackexchange.com/questions/737/implementing-video-of-the-day-feature
3. http://www.andrewdodson.net/2011/02/add-video-embed-meta-boxes-to-custom-post-type/

Client Quotes/Praise
1. http://redlettersstudio.com/blog/2010/07/12/practical-use-case-for-custom-post-types/
2. http://www.amberweinberg.com/working-with-wordpress-3-0s-custom-post-types/

Newsletter
1. http://www.re-cycledair.com/wordpress-3-custom-post-type-tutorial

Products
1. http://net.tutsplus.com/tutorials/wordpress/rock-solid-wordpress-3-0-themes-using-custom-post-types/
2. http://www.bernskiold.com/2010/11/15/adding-your-own-custom-post-type/

Before/After Images:
1. http://sicdigital.com/2010/07/create-custom-post-type-for-image-upload-wordpress3/

Books:
1. http://new2wp.com/pro/wordpress-custom-post-types-and-taxonomies-done-right/

Dogs:
1. http://www.noeltock.com/web-design/wordpress/tutorial-custom-post-types/

Recipes:
1. http://wpmu.org/easy-guide-to-displaying-custom-post-types-in-your-wordpress-theme/

Coupons
1. http://www.catswhocode.com/blog/how-to-create-a-side-blog-with-wordpress-3-0

Cars
1. http://heinencreative.com/archives/tutorials/creating-custom-post-types-in-wordpress-3-0/

Zombies:
1. http://www.slideshare.net/williamsba/custom-post-types-and-taxonomies-in-wordpress && http://www.slideshare.net/williamsba/surviving-the-zombie-apocalypse-using-custom-post-types-and-taxonomies-8058659

Artists:
1. http://www.kinocreative.co.uk/tutorials/using-wordpress-custom-post-types-and-taxonomies/

Properties
1. http://www.wordpresswise.com/custom-post-types-taxonomies-templates-with-a-lightbox-513
2. http://wpsmith.net/genesis/how-to-utilize-agentpresss-settings-custom-fields-in-a-separate-post-type/

Website
1. http://www.wpmayor.com/posts/step-by-step/ultimate-guide-wordpress-custom-post-types/

Bookmarks
1. https://github.com/mfields/mfields-bookmarks

Templates:
1. http://www.wpreso.com/blog/tutorials/2011/02/24/add-multiple-custom-post-types-quickly-and-easily/
2. http://www.wpinsideout.com/your-own-custom-post-types

Class:
1. http://somadesign.ca/projects/smarter-custom-post-types/
2. Links: http://curtishenson.com/wordpress-custom-post-types-and-meta-boxes-example/

post

Helpful Links

Understanding WordPress Custom Post Types

Here are some helpful links to further understand custom post types. Next week, we will be diving into the world of Custom Post Type Plugins.

  1. WordPress Codex: Custom Post Types
  2. WordPress Codex: Register Post Type
  3. Justin Tadlock: Custom Post Types in WordPress
  4. Justin Tadlock: Meta Capabilities (arguments capabilities and capability_type) for Custom Post Types
  5. Kovshenin: Custom Post Types in WordPress 3.0 and Kovshenin: Extending Custom Post Types in WordPress 3.0 by Konstantin
  6. WPSmith: How to Create a WordPress Custom Post Type Template in the Genesis Framework
  7. WP Inside-Out: Advanced Custom Post Types – PHP Class Integration
  8. WP Theming: Custom Post Type Resources
  9. WP Theming: How to Add a Metabox to a Custom Post Type
  10. Justin Tadlock: Showing Custom Post Types On Your Home Blog Page
  11. Justin Tadlock: Meta Capabilities for Custom Post Types
  12. Justin Tadlock: Linking Terms to a Specific Post
  13. WP Engineer’s Impressions of Custom Post Types
  14. FLD Trace: WordPress custom post types, custom back-end columns and post thumbnails
  15. Nielsen Creative Media: How to Develop a Custom Post Plugin with Unique Taxonomy and Tags
  16. Justin Tadlock: Rethinking How News Themes Work
  17. Blogcastor: Submit Post Form for WordPress Custom Post Type
  18. D Baines: WordPress Custom Post Type Search
post

BONUS: Adding a Taxonomy Filter to Your Admin List for a Custom Post Type

Understanding WordPress Custom Post Types
Recently, a friend sent some code over to me, and I thought it would be hugely beneficial for all to see it, especially in this series. For a custom post type that could have a lot of posts (like books) it proves priceless. You can find the original code here.

[php]
// Adding a Taxonomy Filter to Admin List for a Custom Post Type
add_action( ‘restrict_manage_posts’, ‘my_restrict_manage_posts’ );
function my_restrict_manage_posts() {

// only display these taxonomy filters on desired custom post_type listings
global $typenow;
if ($typenow == ‘books_ibm’) {

// create an array of taxonomy slugs you want to filter by – if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
$filters = array(‘genre’, ‘writer’);

foreach ($filters as $tax_slug) {
// retrieve the taxonomy object
$tax_obj = get_taxonomy($tax_slug);
$tax_name = $tax_obj->labels->name;

// output html for taxonomy dropdown filter
echo "<select name=’$tax_slug’ id=’$tax_slug’ class=’postform’>";
echo "<option value=”>Show All $tax_name</option>";
generate_taxonomy_options($tax_slug,0,0);
echo "</select>";
}
}
}

function generate_taxonomy_options($tax_slug, $parent = ”, $level = 0) {
$args = array(‘show_empty’ => 1);
if(!is_null($parent)) {
$args = array(‘parent’ => $parent);
}
$terms = get_terms($tax_slug,$args);
$tab=”;
for($i=0;$i<$level;$i++){
$tab.=’–’;
}
foreach ($terms as $term) {
// output each select option line, check against the last $_GET to show the current option selected
echo ‘<option value=’. $term->slug, $_GET[$tax_slug] == $term->slug ? ‘ selected="selected"’ : ”,’>’ .$tab. $term->name .’ (‘ . $term->count .’)</option>’;
generate_taxonomy_options($tax_slug, $term->term_id, $level+1);
}

}
[/php]

Please let me know what you think!?

post

Displaying Custom Post Types

Understanding WordPress Custom Post Types

There are several ways to display your custom post types:

  1. Display Custom Post Types with Blog Posts
  2. Display Custom Post Types with Custom Loop
  3. Display Custom Post Types via Shortcode

Display Custom Post Types with Posts

To display them with posts on the blog page, you can add this bit of code to your functions.php file:

[php]
add_filter( ‘pre_get_posts’ , ‘wps_add_my_cpt’ );
function wps_add_my_cpt() {
if ( is_home() && false == $query->query_vars['suppress_filters'] ) //if you want it to appear in the feed, comment this line & use the next line
if ( ( is_home() && false == $query->query_vars['suppress_filters'] ) || is_feed() )
$query->set( ‘post_type’ , ‘array( ‘post’ , ‘wps_cars’ );
return $query;
}[/php]

Display Custom Post Types with Custom Loop

WordPress added support for single-type-template in Version 3.0 and for archive-type-template in Version 3.1.

Single template

In the form of the single-type-template. In the same way that posts are shown on their own page with single.php, custom post types will use single-{posttype}.php if it’s available.

So for the above example, you could create a single-wps_cars.php file and the product posts would be shown using that template.

Archive template

In the form of the archive-type-template. In the same way that posts are shown on their own archive with archive.php, custom post types will use archive-{posttype}.php if it’s available.

So for the above example, you could create a archive-wps_cars.php file and the product posts would be shown using that template.

*Note: Use the is_post_type_archive() function to check if the query shows post type archive page, and the post_type_archive_title() to echo the post type title.

Custom Post Type Custom Loops

To create your own custom loop in your page template (or, for Genesis users, you can see my post, <a href=”http://wpsmith.net/frameworks/how-to-create-a-wordpress-custom-post-type-template-in-genesis/” target=”_blank”>How to Create a WordPress Custom Post Type Template in Genesis</a>), you can add this bit of code:

[php]$args = array( ‘post_type’ => ‘wps_cars’ , ‘posts_per_page’ => 5 , ‘orderby’ => ‘post_title’ , ‘order’ => ‘ASC’ );
$carsloop = new WP_Query( $args );
if ( $carsloop->have_posts() ) {
$output = ‘<div id="cars-content">’;
while ( $carsloop ->have_posts() ) : $carsloop ->the_post();
$output .= the_title();
$output .= ‘<div class="entry-content">’;
$output .= the_content();
$output .= ‘</div>’;
endwhile;
$output .= ‘</div>’;
}
else
$output = ‘<p>No cars were found.</p>’;
[/php]

Display Custom Post Types via Shortcode

One way to display custom post types is to create a shortcode (thanks to Mark Jaquith, @markjaquith) to display them on pages or posts. There are a variety of reasons to use them and a variety of reasons that these can be abused. However, the benefits outweigh the risks and if done well, this can improve the user experience.

To display the cars custom post type that we have been working with, simply create a page and insert [ cars] (without the space in the front) to display wps_cars posts as a posts page (except we are ordering by Post Title in ascending order).

[php]function wps_cars_posting() {
global $post;
$xglobals = $GLOBALS;
$args = array( ‘post_type’ => ‘wps_cars’ , ‘posts_per_page’ => 5 , ‘orderby’ => ‘post_title’ , ‘order’ => ‘ASC’ );
$carsloop = new WP_Query( $args );
$output = ”;
if ( $carsloop->have_posts() ) {
while ( $carsloop->have_posts() ): $carsloop->the_post();
$output .= ‘<div id="cars-content">’;
$output .= get_the_post_thumbnail( $post->ID, ‘thumbnail’ );
$output .= ‘<strong>’;
$output .= get_the_title();
$output .= ‘</strong>’;
if (!empty( $post->post_excerpt ) )
$output .= ‘<em>’.$post->post_excerpt.’</em>’;
$output .= get_the_content();
$output .= ‘</div>’;
endwhile;
}
else
$output = ‘<p>No cars were found.</p>’;
$GLOBALS = $xglobals;
return $output;
}

function my_init() {
add_shortcode( ‘cars’ , ‘wps_cars_posting’ );
}

add_action(‘init’ , ‘my_init’);
[/php]

Be sure to add CSS your style.css accordingly.

For Genesis users, you can use the custom_loop function.