wordpress ギャラリーのショートコードを変更する

2013年6月1日

WordPress のデフォルトのギャラリーでは <style> タグが自動的に挿入されたり、サムネイルが <dl> タグで出力されるなど、使い勝手が悪い。

検索したところ「使いづらいWordPressのギャラリーをけっこう使えるギャラリーにする方法(Webデザインレシピ)」にとてもわかりやすい解説があったので参考にさせていただく。

リストで出力するギャラリーのショートコードの作成

  • サムネイルは <li> 要素で出力するようにする。
  • <style> タグが自動的に挿入されないようにする。
  • サムネイルのリンク先は元の画像にする。[ gallery link=”file”]で指定したのと同じ。
  • ギャラリーのショートコードの記述(function gallery_shortcode($attr))は、wp-includes の media.php にある。
  • 上記 gallery_shortcode()をコピーして「functions.php」に名前を変えて保存してカスタマイズ。
  • デフォルトのギャラリーのショートコードを削除し、新しいショートコードを登録。
remove_shortcode('gallery', 'gallery_shortcode');    //デフォルトのショートコードの削除
add_shortcode('gallery', 'my_gallery_shortcode');    //新しいショートコードの追加
//オリジナルの gallery_shortcode()をコピーして名前を変えカスタマイズした関数
function my_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'];
  }

  // Allow plugins/themes to override the default gallery template.
  $output = apply_filters('post_gallery', '', $attr);
  if ( $output != '' )
    return $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->ID,
    'itemtag'    => 'li',    //オリジナルは「dl」
    'icontag'    => 'p',    //オリジナルは「dt」
    'captiontag' => 'p',    //オリジナルは「dd」
    'columns'    => 3,
    'size'       => 'thumbnail',
    'include'    => '',
    'exclude'    => ''
  ), $attr));

  $attr['link'] = 'file';    //サムネイルのリンク先は元の画像にするため追加。

  $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() ) {
    $output = "\n";
    foreach ( $attachments as $att_id => $attachment )
      $output .= wp_get_attachment_link($att_id, $size, true) . "\n";
    return $output;
  }

  $itemtag = tag_escape($itemtag);
  $captiontag = tag_escape($captiontag);
  $icontag = tag_escape($icontag);
  $valid_tags = wp_kses_allowed_html( 'post' );
  if ( ! isset( $valid_tags[ $itemtag ] ) )
    $itemtag = 'li';    //オリジナルは「dl」
  if ( ! isset( $valid_tags[ $captiontag ] ) )
    $captiontag = 'p';    //オリジナルは「dd」
  if ( ! isset( $valid_tags[ $icontag ] ) )
    $icontag = 'p';    //オリジナルは「dt」

  $columns = intval($columns);
  $itemwidth = $columns > 0 ? floor(100/$columns) : 100;
  $float = is_rtl() ? 'right' : 'left';

  $selector = "gallery-{$instance}";

  $gallery_style = $gallery_div = '';    
  //オリジナルではこの部分にスタイルシートの指定があるので削除

  $size_class = sanitize_html_class( $size );
  $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'><ul class='clearfix'>";    //ul タグを追加(必要であればクラス名の追加や変更が可能)
  $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );

  $i = 0;
  foreach ( $attachments as $id => $attachment ) {
    $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
    //42行目の $attr['link'] = 'file';を追加せずに上記を $link = wp_get_attachment_link($id, $size, false, false);としても、サムネイルのリンクを元画像にできる。
    //<{$itemtag}> は <li>
    $output .= "<{$itemtag} class='gallery-item'>";    //必要であればクラス名の追加や変更が可能)
    //<{$icontag}>は<p>。$attachment->post_excerpt や post_content、post_title などを「wptexturize」を用いて追加記述も可能
    $output .= "    
      <{$icontag} class='gallery-icon'>
        $link
      </{$icontag}>";
    if ( $captiontag && trim($attachment->post_excerpt) ) {
      $output .= "
        <{$captiontag} class='wp-caption-text gallery-caption'>
        " . wptexturize($attachment->post_excerpt) . "
        </{$captiontag}>";
    }
    $output .= "</{$itemtag}>";
  //ここの記述 if ( $columns > 0 && ++$i % $columns == 0 ) $output .= '<br style="clear: both" />';も不要なので削除
  }

  $output .= "
    </ul></div>\n";    //ul の閉じタグを追加

  return $output;
}
wp_get_attachment_link($id, $size, $permalink, $icon, $text)
添付ファイルへのリンクのHTMLテキストを取得する。添付ファイルのみを対象とするループで使用。
パラメータ
$id(オプション):添付ファイルのID(デフォルトは現在の投稿(添付ファイル)のID)
$size(オプション):サイズを指定(デフォルトは'thumbnail')
$permalink(オプション):パーマリンクを使用する場合は true を指定(デフォルトはfalse)
$icon(オプション):アイコン画像を使用する場合は true を指定(デフォルトはfalse)
$text(オプション): リンクテキストを指定(デフォルトは false)。この文字列を指定すると画像は表示されずに代わりにこの文字列がリンクとして表示される。
戻り値
アタッチメント情報が存在する場合は、そのHTMLテキストを返す。アタッチメント情報が得られない場合は文字列「Missing Attachment(を翻訳したもの)」を返す。

画像をアップロードした際に指定したタイトル、 キャプション、代替テキスト、説明は以下の部分で使用される。

  • タイトル:a 要素の title 属性の値($post->post_title)
  • キャプション:p 要素(class=”wp-caption-text gallery-caption”)の内容($post->post_excerpt)
  • 代替テキスト:img 要素の alt 属性の値
  • 説明:上記の場合は使用されていないが、$attachment->post_content で出力できる。

また、上記のカスタマイズしたショートコードの添付ファイルのループ(下記)の部分を変更することで、出力をさらにカスタマイズすることができる。

foreach ( $attachments as $id => $attachment ) {
    $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);

    $output .= "<{$itemtag} class='gallery-item'>";
    $output .= "
      <{$icontag} class='gallery-icon'>
        $link
      </{$icontag}>";
    if ( $captiontag && trim($attachment->post_excerpt) ) {
      $output .= "
        <{$captiontag} class='wp-caption-text gallery-caption'>
        " . wptexturize($attachment->post_excerpt) . "
        </{$captiontag}>";
    }

    //説明($attachment->post_content)を追加する場合
    //<{$captiontag}>タグ(<p>)を使って出力
    if ( $captiontag && trim($attachment->post_content) ) {
      $output .= "
        <{$captiontag} class='wp-content-text gallery-content'>
        " . wptexturize($attachment->post_content) . "
        </{$captiontag}>";
    }

    $output .= "</{$itemtag}>";
  }

ただ、これでも使いにくい場合があるので、独自に関数を作成(こちらを参照)。