534 lines
14 KiB
PHP
534 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Genesis Framework.
|
|
*
|
|
* WARNING: This file is part of the core Genesis Framework. DO NOT edit this file under any circumstances.
|
|
* Please do all modifications in the form of a child theme.
|
|
*
|
|
* @package Genesis\Loops
|
|
* @author StudioPress
|
|
* @license GPL-2.0+
|
|
* @link https://my.studiopress.com/themes/genesis/
|
|
*/
|
|
|
|
add_action( 'genesis_loop', 'genesis_do_loop' );
|
|
/**
|
|
* Attach a loop to the `genesis_loop` output hook so we can get some front-end output.
|
|
*
|
|
* @since 1.1.0
|
|
*/
|
|
function genesis_do_loop() {
|
|
|
|
if ( is_page_template( 'page_blog.php' ) ) {
|
|
|
|
$include = genesis_get_option( 'blog_cat' );
|
|
$exclude = genesis_get_option( 'blog_cat_exclude' ) ? explode( ',', str_replace( ' ', '', genesis_get_option( 'blog_cat_exclude' ) ) ) : '';
|
|
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
|
|
|
|
// Easter Egg.
|
|
$query_args = wp_parse_args(
|
|
genesis_get_custom_field( 'query_args' ),
|
|
array(
|
|
'cat' => $include,
|
|
'category__not_in' => $exclude,
|
|
'showposts' => genesis_get_option( 'blog_cat_num' ),
|
|
'paged' => $paged,
|
|
)
|
|
);
|
|
|
|
genesis_custom_loop( $query_args );
|
|
} else {
|
|
genesis_standard_loop();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Standard loop, meant to be executed without modification in most circumstances where content needs to be displayed.
|
|
*
|
|
* It outputs basic wrapping HTML, but uses hooks to do most of its content output like title, content, post information
|
|
* and comments.
|
|
*
|
|
* The action hooks called are:
|
|
*
|
|
* - `genesis_before_entry`
|
|
* - `genesis_entry_header`
|
|
* - `genesis_before_entry_content`
|
|
* - `genesis_entry_content`
|
|
* - `genesis_after_entry_content`
|
|
* - `genesis_entry_footer`
|
|
* - `genesis_after_endwhile`
|
|
* - `genesis_loop_else` (only if no posts were found)
|
|
*
|
|
* @since 1.1.0
|
|
*
|
|
* @return void Return early after legacy loop if not supporting HTML5.
|
|
*/
|
|
function genesis_standard_loop() {
|
|
|
|
// Use old loop hook structure if not supporting HTML5.
|
|
if ( ! genesis_html5() ) {
|
|
genesis_legacy_loop();
|
|
return;
|
|
}
|
|
|
|
if ( have_posts() ) {
|
|
|
|
/**
|
|
* Fires inside the standard loop, before the while() block.
|
|
*
|
|
* @since 2.1.0
|
|
*/
|
|
do_action( 'genesis_before_while' );
|
|
|
|
while ( have_posts() ) {
|
|
|
|
the_post();
|
|
|
|
/**
|
|
* Fires inside the standard loop, before the entry opening markup.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_before_entry' );
|
|
|
|
genesis_markup( array(
|
|
'open' => '<article %s>',
|
|
'context' => 'entry',
|
|
) );
|
|
|
|
/**
|
|
* Fires inside the standard loop, to display the entry header.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_entry_header' );
|
|
|
|
/**
|
|
* Fires inside the standard loop, after the entry header action hook, before the entry content.
|
|
* opening markup.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_before_entry_content' );
|
|
|
|
printf( '<div %s>', genesis_attr( 'entry-content' ) );
|
|
/**
|
|
* Fires inside the standard loop, inside the entry content markup.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_entry_content' );
|
|
echo '</div>';
|
|
|
|
/**
|
|
* Fires inside the standard loop, before the entry footer action hook, after the entry content.
|
|
* opening markup.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_after_entry_content' );
|
|
|
|
/**
|
|
* Fires inside the standard loop, to display the entry footer.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_entry_footer' );
|
|
|
|
genesis_markup( array(
|
|
'close' => '</article>',
|
|
'context' => 'entry',
|
|
) );
|
|
|
|
/**
|
|
* Fires inside the standard loop, after the entry closing markup.
|
|
*
|
|
* @since 2.0.0
|
|
*/
|
|
do_action( 'genesis_after_entry' );
|
|
|
|
} // End of one post.
|
|
|
|
/**
|
|
* Fires inside the standard loop, after the while() block.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_after_endwhile' );
|
|
|
|
} else { // If no posts exist.
|
|
|
|
/**
|
|
* Fires inside the standard loop when they are no posts to show.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_loop_else' );
|
|
|
|
} // End loop.
|
|
|
|
}
|
|
|
|
/**
|
|
* XHTML loop.
|
|
*
|
|
* This is called by {@link genesis_standard_loop()} if the child theme does not support HTML5.
|
|
*
|
|
* It is a standard loop, and is meant to be executed, without modification, in most circumstances where content needs
|
|
* to be displayed.
|
|
*
|
|
* It outputs basic wrapping HTML, but uses hooks to do most of its content output like title, content, post information
|
|
* and comments.
|
|
*
|
|
* The action hooks called are:
|
|
*
|
|
* - `genesis_before_post`
|
|
* - `genesis_before_post_title`
|
|
* - `genesis_post_title`
|
|
* - `genesis_after_post_title`
|
|
* - `genesis_before_post_content`
|
|
* - `genesis_post_content`
|
|
* - `genesis_after_post_content`
|
|
* - `genesis_after_post`
|
|
* - `genesis_after_endwhile`
|
|
* - `genesis_loop_else` (only if no posts were found)
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @global int $loop_counter Increments on each loop pass.
|
|
*/
|
|
function genesis_legacy_loop() {
|
|
|
|
global $loop_counter;
|
|
|
|
$loop_counter = 0;
|
|
|
|
if ( have_posts() ) {
|
|
|
|
while ( have_posts() ) {
|
|
|
|
the_post();
|
|
|
|
/**
|
|
* Fires inside the legacy loop, before the post opening markup.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_before_post' );
|
|
|
|
printf( '<div class="%s">', implode( ' ', get_post_class() ) );
|
|
|
|
/**
|
|
* Fires inside the legacy loop, before the post title hook, after the post opening markup.
|
|
*
|
|
* @since 1.0.1
|
|
*/
|
|
do_action( 'genesis_before_post_title' );
|
|
|
|
/**
|
|
* Fires inside the legacy loop, to display the post title.
|
|
*
|
|
* @since 1.1.0
|
|
*/
|
|
do_action( 'genesis_post_title' );
|
|
|
|
/**
|
|
* Fires inside the legacy loop, after the post title hook.
|
|
*
|
|
* @since 1.0.1
|
|
*/
|
|
do_action( 'genesis_after_post_title' );
|
|
|
|
/**
|
|
* Fires inside the legacy loop, before the post content hook, before the post content opening markup.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_before_post_content' );
|
|
|
|
echo '<div class="entry-content">';
|
|
|
|
/**
|
|
* Fires inside the legacy loop, inside the post content markup.
|
|
*
|
|
* @since 1.1.0
|
|
*/
|
|
do_action( 'genesis_post_content' );
|
|
|
|
echo '</div>'; // End .entry-content.
|
|
|
|
/**
|
|
* Fires inside the legacy loop, after the post content hook, before the post content closing markup.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_after_post_content' );
|
|
|
|
echo '</div>'; // End .entry.
|
|
|
|
/**
|
|
* Fires inside the legacy loop, after the post closing markup.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
do_action( 'genesis_after_post' );
|
|
|
|
$loop_counter++;
|
|
|
|
} // End of one post.
|
|
|
|
/** This action is documented in lib/structure/loops.php */
|
|
do_action( 'genesis_after_endwhile' );
|
|
|
|
} else { // If no posts exist.
|
|
|
|
/** This action is documented in lib/structure/loops.php */
|
|
do_action( 'genesis_loop_else' );
|
|
|
|
} // End loop.
|
|
|
|
}
|
|
|
|
/**
|
|
* Custom loop, meant to be executed when a custom query is needed.
|
|
*
|
|
* It accepts arguments in query_posts style format to modify the custom `WP_Query` object.
|
|
*
|
|
* It outputs basic wrapping HTML, but uses hooks to do most of its content output like title, content, post information,
|
|
* and comments.
|
|
*
|
|
* The arguments can be passed in via the `genesis_custom_loop_args` filter.
|
|
*
|
|
* The action hooks called are the same as {@link genesis_standard_loop()}.
|
|
*
|
|
* @since 1.1.0
|
|
*
|
|
* @global WP_Query $wp_query Query object.
|
|
* @global int $more
|
|
*
|
|
* @param array $args Loop configuration.
|
|
*/
|
|
function genesis_custom_loop( $args = array() ) {
|
|
|
|
global $wp_query, $more;
|
|
|
|
$defaults = array(); // For forward compatibility.
|
|
$args = apply_filters( 'genesis_custom_loop_args', wp_parse_args( $args, $defaults ), $args, $defaults );
|
|
|
|
$wp_query = new WP_Query( $args );
|
|
|
|
// Only set $more to 0 if we're on an archive.
|
|
$more = is_singular() ? $more : 0;
|
|
|
|
genesis_standard_loop();
|
|
|
|
// Restore original query.
|
|
wp_reset_query();
|
|
|
|
}
|
|
|
|
/**
|
|
* The grid loop - a specific implementation of a custom loop.
|
|
*
|
|
* Outputs markup compatible with a Feature + Grid style layout.
|
|
* All normal loop hooks present, except for `genesis_post_content`.
|
|
*
|
|
* The arguments can be filtered by the `genesis_grid_loop_args` filter.
|
|
*
|
|
* @since 1.5.0
|
|
*
|
|
* @global array $_genesis_loop_args Associative array for grid loop configuration.
|
|
*
|
|
* @param array $args Associative array for grid loop configuration.
|
|
*/
|
|
function genesis_grid_loop( $args = array() ) {
|
|
|
|
// Global vars.
|
|
global $_genesis_loop_args;
|
|
|
|
// Parse args.
|
|
$args = apply_filters(
|
|
'genesis_grid_loop_args',
|
|
wp_parse_args(
|
|
$args,
|
|
array(
|
|
'features' => 2,
|
|
'features_on_all' => false,
|
|
'feature_image_size' => 0,
|
|
'feature_image_class' => 'alignleft',
|
|
'feature_content_limit' => 0,
|
|
'grid_image_size' => 'thumbnail',
|
|
'grid_image_class' => 'alignleft',
|
|
'grid_content_limit' => 0,
|
|
'more' => __( 'Read more', 'genesis' ) . '…',
|
|
)
|
|
)
|
|
);
|
|
|
|
// If user chose more features than posts per page, adjust features.
|
|
if ( get_option( 'posts_per_page' ) < $args['features'] ) {
|
|
$args['features'] = get_option( 'posts_per_page' );
|
|
}
|
|
|
|
// What page are we on?
|
|
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
|
|
|
|
// Potentially remove features on page 2+.
|
|
if ( $paged > 1 && ! $args['features_on_all'] ) {
|
|
$args['features'] = 0;
|
|
}
|
|
|
|
// Set global loop args.
|
|
$_genesis_loop_args = $args;
|
|
|
|
// Remove some unnecessary stuff from the grid loop.
|
|
remove_action( 'genesis_before_post_title', 'genesis_do_post_format_image' );
|
|
remove_action( 'genesis_post_content', 'genesis_do_post_image' );
|
|
remove_action( 'genesis_post_content', 'genesis_do_post_content' );
|
|
remove_action( 'genesis_post_content', 'genesis_do_post_content_nav' );
|
|
|
|
remove_action( 'genesis_entry_header', 'genesis_do_post_format_image', 4 );
|
|
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
|
|
remove_action( 'genesis_entry_content', 'genesis_do_post_content' );
|
|
remove_action( 'genesis_entry_content', 'genesis_do_post_content_nav', 12 );
|
|
remove_action( 'genesis_entry_content', 'genesis_do_post_permalink', 14 );
|
|
|
|
|
|
// Custom loop output.
|
|
add_filter( 'post_class', 'genesis_grid_loop_post_class' );
|
|
add_action( 'genesis_post_content', 'genesis_grid_loop_content' );
|
|
add_action( 'genesis_entry_content', 'genesis_grid_loop_content' );
|
|
|
|
// The loop.
|
|
genesis_standard_loop();
|
|
|
|
// Reset loops.
|
|
genesis_reset_loops();
|
|
remove_filter( 'post_class', 'genesis_grid_loop_post_class' );
|
|
remove_action( 'genesis_post_content', 'genesis_grid_loop_content' );
|
|
remove_action( 'genesis_entry_content', 'genesis_grid_loop_content' );
|
|
|
|
}
|
|
|
|
/**
|
|
* Filter the post classes to output custom classes for the feature and grid layout.
|
|
*
|
|
* Based on the grid loop args and the loop counter.
|
|
*
|
|
* Applies the `genesis_grid_loop_post_class` filter.
|
|
*
|
|
* The `&1` is a test to see if it is odd. `2&1 = 0` (even), `3&1 = 1` (odd).
|
|
*
|
|
* @since 1.5.0
|
|
*
|
|
* @global array $_genesis_loop_args Associative array for grid loop config.
|
|
* @global WP_Query $wp_query Query object.
|
|
*
|
|
* @param array $classes Existing post classes.
|
|
* @return array Amended post classes.
|
|
*/
|
|
function genesis_grid_loop_post_class( array $classes ) {
|
|
|
|
global $_genesis_loop_args, $wp_query;
|
|
|
|
$grid_classes = array();
|
|
|
|
if ( $_genesis_loop_args['features'] && $wp_query->current_post < $_genesis_loop_args['features'] ) {
|
|
$grid_classes[] = 'genesis-feature';
|
|
$grid_classes[] = sprintf( 'genesis-feature-%s', $wp_query->current_post + 1 );
|
|
$grid_classes[] = $wp_query->current_post&1 ? 'genesis-feature-even' : 'genesis-feature-odd';
|
|
} elseif ( $_genesis_loop_args['features']&1 ) {
|
|
$grid_classes[] = 'genesis-grid';
|
|
$grid_classes[] = sprintf( 'genesis-grid-%s', $wp_query->current_post - $_genesis_loop_args['features'] + 1 );
|
|
$grid_classes[] = $wp_query->current_post&1 ? 'genesis-grid-odd' : 'genesis-grid-even';
|
|
} else {
|
|
$grid_classes[] = 'genesis-grid';
|
|
$grid_classes[] = sprintf( 'genesis-grid-%s', $wp_query->current_post - $_genesis_loop_args['features'] + 1 );
|
|
$grid_classes[] = $wp_query->current_post&1 ? 'genesis-grid-even' : 'genesis-grid-odd';
|
|
}
|
|
|
|
return array_merge( $classes, apply_filters( 'genesis_grid_loop_post_class', $grid_classes ) );
|
|
|
|
}
|
|
|
|
/**
|
|
* Output specially formatted content, based on the grid loop args.
|
|
*
|
|
* @since 1.5.0
|
|
*
|
|
* @global array $_genesis_loop_args Associative array for grid loop configuration.
|
|
*/
|
|
function genesis_grid_loop_content() {
|
|
|
|
global $_genesis_loop_args;
|
|
|
|
if ( in_array( 'genesis-feature', get_post_class() ) ) {
|
|
|
|
if ( $_genesis_loop_args['feature_image_size'] ) {
|
|
|
|
$image = genesis_get_image( array(
|
|
'size' => $_genesis_loop_args['feature_image_size'],
|
|
'context' => 'grid-loop-featured',
|
|
'attr' => genesis_parse_attr( 'entry-image-grid-loop', array(
|
|
'class' => $_genesis_loop_args['feature_image_class'],
|
|
) ),
|
|
) );
|
|
|
|
printf( '<a href="%s">%s</a>', get_permalink(), $image );
|
|
|
|
}
|
|
|
|
if ( $_genesis_loop_args['feature_content_limit'] ) {
|
|
the_content_limit( (int) $_genesis_loop_args['feature_content_limit'], genesis_a11y_more_link( esc_html( $_genesis_loop_args['more'] ) ) );
|
|
} else {
|
|
the_content( genesis_a11y_more_link( esc_html( $_genesis_loop_args['more'] ) ) );
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( $_genesis_loop_args['grid_image_size'] ) {
|
|
|
|
$image = genesis_get_image( array(
|
|
'size' => $_genesis_loop_args['grid_image_size'],
|
|
'context' => 'grid-loop',
|
|
'attr' => genesis_parse_attr( 'entry-image-grid-loop', array(
|
|
'class' => $_genesis_loop_args['grid_image_class'],
|
|
) ),
|
|
) );
|
|
|
|
printf( '<a href="%s">%s</a>', get_permalink(), $image );
|
|
|
|
}
|
|
|
|
if ( $_genesis_loop_args['grid_content_limit'] ) {
|
|
the_content_limit( (int) $_genesis_loop_args['grid_content_limit'], genesis_a11y_more_link( esc_html( $_genesis_loop_args['more'] ) ) );
|
|
} else {
|
|
the_excerpt();
|
|
printf( '<a href="%s" class="more-link">%s</a>', get_permalink(), genesis_a11y_more_link( esc_html( $_genesis_loop_args['more'] ) ) );
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
add_action( 'genesis_after_post', 'genesis_add_id_to_global_exclude', 9 );
|
|
add_action( 'genesis_after_entry', 'genesis_add_id_to_global_exclude', 9 );
|
|
/**
|
|
* Modify the global $_genesis_displayed_ids each time a loop iterates.
|
|
*
|
|
* Keep track of what posts have been shown on any given page by adding each ID to a global array, which can be used any
|
|
* time by other loops to prevent posts from being displayed twice on a page.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @global array $_genesis_displayed_ids Array of displayed post IDs.
|
|
*/
|
|
function genesis_add_id_to_global_exclude() {
|
|
|
|
global $_genesis_displayed_ids;
|
|
|
|
$_genesis_displayed_ids[] = get_the_ID();
|
|
|
|
}
|