Skip to content

Instantly share code, notes, and snippets.

@richaber
Created September 24, 2015 01:03
Show Gist options
  • Save richaber/8bd66b46e07ffef0635a to your computer and use it in GitHub Desktop.
Save richaber/8bd66b46e07ffef0635a to your computer and use it in GitHub Desktop.
Display WP [gallery] shortcode, outside of the_content, on static front-page, then remove that shortcode from the_content on static front-page with a filter function attached to the_content filter
<?php
/**
* A "Proof Of Concept" Front Page template that displays the first gallery found in the_content, above the_content.
*
* The concept could be applied to any singular template, single posts, single pages, single custom post types, static
* front page, etc (not really for archive pages, or blog home). The function
* yourthemeprefix_remove_first_gallery_shortcode will then remove the first gallery shortcode that it finds in the
* content, from the front page, so that we only output the first one once, above our content, and not again, within
* our content.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
* @link https://developer.wordpress.org/themes/template-files-section/page-template-files/page-templates/
* @link https://codex.wordpress.org/The_WordPress_Gallery
* @link https://codex.wordpress.org/Gallery_Shortcode
* @link https://codex.wordpress.org/Function_Reference/get_post_gallery
* @link https://codex.wordpress.org/Function_Reference/get_the_ID
*
* @package testing
*/
get_header(); ?>
<section class="row main-content-home" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<?php if ( get_post_gallery( get_the_ID() ) ) : ?>
<div class="gallery-display">
<?php echo get_post_gallery( get_the_ID() ); ?>
</div>
<?php endif; ?>
<div class="container">
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
</section>
<?php get_sidebar(); ?>
<?php
get_footer();
<?php
/**
* Your Theme's functions.php file.
*/
/**
* Remove the first [gallery] shortcode from the_content of static front page's main query.
*
* Returns early wherever possible.
* This is intentionally written to be very overly ridiculously verbose, for ease of study.
* This function is fired on the_content filter, with a priority of 10.
* Be aware that if it were to fire later, say priority 11, do_shortcode would have already run, and the shortcode
* we are looking to remove would no longer be in the $content string.
*
* @filter the_content priority 10
*
* @link https://pippinsplugins.com/playing-nice-with-the-content-filter/
* @link https://developer.wordpress.org/reference/functions/is_main_query/
* @link https://developer.wordpress.org/reference/functions/is_front_page/
* @link https://developer.wordpress.org/reference/functions/is_home/
* @link https://codex.wordpress.org/Function_Reference/is_home#Blog_Posts_Index_vs._Site_Front_Page
* @link http://php.net/manual/en/function.strpos.php
* @link https://developer.wordpress.org/reference/functions/get_shortcode_regex/
* @link http://php.net/manual/en/function.preg-match-all.php
* @link http://php.net/manual/en/function.array-search.php
* @link http://php.net/manual/en/function.str-replace.php
* @link https://github.com/WordPress/WordPress/blob/4.3-branch/wp-includes/default-filters.php#L388
*
* @param string $content Content of the current post.
*
* @return string
*/
function yourthemeprefix_remove_first_gallery_shortcode( $content = null ) {
/**
* If there's no content, return early. Presumably the content would never be empty, but it's better to be safe than
* make assumptions and throw warnings and errors later.
*/
if ( empty( $content ) ) {
return $content;
}
/**
* If this is not the main query, return early.
*/
if ( ! is_main_query() ) {
return $content;
}
/**
* If this is not the front page (what most people would call "homepage"), return early.
*/
if ( ! is_front_page() ) {
return $content;
}
/**
* If this is the front page, but front page is a blog listing (not a static page), return early.
*/
if ( is_home() ) {
return $content;
}
/**
* Locate position of the string '[gallery' relative to the beginning of the content string.
*
* Note that string positions start at 0, and not 1. Returns FALSE if '[gallery' needle was not found.
* Use strict === equality to evaluate position (in case position was found at 0). This is a faster "check" than
* preg_match, which is why I'm calling it before we ever get to preg_match. We want to avoid heavy processing
* wherever possible, and return early wherever possible, so we do not have a detrimental impact on performance.
* If we didn't find the position of '[gallery' then the shortcode is not in the content, and we can return early,
* avoiding further, unnecessary processing.
*
* @var bool|int $position
*/
$position = strpos( $content, '[gallery' );
/**
* If there's no gallery position in content, return early.
*/
if ( false === $position ) {
return $content;
}
/**
* Get the shortcode search regular expression pattern.
*
* @var string $shortcode_regex
*/
$shortcode_regex = get_shortcode_regex();
/**
* If there's no shortcode regular expression pattern, return early. I can't imagine this ever being empty, but it's
* better to be safe than make assumptions and throw warnings and errors later.
*/
if ( empty( $shortcode_regex ) ) {
return $content;
}
/**
* Fill the $matches array with shortcodes found in the content.
* Depending on what's in your content, it could look something like this.
*
* $matches = Array
* (
* [0] => Array
* (
* [0] => [video mp4="http://site.com/wp-content/uploads/2015/09/movie.mp4"][/video]
* [1] => [gallery link="none" columns="1" size="full" ids="202,3378,3376" orderby="rand"]
* )
* [1] => Array
* (
* [0] =>
* [1] =>
* )
* [2] => Array
* (
* [0] => video
* [1] => gallery
* )
* [3] => Array
* (
* [0] => mp4="http://site.com/wp-content/uploads/2015/09/movie.mp4"
* [1] => link="none" columns="1" size="full" ids="202,3378,3376" orderby="rand"
* )
* [4] => Array
* (
* [0] =>
* [1] =>
* )
* [5] => Array
* (
* [0] =>
* [1] =>
* )
* [6] => Array
* (
* [0] =>
* [1] =>
* )
* )
*/
preg_match_all( '/' . $shortcode_regex . '/s', $content, $matches );
/**
* Matches[2] is empty, return early.
*/
if ( empty( $matches[2] ) ) {
return $content;
}
/**
* Find the first occurrence of the string 'gallery' in the $matches[2] array.
*
* @var int $key
*/
$gallery_key = array_search( 'gallery', $matches[2] );
/**
* The array search did not locate the string 'gallery', return early.
* Theoretically this shouldn't happen, based on the checks we had earlier, but better to be safe than make
* assumptions and throw errors and warnings.
*/
if ( false === $gallery_key ) {
return $content;
}
/**
* Find the first gallery shortcode string in the $matches[0] array, that corresponds to the $gallery_key found by
* array_search.
*
* @var string $first_gallery_shortcode
*/
$first_gallery_shortcode = $matches[0][ $gallery_key ];
/**
* Amazingly, we don't have a matching shortcode string, return early.
* Theoretically this shouldn't happen, based on the checks we had earlier, but better to be safe than make
* assumptions and throw errors and warnings.
*/
if ( empty( $first_gallery_shortcode ) ) {
return $content;
}
/**
* We have the very first gallery shortcode from the content, strip it out, because we already displayed it in the
* front-page.php template, outside of the content.
*/
$content = str_replace( $first_gallery_shortcode, '', $content );
return $content;
}
add_filter( 'the_content', 'yourthemeprefix_remove_first_gallery_shortcode', 10 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment