LoopBuddy Basics/Advance

LoopBuddy is a tool that overwrites a WordPress Loop using a combination of a custom query and a custom layout. You can also create your own Loops using the LoopBuddy shortcode and LoopBuddy widget.

Content

Query Editor

If LoopBuddy was a body, the Query Editor would be the brain, with the Layout Editor being the outside bodily appearance.

With the Query Editor, you can create Query Groups. Each Query Group defines what data a WordPress Loop is supposed to pull in.

With the Query Editor, you can define:

  • Which posts to gather
  • Whether pagination or comments are enabled
  • Whether to use the default post ID (if on a single post or page)
  • and much, much more...

Layout Editor

The Layout Editor controls how a particular WordPress Loop is supposed to be structured. At the heart of the Layout Editor is Layout Tags. There are several Layout Tags built-in, but you can use the LoopBuddy Hooks to create your own custom Layout Tag and Layout Tag Items.

With the Layout Editor, simply drag Layout Tags into the appropriate area. If you create a new Layout, there are several default tags that are added automatically.

LoopBuddy Global Settings

The Global LoopBuddy Settings allow you to globally override a default WordPress Loop. If your theme doesn't support the Loop Standard, you'll see an error message at the top.

If your theme does support the Loop Standard, you can use the options to override the default WordPress Loops in various areas of the site.

Although LoopBuddy attempts to work without a custom Query, it is highly advisable to use a custom Query and Layout.

Import/Export

Within the Query and Layout lists pages, you can export/import the items so you can use the same Queries/Layouts on a different site.

This is the same page as where you create new Queries or Layouts.

LoopBuddy Widget

You can use the LoopBuddy Widget to display a LoopBuddy Query/Layout in any widgetized area of a site. Please note that you must have a Query AND a Layout for the widget to work.

LoopBuddy Shortcode

The LoopBuddy shortcode takes two attributes: a Query ID and a Layout ID. Please note that you must have a Query AND a Layout for the widget to work.

Simply insert the shortcode into a post or page:

[loopbuddy query_id='0' layout_id='0']

To find the Query ID, you'll go into LoopBuddy > Query Editor > Query of your choice. Once you're in the page to edit that query, you'll see the Query ID in your url.

You'll find the Layout ID in the same place when you go in to edit the layout you'd like to use in your shortcode.

The Loop Standard

The Loop Standard divides a loop into two main concepts: a loop and one or more entries.

Both a loop and an entry have three sections: a header, a content section, and a footer. The header contains title information, any meta information, and any necessary navigation links. The content section contains the content relevant to that loop or entry. The footer section is a place to hold additional or duplicate meta information and navigation links.

The Loop Explained

The content of a loop is a bit more complex than the content of an entry as a loop's content contains the entries. To better visualize this, here is the basic structure described so far:

  • Loop
    • Header
      • title
      • navigation
      • meta
    • Content
      • Entry
        • Header
          • title
          • navigation
          • meta
        • Content
        • Footer
          • navigation
          • meta
      • Additional entries...
      • Footer
        • navigation
        • meta

The idea is that each section is broken out in a repeatable pattern. This makes styling easier as any content that follows this form can be styled without having to first read through the code in order to understand the structure.

You may notice that there are titles, navigation, and meta for both the entries and the loop. This is because some titles, navigation, and meta are relevant to the loop (the title archive, navigating between pages of posts, or information about an author in an author archive) while other titles, navigation, and meta are relevant to the entry (the blog post's title, navigating through a page split into multiple pages, or a blog post's category information). The rule of thumb is that if the information is specific to an individual post's, page's, etc content, it is an entry-level structure; otherwise, it is a loop-level structure.

Each of these sections have a specific class in the Loop Standard. Here is the structure again with the classes replacing the names:

  • loop
    • loop-header
      • loop-title
      • loop-utility
      • loop-meta
    • loop-content
      • hentry
        • entry-header
          • entry-title
          • entry-utility
          • entry-meta
        • entry-content
        • entry-footer
          • entry-utility
          • entry-meta
      • hentry...
    • loop-footer
      • loop-utility
      • loop-meta

Notice the "hentry" class. This looks odd but is actually generated by WordPress internally. It is produced by the post_class() function that is in 2010 and 2011 theme template files. So when you see "hentry", know that this is simply the div looks like:

<div <?php post_class(); ?>></div>

Here is the standard loop in practice:

  • loop
    • loop-header
      • loop-title (page-title)
    • loop-content
      • hentry
        • entry-header (title)
          • entry-title (post-title)
          • entry-meta (post-meta)
          • entry-meta date (date)
        • entry-content (post-content)
        • entry-footer (meta-bottom)
          • entry-meta alignright (alignright)
          • entry-meta alignleft (meta-bottom-left)
      • hentry...
  • loop-footer
    • loop-utility (paging)

Not all the elements from above structure examples were used since not all were needed. In the end, only three elements had to be added. The rest of the changes were simply modifying or adding classes to conform to the Loop Standard structure. For some elements, such as "date", the "date" class remained while also getting the "entry-meta" class. This makes it clear what type of structure it is while still giving the additional meaning of it being a container for the date.

 

Modifying a Theme to Use LoopBuddy

Here's an example of TwentyTen's index.php file before it begins loading the various templates:

<?php if ( ! dynamic_loop() ) : ?>
	<div class="loop">
		<?php
		/* Run the loop to output the posts.
		 * If you want to overload this in a child theme then include a file
		 * called loop-index.php and that will be used instead.
		 */
		 get_template_part( 'loop', 'index' );
		?>
	</div>
<?php endif; ?>

When dynamic_loop() is executed, LoopBuddy searches to see if this particular loop should be overridden. If not, the normal loop executes. If so, then LoopBuddy overwrites the content of the loop with LoopBuddy content.

Example of TwentyTen Using the Loop Standard

Here's an example TwentyTen Loop converted to using the Loop Standard

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

			<div class="loop-content">
				<div id="nav-above" class="navigation loop-utility loop-utility-above">
					<div class="nav-previous"><?php previous_post_link( '%link', '<span class="meta-nav">' . _x( '←', 'Previous post link', 'twentyten' ) . '</span> %title' ); ?></div>
					<div class="nav-next"><?php next_post_link( '%link', '%title <span class="meta-nav">' . _x( '→', 'Next post link', 'twentyten' ) . '</span>' ); ?></div>
				</div><!-- #nav-above -->

				<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
					<div class="entry-header">
						<h1 class="entry-title"><?php the_title(); ?></h1>
						<div class="entry-meta">
							<?php twentyten_posted_on(); ?>
						</div><!-- .entry-meta -->
					</div><!-- .entry-header-->
					<div class="entry-content">
						<?php the_content(); ?>
						<?php wp_link_pages( array( 'before' => '<div class="page-link">' . __( 'Pages:', 'twentyten' ), 'after' => '</div>' ) ); ?>
					</div><!-- .entry-content -->
					<div class="entry-footer">
<?php if ( get_the_author_meta( 'description' ) ) : // If a user has filled out their description, show a bio on their entries  ?>
						<div id="entry-author-info" class="entry-meta entry-meta-below">
							<div id="author-avatar">
								<?php echo get_avatar( get_the_author_meta( 'user_email' ), apply_filters( 'twentyten_author_bio_avatar_size', 60 ) ); ?>
							</div><!-- #author-avatar -->
							<div id="author-description">
								<h2><?php printf( esc_attr__( 'About %s', 'twentyten' ), get_the_author() ); ?></h2>
								<?php the_author_meta( 'description' ); ?>
								<div id="author-link">
									<a href="<?php echo get_author_posts_url( get_the_author_meta( 'ID' ) ); ?>">
										<?php printf( __( 'View all posts by %s <span class="meta-nav">→</span>', 'twentyten' ), get_the_author() ); ?>
									</a>
								</div><!-- #author-link	-->
							</div><!-- #author-description -->
						</div><!-- #entry-author-info -->
<?php endif; ?>
	
						<div class="entry-utility">
							<?php twentyten_posted_in(); ?>
							<?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?>
						</div><!-- .entry-utility -->
					</div><!-- .entry-footer-->
				</div><!-- #post-## -->
				<div class="loop-footer">
					<div id="nav-below" class="navigation loop-utility loop-utility-below">
						<div class="nav-previous"><?php previous_post_link( '%link', '<span class="meta-nav">' . _x( '←', 'Previous post link', 'twentyten' ) . '</span> %title' ); ?></div>
						<div class="nav-next"><?php next_post_link( '%link', '%title <span class="meta-nav">' . _x( '→', 'Next post link', 'twentyten' ) . '</span>' ); ?></div>
					</div><!-- #nav-below -->
				</div><!-- .loop-footer-->

				<?php comments_template( '', true ); ?>
			</div><!-- .loop-content-->

