how to have the gallery shortcode output one single UL list instead of several DL?

I need the built-in gallery shortcode to output UL instead of DL. How can I do it? I know I can use the ‘post_gallery’ filter, but that means almost duplicating the media’s gallery_shortcode function. I’d like to find a less ‘verbose’ solution.

Thank you

Related posts

Leave a Reply

2 comments

  1. You can use the the following attributes for the gallery shortcode:

    [gallery itemtag="ul" icontag="li" captiontag="li"]
    

    The problem with this is that the gallery shortcode wraps the image and the caption in different elements(thats why the default solution is using dl-dt-dd), so this will generate one li element for the image, and one for the caption. You can still style it using CSS though, because both of the element has unique classnames.

  2. Ok, so I rewrote the gallery shortcode function by copying the original and removing/adding/changing what I needed, and now I share it with you. The major things I added/changed are:

    • One single UL/LI list per gallery instead of a DL for each damned item..
    • Removed ‘itemtag’ attr, since there’s no point in using another tag for items inside an UL
    • ‘icontag’ now defaults to ‘figure’, ‘captiontag’ now defaults to ‘p’
    • new ‘class’ attr for adding a custom class to the container UL
    • new ‘first-in-row’, ‘last-in-row’, ‘first-row’, ‘last-row’ helper classes for LI items (though I strongly recommend to use nth-child css selectors instead)

    Here’s the code:

    //remove styles: I'll use mine
    add_filter('use_default_gallery_style','__return_false');
    
    
    //remove default shortcode
    remove_shortcode('gallery');
    //add new shortcode
    add_shortcode('gallery', 'custom_gallery');
    
    function custom_gallery($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'];
      }
    
      $output = '';
    
      // We're trusting author input, so let's at least make sure it looks like a valid orderby statement
      if(isset($attr['orderby'])){
        $attr['orderby'] = sanitize_sql_orderby($attr['orderby']);
        if(!$attr['orderby']) unset($attr['orderby']);
      }
    
      extract(shortcode_atts(array(
        'order'      => 'ASC',
        'orderby'    => 'menu_order ID',
        'id'         => $post ? $post->ID : 0,
        'icontag'    => 'figure',
        'captiontag' => 'p',
        'columns'    => 3,
        'size'       => 'thumbnail',
        'include'    => '',
        'exclude'    => '',
        'link'       => '',
        'class'      => ''//now you can add custom class to container UL 
      ), $attr, 'gallery'));
    
      $id = intval($id);
    
      if('RAND' == $order) $orderby = 'none';
    
      if(!empty($include)){
        $_attachments = get_posts(array(
          'include' => $include,
          'post_status' => 'inherit',
          'post_type' => 'attachment',
          'post_mime_type' => 'image',
          'order' => $order,
          'orderby' => $orderby
        ));
    
        $attachments = array();
        foreach($_attachments as $key => $val){
          $attachments[$val->ID] = $_attachments[$key];
        }
      } elseif (!empty($exclude)){
        $attachments = get_children(array(
          'post_parent' => $id,
          'exclude' => $exclude,
          'post_status' => 'inherit',
          'post_type' => 'attachment',
          'post_mime_type' => 'image',
          'order' => $order,
          'orderby' => $orderby
        ));
      } else {
        $attachments = get_children(array(
          'post_parent' => $id,
          'post_status' => 'inherit',
          'post_type' => 'attachment',
          'post_mime_type' => 'image',
          'order' => $order,
          'orderby' => $orderby
        ));
      }
    
      if(empty($attachments)) return '';
    
      //if ( is_feed() ) //removed, see original in media.php
    
    
      $itemtag = tag_escape('li');//new tag for item 
      $captiontag = tag_escape($captiontag);
      $icontag = tag_escape($icontag);
    
      //valid tags check removed, see original in media.php
    
      $columns = intval($columns);
      $selector = "gallery-{$instance}";
    
      $size_class = sanitize_html_class( $size );
    
      //new tag for container 
      $output = "<ul id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class} {$class}'>";
    
      $i = 0;
      $c = count($attachments);
      $o = (int)floor($c/$columns)*$columns;
    
      foreach ( $attachments as $id => $attachment ) {
        if(!empty($link) && 'file' === $link) $image_output = wp_get_attachment_link($id,$size,false,false);
        elseif(!empty($link) && 'none' === $link) $image_output = wp_get_attachment_image($id,$size,false);
        else $image_output = wp_get_attachment_link( $id, $size, true, false );
        $image_meta = wp_get_attachment_metadata($id);
        $orientation = '';
        if(isset($image_meta['height'], $image_meta['width'])) $orientation = ($image_meta['height'] > $image_meta['width']) ? 'portrait' : 'landscape';
    
        //setup custom aux classes to help style
        $m = ++$i % $columns;
        $item_pos_class = ($m == 1) ? 'first-in-row' : (($m == 0) ? 'last-in-row' : '');
        $row_class = ($i <= $columns) ? 'first-row' : (($i > $o) ? 'last-row' : '');
    
        //added: custom aux classes
        $output .= "<{$itemtag} class='gallery-item {$item_pos_class} {$row_class}'>";
        $output .= "<{$icontag} class='gallery-icon {$orientation}'>$image_output</{$icontag}>";
        if($captiontag && trim($attachment->post_excerpt)){
          $output .= "<{$captiontag} class='wp-caption-text gallery-caption'>" . wptexturize($attachment->post_excerpt) . "</{$captiontag}>";
        }
        $output .= "</{$itemtag}>";
      }
    
      //changed BR>clear:both with a more conventional clearfix div
      $output .= "</ul>n<div class='clearfix'></div>";
    
      return $output;
    }//end custom gallery
    

    And just to complete the gallery shortcode “chapter”, here I show you how to eventually programmatically change the default and/or user defined attributes. Say for example I need to change the size attr based on number of items:

    add_filter('shortcode_atts_gallery','set_gallery_thumbs_size',10,3);
    
    function set_gallery_thumbs_size($out, $pairs, $atts) {
    
      //in this case, if size was defined by the user, keep original and stop here
      if(isset($atts['size'])) return $out;
    
      //get number of images
      $c = count(explode(',',$atts['ids']));
      //set different sizes based on items count
      //new sizes were created with add_image_size() and image_size_names_choose filter (see wp docs)
      $atts['size'] = ($c > 2) ? 'thumb-3c' : ( ($c > 1) ? 'thumb-2c' : 'thumbnail');
      //merge original array with new one and return it
      return array_merge($out,$atts);
    }
    

    Hope it will help other people searching for a cleaner gallery markup.