2

So I'm trying to add or change the built in gallery shortcode so that it can display all images of a specific category that we'll call internal medicine with an id of 2, but also able to have the same functionality if I wanted to grab all the images of a different category lets say called downtown with an id of 4, where can I start with this? Here's the code for the built-in shortcode that I'm trying to edit.

    add_shortcode('gallery', 'gallery_shortcode');
/**
 * Builds the Gallery shortcode output.
 *
 * This implements the functionality of the Gallery Shortcode for displaying
 * WordPress images on a post.
 *
 * @since 2.5.0
 *
 * @staticvar int $instance
 *
 * @param array $attr {
 *     Attributes of the gallery shortcode.
 *
 *     @type string       $order      Order of the images in the gallery. Default 'ASC'. Accepts 'ASC', 'DESC'.
 *     @type string       $orderby    The field to use when ordering the images. Default 'menu_order ID'.
 *                                    Accepts any valid SQL ORDERBY statement.
 *     @type int          $id         Post ID.
 *     @type string       $itemtag    HTML tag to use for each image in the gallery.
 *                                    Default 'dl', or 'figure' when the theme registers HTML5 gallery support.
 *     @type string       $icontag    HTML tag to use for each image's icon.
 *                                    Default 'dt', or 'div' when the theme registers HTML5 gallery support.
 *     @type string       $captiontag HTML tag to use for each image's caption.
 *                                    Default 'dd', or 'figcaption' when the theme registers HTML5 gallery support.
 *     @type int          $columns    Number of columns of images to display. Default 3.
 *     @type string|array $size       Size of the images to display. Accepts any valid image size, or an array of width
 *                                    and height values in pixels (in that order). Default 'thumbnail'.
 *     @type string       $ids        A comma-separated list of IDs of attachments to display. Default empty.
 *     @type string       $include    A comma-separated list of IDs of attachments to include. Default empty.
 *     @type string       $exclude    A comma-separated list of IDs of attachments to exclude. Default empty.
 *     @type string       $link       What to link each image to. Default empty (links to the attachment page).
 *                                    Accepts 'file', 'none'.
 * }
 * @return string HTML content to display gallery.
 */
