How do I organize photos for multiple galleries?

Recently I’m using this workflow:

  1. Register a custom taxonomy for attachments
  2. Use some code to add the feature of mass assign taxonomy terms to uploaded images

    (Because I do these 2 tasks frequently I’ve created a plugin that implement them and more see here)

  3. Create in a plugin a shorcode that looks like [gallery_term tag="landscapes, still_life"]. This shortcode takes the tag(s) passed as shorcode param and use them in a WP_Query with meta_query to retrieve images and output them.

Once done I need only to upload images and assign them a tag for every gallery to which they belongs (using my plugin for bulk assignment it’s a cinch). The create a post (or a page, or a cpt) and use the shortcode. That’s all.

This workflow is absloutely powerful and flexible:

  • I can have galleries wherever I want: in pages, in posts, in custom post types, even in sidebar. I can use post (or pages or cpt) title, content, taxonomies & custom meta for gallery details.
  • I can simply use the featured image as cover image for the gallery.
  • Photos can belong to different taxonomies, and so to different galleries, without have to upload them multiple times or have to add image informations multiple times.
  • All the features are implemented only via wp core features: solid and future proof!

A great piece of my workflow is done by the shortcode function, that is something like this:

add_shortcode( 'gallery_term', 'show_gallery_term' );

function show_gallery_term( $atts ) {
  extract( shortcode_atts( array(
    'tax' => 'media-tag', // this is the name of taxonomy registered by my plugin
    'tags' => '',
    'qv' => '', // query vars
    'template' => 'gallery.php', 'item_template' => 'gallery-item.php',
    'wrap' => 1, 'wrap_class' => 'gallery-wrap',
    'class' => 'gallery', 'item_class' => 'gallery-item',
    'th_size' => 'thumb',
    'link' => 1, 'link_size' => 'full', 'link_rel' => '', 'permalink' => ''
  ), $atts ) );
  // parse query vars
  $qv = wp_parse_args($qv, 'order_by=menu_order&posts_per_page=-1&post_mime_type=image/jpeg,image/gif,image/jpg,image/png');
  // force some query vars
  $qv['post_type'] = 'attachment';
  $qv['post_status'] = 'inherit';
  $qv['paged'] = get_query_var('paged') ? : 1;
  // the taxonomy query
  if ( $tax && in_array( $tax, get_object_taxonomies('attachment')) && ! empty($tags) ) {
    $qv['meta_query'] = array( array(
      'taxonomy' => $tax, 'field' => 'slug', 'terms' => $tags, 'operator' => 'IN'
    ) );
  }
  $images = new WP_Query($qv);
  if ( $images->have_posts() ) {
    $template = apply_filters('def_gallery_template', $template);
    global $gallery_query, $gallery_atts;
    $gallery_query = $images;
    $gallery_atts = $atts;
    ob_start();
    if ( ! locate_template($template, true, false) ) { // use a template file to display gallery
      if ($wrap) echo '<div class="' . esc_attr($wrap_class) . '">';
      echo '<ul class="' . esc_attr($class) . '">';
      $item_template = apply_filters('def_gallery_item_template', $item_template);
      while ( $images->have_posts() ) :
        $images->the_post();
        if ( ! locate_template($item_template, true, false) ) { // use a template file to display gallery items
          echo '<li class="' . esc_attr($item_class) . '">';
          $th = wp_get_attachment_image_src( get_the_ID(), $th_size);
          $title = esc_attr( get_the_title() );
          $rel = $link_rel ? ' rel="' . esc_attr($link_rel) . '" ' : '';
          $link_format="<a href="https://wordpress.stackexchange.com/questions/112346/%s" title="https://wordpress.stackexchange.com/questions/112346/%s"%s>";
          if ($link) { // link to another size
            $big = wp_get_attachment_image_src( get_the_ID(), $link_size);
            printf($link_format, $big[0], $title, $rel);
          } elseif ( $permalink ) { // link post attachment permalink
            printf($link_format, get_permalink(), $title, $rel);
          }
          printf('<img src="https://wordpress.stackexchange.com/questions/112346/%s" alt="https://wordpress.stackexchange.com/questions/112346/%s" width="%d" height="%d" />', $th[0], $title, $th[1], $th[2]);
          if ( $link || $permalink ) echo '</a>';
          echo '</li>';
        }
      endwhile;
      echo '</ul>';
      if ($wrap) echo '</div>';
    }
    unset($gallery_query, $gallery_atts);
    wp_reset_postdata();
    return ob_get_clean();
  }
}

This function provide huge flexibility, in fact:

  • I can use the file gallery.php in current theme to output my
    gallery (using global $gallery_query variable). If I want to use
    another template I can change it passing name via shortcode param or
    via a filter
    .
  • Is possible don’t use any template for all gallery, but use a template for
    any gallery item. The default is gallery-item.php but again I can
    change it via shortcode or via filter. Using this template the
    attachment post is accessible in the global $post variable, so all
    template tags works
  • Is also possible don’t use any template at all and let function output the html. In this case a lot of options let configure the resulting html.
  • If one is lazy can use shortcode in like this: [gallery_term tag="atag"] and do not create any template file… it works!
  • The workflow is javascript agnostic: In the theme is possible enqueue the desired script go wild with it. Want to chang theme and chang script: no problem at all!