<?php endwhile; // end of the loop. ?>
	

After updating the template files, go through the theme's style.css file in order to update class references to match the new ones. Here are some basic replacements to make:

  • .page-title → .loop-title
  • .title → .entry-header
  • .post-title [h1, h2, h3, etc] (any instance of .post-title followed by a header tag) → .entry-title
  • .post-title → .entry-title
  • .post-meta → .entry-meta
  • .post-content → .entry-content
  • .meta-top → .entry-header
  • .meta-bottom → .entry-footer
  • .post → .hentry
  • .paging → .loop-utility

Showing LoopBuddy Theme Support

After you've modified your theme's loops, show LoopBuddy that your theme supports it by adding in the following line to your theme's functions.php file:

// Add support for the Loop Standard
add_theme_support( 'loop-standard' );

Adding the Dynamic Loop Function to Your Theme

The Dynamic Loop function must be added to your theme's functions.php file. This is achieved by adding the following code to the end of the function.php file:

// Add dynamic_loop function for LoopBuddy

/*
Copyright 2011 iThemes (email: support@ithemes.com)

Written by Chris Jean
Version 0.0.1

Version History
	0.0.1 - 2011-02-28 - Chris Jean
		Initial version
*/


if ( ! function_exists( 'dynamic_loop' ) ) {
	function dynamic_loop() {
		global $dynamic_loop_handlers;
		
		if ( empty( $dynamic_loop_handlers ) || ! is_array( $dynamic_loop_handlers ) )
			return false;
		
		ksort( $dynamic_loop_handlers );
		
		
		foreach ( (array) $dynamic_loop_handlers as $handlers ) {
			foreach ( (array) $handlers as $function ) {
				if ( is_callable( $function ) && ( false != call_user_func( $function ) ) ) {
					return true;
				}
			}
		}
		
		return false;
	}
}

if ( ! function_exists( 'register_dynamic_loop_handler' ) ) {
	function register_dynamic_loop_handler( $function, $priority = 10 ) {
		global $dynamic_loop_handlers;

		if ( ! is_numeric( $priority ) )
			$priority = 10;
		
		if ( ! isset( $dynamic_loop_handlers ) || ! is_array( $dynamic_loop_handlers ) )
			$dynamic_loop_handlers = array();
		
		if ( ! isset( $dynamic_loop_handlers[$priority] ) || ! is_array( $dynamic_loop_handlers[$priority] ) )
			$dynamic_loop_handlers[$priority] = array();
		
		$dynamic_loop_handlers[$priority][] = $function;
	}
}

Convert Any Theme to Support LoopBuddy

Note: The details provided here are based on a WebDesign.com training webinar that occurred on September 17th, 2012.

In order to convert a theme to support LoopBuddy, it must support the loop-standard. The loop-standard is based on a proposal by Chris Jean which can be found here .

For a theme to support the loop-standard, there are three main steps:

  1. Add the necessary code support in the theme's functions.php file. Details can be found here
  2. Modify the theme's files that provide The Loop to be wrapped in a conditional that allows them to be replaced by LoopBuddy. Details can be found here .
  3. The theme's styling will likely need to be updated to support the HTML structure used by LoopBuddy. An example of the structure of The Loop output by LoopBuddy can be found on slide 17 of this presentation . Note that the slide shows all the potential areas that can be output; each Loop may have different sections available depending on the setup of the Loop structure in LoopBuddy.

Theme functions.php Modification for LoopBuddy Support

(Redirected from Two Key Code Snippets that Support LoopBuddy )

In order for plugins and other modifications that support the loop-standard to function, the theme must declare that it supports the loop-standard and supply some needed functions. This can be done by adding the following modification to the end of the theme's functions.php file (ensure that if a ?> line is at the end of the file, that the modification is placed above the ?> line).

// Add support for the loop-standard.
add_theme_support( 'loop-standard' );

if ( ! function_exists( 'dynamic_loop' ) ) {
	function dynamic_loop() {
		global $dynamic_loop_handlers;
		if ( empty( $dynamic_loop_handlers ) || ! is_array( $dynamic_loop_handlers ) )
			return false;
		ksort( $dynamic_loop_handlers );
		foreach ( (array) $dynamic_loop_handlers as $handlers ) {
			foreach ( (array) $handlers as $function ) {
				if ( is_callable( $function ) && ( false != call_user_func( $function ) ) ) {
					return true;
				}
			}
		}
		return false;
	}
}
if ( ! function_exists( 'register_dynamic_loop_handler' ) ) {
	function register_dynamic_loop_handler( $function, $priority = 10 ) {
		global $dynamic_loop_handlers;
		if ( ! is_numeric( $priority ) )
			$priority = 10;
		if ( ! isset( $dynamic_loop_handlers ) || ! is_array( $dynamic_loop_handlers ) )
			$dynamic_loop_handlers = array();
		if ( ! isset( $dynamic_loop_handlers[$priority] ) || ! is_array( $dynamic_loop_handlers[$priority] ) )
			$dynamic_loop_handlers[$priority] = array();
		$dynamic_loop_handlers[$priority][] = $function;
	}
}

Theme Template File Modification for LoopBuddy Support

(Redirected from Wrap the Original Loop with a Conditional Tag )

The main feature of supporting the loop-standard is allowing The Loop to be replaced with a new one, such as one provided by a plugin or customization. In order for this to function properly, each of the theme's template files will need a modification that allows The Loop to be conditionally replaced. The dynamic_loop() function provides this functionality. A Loop wrapped in this modification looks as follows.

<?php if ( ! dynamic_loop() ) : ?>
	// Original Loop Code
<?php endif; ?>

With this modification in place in each of the theme's template files, a plugin or customization is able to replace The Loop. If no replacement is done, The Loop is not replaced and is used as if no modification had been made.

The following is the unmodified single.php file from the Twenty Fourteen theme:

<?php
/**
 * The Template for displaying all single posts
 *
 * @package WordPress
 * @subpackage Twenty_Fourteen
 * @since Twenty Fourteen 1.0
 */

get_header(); ?>

    <div id="primary" class="content-area">
        <div id="content" class="site-content" role="main">
            <?php
                // Start the Loop.
                while ( have_posts() ) : the_post();

                    /*
                     * Include the post format-specific template for the content. If you want to
                     * use this in a child theme, then include a file called called content-___.php
                     * (where ___ is the post format) and that will be used instead.
                     */
                    get_template_part( 'content', get_post_format() );

                    // Previous/next post navigation.
                    twentyfourteen_post_nav();

                    // If comments are open or we have at least one comment, load up the comment template.
                    if ( comments_open() || get_comments_number() ) { 
                        comments_template();
                    }
                endwhile;
            ?>
        </div><!-- #content -->
    </div><!-- #primary -->

<?php
get_sidebar( 'content' );
get_sidebar();
get_footer();

After modifying it to support the loop-standard, the file looks as follows:

<?php
/**
 * The Template for displaying all single posts
 *
 * @package WordPress
 * @subpackage Twenty_Fourteen
 * @since Twenty Fourteen 1.0
 */

get_header(); ?>

    <div id="primary" class="content-area">
        <div id="content" class="site-content" role="main">
            <?php if ( ! dynamic_loop() ) : ?>
                <?php
                    // Start the Loop.
                    while ( have_posts() ) : the_post();

                        /*
                         * Include the post format-specific template for the content. If you want to
                         * use this in a child theme, then include a file called called content-___.php
                         * (where ___ is the post format) and that will be used instead.
                         */
                        get_template_part( 'content', get_post_format() );

                        // Previous/next post navigation.
                        twentyfourteen_post_nav();

                        // If comments are open or we have at least one comment, load up the comment template.
                        if ( comments_open() || get_comments_number() ) {
                            comments_template();
                        }
                    endwhile;
                ?>
            <?php endif; ?>
        </div><!-- #content -->
    </div><!-- #primary -->

<?php
get_sidebar( 'content' );
get_sidebar();
get_footer();

The modifications on lines 14 and 35 wrap The Loop in a conditional that allows loop-standard features to replace The Loop as needed.

In order for this to function properly in a theme, each template file must be updated to support the modification. Since The Loop for one or more templates may be moved to a template part file, check all the theme's files to ensure that each instance of The Loop is modified.

Other Notes About Conversions

You can extract a loop and put it into a separate file and then call that original loop (inside the dynamic_loop() conditional tag) by using the get_template_part() WordPress function.

 

Have more questions? Submit a request
Powered by Zendesk