function gallery_shortcode( $attr ) {
    $post = get_post();
    static $instance = 0;
    $instance++;
    if ( ! empty( $attr['ids'] ) ) {
        // 'ids' is explicitly ordered, unless you specify otherwise.
        if ( empty( $attr['orderby'] ) ) {
            $attr['orderby'] = 'post__in';
        }
        $attr['include'] = $attr['ids'];
    }
    /**
     * Filters the default gallery shortcode output.
     *
     * If the filtered output isn't empty, it will be used instead of generating
     * the default gallery template.
     *
     * @since 2.5.0
     * @since 4.2.0 The `$instance` parameter was added.
     *
     * @see gallery_shortcode()
     *
     * @param string $output   The gallery output. Default empty.
     * @param array  $attr     Attributes of the gallery shortcode.
     * @param int    $instance Unique numeric ID of this gallery shortcode instance.
     */
    $output = apply_filters( 'post_gallery', '', $attr, $instance );
    if ( $output != '' ) {
        return $output;
    }
    $html5 = current_theme_supports( 'html5', 'gallery' );
    $atts = shortcode_atts( array(
        'order'      => 'ASC',
        'orderby'    => 'menu_order ID',
        'id'         => $post ? $post->ID : 0,
        'itemtag'    => $html5 ? 'figure'     : 'dl',
        'icontag'    => $html5 ? 'div'        : 'dt',
        'captiontag' => $html5 ? 'figcaption' : 'dd',
        'columns'    => 3,
        'size'       => 'thumbnail',
        'include'    => '',
        'exclude'    => '',
        'link'       => ''
    ), $attr, 'gallery' );
    $id = intval( $atts['id'] );
    if ( ! empty( $atts['include'] ) ) {
        $_attachments = get_posts( array( 'include' => $atts['include'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
        $attachments = array();
        foreach ( $_attachments as $key => $val ) {
            $attachments[$val->ID] = $_attachments[$key];
        }
    } elseif ( ! empty( $atts['exclude'] ) ) {
        $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
    } else {
        $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
    }
    if ( empty( $attachments ) ) {
        return '';
    }
    if ( is_feed() ) {
        $output = "\n";
        foreach ( $attachments as $att_id => $attachment ) {
            $output .= wp_get_attachment_link( $att_id, $atts['size'], true ) . "\n";
        }
        return $output;
    }
    $itemtag = tag_escape( $atts['itemtag'] );
    $captiontag = tag_escape( $atts['captiontag'] );
    $icontag = tag_escape( $atts['icontag'] );
    $valid_tags = wp_kses_allowed_html( 'post' );
    if ( ! isset( $valid_tags[ $itemtag ] ) ) {
        $itemtag = 'dl';
    }
    if ( ! isset( $valid_tags[ $captiontag ] ) ) {
        $captiontag = 'dd';
    }
    if ( ! isset( $valid_tags[ $icontag ] ) ) {
        $icontag = 'dt';
    }
    $columns = intval( $atts['columns'] );
    $itemwidth = $columns > 0 ? floor(100/$columns) : 100;
    $float = is_rtl() ? 'right' : 'left';
    $selector = "gallery-{$instance}";
    $gallery_style = '';

So the goal of this would be able to put [gallery category="2"] or [gallery id="2"] or however way so that it displays all the images in a specific category, so any help would be very appreciated!

edit so the way I want it to work is to be able to put [gallery category="emergency-medicine"] and have all images or the top 20 most recent appear in the post or another example would be [gallery post_type="gallery" category="medicine"] and what I use to make these custom post types/categories is with the plugin ToolSet Types

function gallery_shortcode( $attr ) {
$post = get_post();
static $instance = 0;
$instance++;
if ( ! empty( $attr['ids'] ) ) {
    // 'ids' is explicitly ordered, unless you specify otherwise.
    if ( empty( $attr['orderby'] ) ) {
        $attr['orderby'] = 'post__in';
    }
    $attr['include'] = $attr['ids'];
}
/**
 * Filters the default gallery shortcode output.
 *
 * If the filtered output isn't empty, it will be used instead of generating
 * the default gallery template.
 *
 * @since 2.5.0
 * @since 4.2.0 The `$instance` parameter was added.
 *
 * @see gallery_shortcode()
 *
 * @param string $output   The gallery output. Default empty.
 * @param array  $attr     Attributes of the gallery shortcode.
 * @param int    $instance Unique numeric ID of this gallery shortcode instance.
 */
$output = apply_filters( 'post_gallery', '', $attr, $instance );
if ( $output != '' ) {
    return $output;
}
$html5 = current_theme_supports( 'html5', 'gallery' );
$atts = shortcode_atts( array(
    'order'      => 'ASC',
    'orderby'    => 'menu_order ID',
    'id'         => null,
    'itemtag'    => $html5 ? 'figure'     : 'dl',
    'icontag'    => $html5 ? 'div'        : 'dt',
    'captiontag' => $html5 ? 'figcaption' : 'dd',
    'columns'    => 3,
    'size'       => 'thumbnail',
    'include'    => '',
    'exclude'    => '',
    'link'       => '',
    'category' => null,
    'post_type' => 'uc-general-gallery',
    'img' => null
), $attr, 'gallery' );
$ids = array();
ob_start();
if ($atts['id'] != null ) {
    $id_str = preg_replace('/\s+/', '', $atts['id']); // strip whitespace
    $ids = explode(',', $id_str);
    ?>
     <?php foreach($ids as $id): ?>
                <?php if(is_numeric($id)): ?>
                                    <?php endif; ?>
            <?php endforeach; ?>
            <?php
} else if($atts['category'] != null) {
    $cat_str = preg_replace('/\s+/', '', $atts['category']); // strip whitespace
    $args = array(
        'post_type'         => $atts['post_type'],
        'order'             => 'DESC',
        'category_name'     => $cat_str,
        'posts_per_page' => 999
        );
    $the_query = new WP_Query( $args );
    if($the_query->have_posts() ) :
        ?>
         <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
         <?php endwhile; ?>
                     <?php
    endif;
}
if ( ! empty( $atts['include'] ) ) {
    $_attachments = get_posts( array( 'include' => $atts['include'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
    $attachments = array();
    foreach ( $_attachments as $key => $val ) {
        $attachments[$val->ID] = $_attachments[$key];
    }
} elseif ( ! empty( $atts['exclude'] ) ) {
    $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
} else {
    $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
}
if ( empty( $attachments ) ) {
    return '';
}
if ( is_feed() ) {
    $output = "\n";
    foreach ( $attachments as $att_id => $attachment ) {
        $output .= wp_get_attachment_link( $att_id, $atts['size'], true ) . "\n";
    }
    return $output;
}
$itemtag = tag_escape( $atts['itemtag'] );
$captiontag = tag_escape( $atts['captiontag'] );
$icontag = tag_escape( $atts['icontag'] );
$valid_tags = wp_kses_allowed_html( 'post' );
if ( ! isset( $valid_tags[ $itemtag ] ) ) {
    $itemtag = 'dl';
}
if ( ! isset( $valid_tags[ $captiontag ] ) ) {
    $captiontag = 'dd';
}
if ( ! isset( $valid_tags[ $icontag ] ) ) {
    $icontag = 'dt';
}
$columns = intval( $atts['columns'] );
$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
$float = is_rtl() ? 'right' : 'left';
$selector = "gallery-{$instance}";
$gallery_style = '';

So this is what I did to get it working(though kind of ugly) so now I can input [gallery post_type="uc-general-gallery" category="people-residents"] or just [gallery category="etc"] and it'll grab the images and display them, but in the visual editor it'll say no items found but when I actually view the post it does show up in the page, now another issue is I need it to be responsive for mobile users so when the screen shrinks down it'll turn into a slider or slideshow.

Edit

Never mind! my code is buggy and displays every image added instead of going by category, would there be an easy way to fix this?

1 Answer 1

1

There are various ways to run another WP_Query with a tax query and collect the ID's into the include attribute of the gallery shortcode.

Let's try another approach, without running a secondary WP_Query.

Native gallery: Support taxonomy and term attributes

We introduce the following custom gallery shortcode attributes:

[gallery taxonomy="media_category" term="people"]

Here's a demo plugin that supports that through the post_gallery, shortcode_atts_gallery filters and the pre_get_posts action:

<?php
/**
 * Plugin Name: Native Gallery Shortcode With Taxonomy And Term Filter Support
 * Description: Add support for [gallery taxonomy='some-taxonomy' term="some-term"]
 * Plugin URI:  http://wordpress.stackexchange.com/a/257801/26350
 */

namespace WPSE\Q257743;

class Gallery
{
    private $term;
    private $taxonomy;

    public function init()
    {
        add_filter( 'post_gallery', [$this, 'post_gallery'], 10, 2 );               
    }

    public function post_gallery( $html, $attr )
    {
        // Check user input for term and taxonomy
        if( empty( $attr['term'] ) || empty( $attr['taxonomy'] ) )
            return $html;

        // Validate taxonomy
        if( ! taxonomy_exists( $attr['taxonomy'] ) )
            return esc_html__( "Taxonomy doesn't exists!", 'wpse-257743' );

        // Validate term
        if( ! term_exists( $attr['term'] , $attr['taxonomy'] ) )
            return esc_html__( "Term doesn't exists!", 'wpse-257743' );

        $this->term     = $attr['term'];
        $this->taxonomy = $attr['taxonomy'];

        // Activate customization
        add_filter( 'shortcode_atts_gallery',   [$this, 'gallery_atts'] );
        add_action( 'pre_get_posts',            [$this, 'pre_get_posts'] );

        return $html;
    }

    public function gallery_atts( $pairs )
    {
        // Set include to a temporary non empty value (that becomes 0)
        $pairs['include'] = ' ';

        // Only run once per gallery
        remove_filter( current_filter(), __FUNCTION__ );

        return $pairs;
    }

    public function pre_get_posts( \WP_Query $q )
    {
        // Make sure it's attachments query
        if( 'attachment' !== $q->get( 'post_type' ) )
            return;

        $post__in = $q->get( 'post__in' );

        // Target queries with post__in (include)       
        if ( empty( $post__in ) )
            return;

        // Check for our temporary 0 value
        if( 1 === count( $post__in ) && 0 != $post__in[0] )
            return;

        $q->set( 'post__in', null );

        // Set the taxonomy query:
        $q->set( 'tax_query', 
            [
                [
                    'taxonomy'  => $this->taxonomy,
                    'field'     => 'slug',
                    'terms'     => $this->term,
                ]
            ]
        );

        // Adjust the number of images to e.g. max 100
        $q->set( 'posts_per_page', 100 );

        // Only run once per gallery
        remove_action( current_action(), __FUNCTION__ );
    }

}

add_action( 'init', [new Gallery, 'init' ] );

Note that here we added a limit of 100 images.

Hope you can test and adjust it further to your needs, and e.g. change it so it can support multiple terms.

9
  • Thank you!, I'll be trying this out as soon as I can, I'll get back to you with my results
    – plenk117
    Feb 24, 2017 at 19:00
  • Very sorry but I couldn't get this to work for me at all and also sorry I took a while to get back with my results, I keep on coming up with No Items found with whatever I try, I made custom taxonomies and terms, I used the taxonomies built in but I couldn't get it to work, can you provide me with some more input? I just tried your code as you did it, so I apologize if I was suppose to change a part of it to get it working.
    – plenk117
    Mar 1, 2017 at 5:32
  • Also I added a bit more code for the built in shortcode that I forgot to include if that makes any difference and I also explained myself a bit better, any help would be greatly appreciated.
    – plenk117
    Mar 1, 2017 at 5:34
  • Hi, I assumed you were assigning custom media taxonomies directly to the attachments, e.g. like you can with plugins like this one or as is nicely explained in this tutorial. (ps: I'm unrelated to both links) @plenk117
    – birgire
    Mar 1, 2017 at 10:00
  • Thanks I will look at those @birgire I actually got it working by editing some code in the built in gallery though it's not super pretty, but works for the most part, I will try out what you did too though to try to get it working, but another question I also want to make it responsive so that it turns into a slider or slideshow for mobile users, so if you know where I can get started on that would be great! I'll also put the code I did in.
    – plenk117
    Mar 1, 2017 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.