ショートコードでカスタム投稿一覧を呼び出す。ターム、n番目など細かく制御

ワードプレスのメモ

カスタムフィールド中に突然、

「ある投稿タイプの最新記事を1件だす。」

「別のフィールドに、ある投稿タイプの2番目に新しい記事を1件だす。」

ということが必要になり、

「まぁ、これはショートコードで処理するのが簡単かな。」と思い、作ってみました。

※2020/4/2

1:エラー処理が足りなかった、オプションを大量に追加、などで全面書き換えしました。

2:「get_field」「the_field」等はACFプラグインが無いとエラーを出します。

インストールだけでもするか、

あるいは該当箇所を

・get_post_meta( $post->ID, ‘○○○’, true ) )

・echo get_post_meta( $post->ID, ‘○○○’, true ) )

などに書き換えてください。

関数

function show_subloop( $atts ){
	global $post;
	$sentence = '';

//投稿タイプ
if( !empty( $atts['post_type'] ) ){
	$post_type = $atts['post_type'];
}else{
	$post_type = 'post';
}

//表示数
if( !empty( $atts['show'] ) ){
	$show = $atts['show'];
}else{
	$show = 4;
}

//オフセット
if( !empty( $atts['offset'] ) ){
	$offset = $atts['offset'];
}else{
	$offset = 0;
}

//著者絞り込み
if( !empty( $atts['author'] ) ){
	$user = get_user_by( 'id', $atts['author'] );
	if( $user ){
		$author_id = $user->id;
	}else{
		$author_id = '';
	}
}

//タイトル
if( !empty( $atts['title'] ) ){
	$title = '<h2 class="shortcode-loop-title">' . $atts['title'] . '</h2>';
}else{
	$title = '';
}

//アーカイブへのリンク
if( !empty( $atts['archive_link_anker'] ) ){
	$archive_link_anker = $atts['archive_link_anker'];		
}else{
	$archive_link_anker = 'アーカイブ';
}
if( !empty( $atts['archive_link'] ) && $atts['archive_link'] == 'true' ){
	if( !empty( $atts['tax'] ) && !empty( $atts['term'] ) ){
		$term_name = get_term_by( 'slug', $atts['term'], $atts['tax'] )->name;
		$archive_link_anker .= ':' . $term_name;
		$archive_link = '<div class="shortcode-loop-archive-link"><a href="' . get_term_link( $atts['term'], $atts['tax'] ) . '">' . $archive_link_anker . '</a></div>';
	}else{
		$archive_link = '<div class="shortcode-loop-archive-link"><a href="' . get_post_type_archive_link( $post_type ) . '">' . $archive_link_anker . '</a></div>';
		$archive_link_anker .= '';
	}
}else{
	$archive_link = '';
}

//ラッパーにID付与
if( !empty( $atts['id'] ) ){
	$id = ' id="' . $atts['id'] . '"';
}else{
	$id = '';
}

//ラッパーにクラス付与
if( !empty( $atts['class'] ) ){
	$class = ' ' . $atts['class'];
}else{
	$class = '';
}

//投稿にクラス付与
if( !empty( $atts['article_class'] ) ){
	$article_class = ' ' . $atts['article_class'];
}else{
	$article_class = '';
}

//設置ページのID
$location_id = get_the_ID();

//親ページのID取得
if( !empty( $atts['parent'] ) ){
	$parent_data = get_page_by_path( $atts['parent'] );
	$parent_ID = $parent_data->ID;
}

//WPPのデータ取得
if( function_exists( 'wpp_get_mostpopular' ) ){
$wpp_args = array(
	'range' => 'last30days',
	'order_by' => 'views',
	'post_type' => 'column',
);
$wpp_query = new WPP_Query( $wpp_args );
$rank_data = $wpp_query->get_posts();
}

//▲ループ外処理ここまで▲

//出力条件
if( !empty( $atts['tax'] ) && !empty( $atts['term'] ) ){
	$args = array(
		'post_type' => $post_type,
		'tax_query' => array(
			array(
				'taxonomy'	=> $atts['tax'],
				'field'		=> 'slug',
				'terms'		=> $atts['term'],
			),
		),
		'posts_per_page'	=> $show,
		'offset'			=> $offset,
	 );
	$shortcode_posts = get_posts( $args );
}else{
	$args = array(
		'post_type'			=> $post_type,
		'author'			=> $author_id,
		'posts_per_page'	=> $show,
		'offset'			=> $offset,
		'post_parent'		=> $parent_ID,
	);
	$shortcode_posts = get_posts( $args );
}
	if( $shortcode_posts ){
		$sentence .= '<div' . $id . ' class="shortcode-loop shortcode-loop-' . $post_type . $class . '">' . "\n" . '<div class="shortcode-loop-header">' . $title . "\n" . '</div>' . "\n" . '<div class="article-container">' . "\n";
		foreach ( $shortcode_posts as $post ){
			setup_postdata( $post );

//▼ループ内処理ここから▼

//ID比較
$article_id = get_the_ID();
if( $location_id == $article_id ){
	$current = ' current';
}else{
	$current = '';
}

//著者表示
if( !empty( $atts['show_author'] ) && $atts['show_author'] == 'true' ){
	$author_display = '<p class="author"><span class="fn">' . get_the_author_posts_link() . '</p>';
}else{
	$author_display = '';
}

//アバター
if( !empty( $atts['avatar'] ) && $atts['avatar'] == 'true' ){
	$avatar = '<a href="' . get_author_posts_url( $post->post_author ) . '" class="a-avatar" style="background-image: url(' . get_avatar_url( $post->post_author ) . ');"></a>';
}

//日付
if( !empty( $atts['date'] ) && $atts['date'] == 'false' ){
	$date = '';
}else{
	$date = '<p class="date">' . get_the_date() . '</p>';
}

//要約
if( !empty( $atts['excerpt'] ) && $atts['excerpt'] == 'false' ){
	$excerpt = '';
}else{
	$excerpt = '<div class="entry-content entry-body excerpt-container">' . mb_strimwidth( strip_tags( $post->post_content ), 0, 92, '', 'UTF-8' ) . '</div>';
}

//ページ内リンク
if( !empty( $atts['samepage'] ) && $atts['samepage'] == 'true' ){
	$link = '#post-' . get_the_ID();
	$self_id = ' id="link-post-' . get_the_ID() . '"';
}else{
	if( get_post_meta( $post->ID, 'post_linknone', true ) ){
		$article_link_class = ' article-link-none';
		$link_url = '';
		$link_class = ' link-none';
		$link_more = 'false';
	}elseif( get_post_meta($post->ID, 'post_linkurl', true ) ){
		$link_url = ' href="' . get_post_meta( $post->ID, 'post_linkurl', true ) . '"';
		$link_class = ' link-optional';
		if( get_post_meta($post->ID, 'post_link_blank', true ) ){
			$link_target = ' target="_blank" rel="noreferrer noopener"';
			$link_class = ' link-optional link-ext';
		}
	}else{
		$link_url = ' href="' . get_permalink() . '"';
	}
	$self_id = ' id="post-' . get_the_ID() . '"';
}

//サムネール
if( has_post_thumbnail() && !post_password_required() ){
	$image_url = get_the_post_thumbnail_url( get_the_ID(), 'thumbnail-vga' );
}else{
	$image_url = get_stylesheet_directory_uri() . '/images/thumbnail-default-vga.png';
}
$image_style = ' style="background-image: url( '.$image_url.' );"';
if( !empty( $atts['thumbnail'] ) && $atts['thumbnail'] == 'false' ){
	$thumbnail = '';
}else{
	$thumbnail = '<a class="article-image" href="' . get_permalink() . '"' . $image_style . '></a>';
}

//タグ
if( !empty( $atts['taglist'] ) && $atts['taglist'] == 'false' ){
}else{
	$taxonomies = get_the_taxonomies();
	if( !empty( $taxonomies ) ){
		$tags .= '<p class="taglist">';
		$count=1;
		foreach ( $taxonomies as $tax => $value ){
		    $tags .= '<span class="taglist-tax taglist-' . $tax . ' tax-order-' . $count . '">';
			$terms = wp_get_object_terms( $post->ID, $tax );
			foreach ( $terms as $term ){
				$tags .= '<a href="' . get_term_link( $term ) . '" class="taglist-term taglist-term-' . esc_html( $term->slug ) . '">' . $term->name . '</a>';
			}
			$tags .= '</span>';
		$count++;
		}
		$tags .= '</p>';
	}
}

//カスタムフィールド
if( !empty( $atts['cf_data'] ) && $atts['cf_data'] == 'true' ){
	if( get_field( 'cf_data_archive' ) ){
		$cf_data_archive = '<div class="cf-data cf-data-archive">' . get_field( 'cf_data_archive' ) . '</div>';
	}else{
		$cf_data_archive = '';
	}
}else{
	$cf_data_archive = '';
}

//WPP順位取得
if( function_exists( 'wpp_get_mostpopular' ) ){
$rank_num = array_search( get_the_ID(), array_column( $rank_data, 'id' ) );
if ( $rank_num !== false ) {
	$ranking = ' ranking ranking-' . ( $rank_num + 1 );
}
}

			$sentence .= '<article' . $self_id . 'class="shortcode-article' . $ranking . $article_class . $current . '">' . $thumbnail . '<div class="loop-content">' . $avatar . $author_display . $date . '<h2 class="entry-title post-title">' . '<a class="link-shortcode-title' . $link_class . '"' . $link_url . $link_target . '>' . get_the_title() . '</a>' . '</h2>' . $tags . $excerpt . $cf_data_archive . '</div></article>' . "\n";
			$tags = '';
		}
		$sentence .=  "\n" . '</div>' . $archive_link . "\n" . '</div>' . "\n";
	}
	wp_reset_postdata( );
	return $sentence;
}
add_shortcode( 'show_subloop', 'show_subloop' );

オプション

デフォルト

標準投稿、最新記事から4つ、日付、サムネールあり)

「show_subloop」
カスタム投稿
「post_type=”news”」
タクソノミ

「tax=”news_cat”」

ターム

「term=”breaking”」

著者絞り込み

「author=”1″」=ID1の著者の記事(ユーザー名でも可、にしたかも)

表示数

「show=”1″」=1件

「show=”-1″」=全件

オフセット

「offset=”1″」=2番目に新しい記事

要約

「excerpt=”false”」=要約を出さない

サムネール

「thumbnail=”false”」=アイキャッチ無し

日付

「date=”false”」=日付無し

タグ

「taglist=”false”」=タグ無し

著者表示

「show_author=”true”」=著者表示

アバター

「avatar=”true”」=アバターアイコン出力

タイトル

「title=”ループのタイトル”」=ブロック内にh2タイトルを表示します。

アーカイブへのリンク

「archive_link=”true”」=投稿タイプアーカイブへのリンクを出力します。

taxとtermが指定してあれば、タームへのリンクに変わります。

「archive_link_anker=”一覧”」=一覧、関連記事など任意にアンカーを書き換え

「一覧:重要なニュース」のような感じになります。

 

そのほか、カスタムフィールドやWPP(人気記事リストを作ってくれるプラグイン)などにも対応してますが、コピペでは動かないので割愛。

固定ページでのツリー表示、ページ内遷移用のリンクなども必要だったのでくっつけてますが、普通は要らないか。

 

大分長くなっちゃったので、別ファイルにしてfunctions.phpに読み込んでくださいませ。

そのうちプラグインにしてみよう、、、かな

▼実際に貼り付けると▼

「show_subloop」

標準投稿用のソースをありがたく参考にさせていただきました。

https://gatespace.jp/2012/03/28/show_categoryposts_shortcode/