カスタムフィールド中に突然、
「ある投稿タイプの最新記事を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 ) )
などに書き換えてください。
目次
関数
2021年12月7日書き換え
- 著者の絞り込みの誤りを修正
- アーカイブへのリンクに投稿タイプ名を追加
- 編集リンクを追加
等
//サブループ呼び出し
//呼び出し例
//ページツリー使う場合の引数例「post_type="page" parent="recruit"」
function show_subloop( $atts ){
global $post;
$sentence = '';
//投稿タイプ
if( !empty( $atts['post_type'] ) ){
$post_type = $atts['post_type'];
}else{
$post_type = 'post';
}
$post_type_name = get_post_type_object( $post_type );
$post_type_label = $post_type_name->labels->name;
//表示数
if( !empty( $atts['show'] ) ){
$show = $atts['show'];
}else{
$show = 4;
}
//オフセット
if( !empty( $atts['offset'] ) ){
$offset = $atts['offset'];
}else{
$offset = 0;
}
//除外ターム
if( !empty( $atts['exclude_term'] ) ){
$exclude_term = $atts['exclude_term'];
}else{
$exclude_term = '';
}
//著者絞り込み
if( !empty( $atts['author'] ) ){
$author_id = get_user_by( 'slug', $atts['author'] )->id;
}else{
$author_id = '';
}
//カスタムフィールド値で絞り込み
if( !empty( $atts['meta_key'] ) && !empty( $atts['meta_value'] ) ){
$meta_key = $atts['meta_key'];
$meta_value = $atts['meta_value'];
$meta_compare = 'LIKE';
}
//ループのタイトル
if( !empty( $atts['term'] ) && $atts['term'] === 'current' ){
$terms = get_the_terms( $post->ID, $atts['tax'] );
foreach ( $terms as $term ) {
$term_slug = $term->slug;
$term_name = $term->name;
break;
}
$expost = get_the_ID();
$title = '<h2 class="loop-title shortcode-loop-title"><span class="slug">' . $term_slug . '</span><span class="page-language">' . $term_name . '</span></h2>';
}elseif( !empty( $atts['title'] ) ){
if( !empty( $atts['title_slug'] ) ){
$title = '<h2 class="loop-title shortcode-loop-title"><span class="slug">' . $atts['title_slug'] . '</span><span class="page-language">' . $atts['title'] . '</span></h2>';
}else{
$title = '<h2 class="shortcode-loop-title">' . $atts['title'] . '</h2>';
}
}else{
$title = '';
}
//アーカイブへのリンク
if( !empty( $atts['term'] ) && $atts['term'] === 'current' ){
$term_name = get_term_by( 'slug', $term_slug, $atts['tax'] )->name;
if( $term_name ){
$archive_link_url = get_term_link( $term_slug, $atts['tax'] );
$archive_link_anker = $term_name . 'の' . $post_type_label . '一覧';
}
}elseif( !empty( $atts['tax'] ) && !empty( $atts['term'] ) ){
$term_name = get_term_by( 'slug', $atts['term'], $atts['tax'] )->name;
if( $term_name ){
$archive_link_url = get_term_link( $atts['term'], $atts['tax'] );
$archive_link_anker = $term_name . 'の' . $post_type_label . '一覧';
}
}elseif( !empty( $atts['author'] ) ){
$author_id = get_user_by( 'slug', $atts['author'] )->id;
$archive_link_url = get_author_posts_url( $author_id );
$archive_link_anker = get_the_author_meta( 'display_name', $author_id ) . 'の' . $post_type_label . '一覧';
}else{
$archive_link_url = get_post_type_archive_link( $post_type );
$archive_link_anker = $post_type_label . '一覧';
}
if( !empty( $atts['archive_link_anker'] ) ){
$archive_link_anker = $atts['archive_link_anker'];
}
if( !empty( $atts['archive_link'] ) && $atts['archive_link'] === 'false' ){
}else{
$archive_link = '<div class="shortcode-loop-archive-link link-related"><a href="' . $archive_link_url . '">' . $archive_link_anker . '</a></div>';
}
//ラッパーにID付与
if( !empty( $atts['id'] ) ){
$id = ' id="' . $atts['id'] . '"';
}else{
$id = '';
}
//ラッパーにクラス付与
if( !empty( $atts['class'] ) ){
$class = ' ' . $atts['class'];
}else{
$class = '';
}
if( !empty( $atts['term'] ) && $atts['term'] === 'current' ){
$class .= ' term-' . $term_slug;
}
//.article-containerにクラス付与
if( !empty( $atts['style'] ) && $atts['style'] == 'text' ){
$container_class = ' display-text';
}elseif( !empty( $atts['style'] ) && $atts['style'] == 'thumbnail' ){
$container_class = ' display-thumbnail';
}elseif( !empty( $atts['style'] ) && $atts['style'] == 'grid' ){
$container_class = ' flex-container flex-dir-row display-grid-l flex-c4 flex-768-css flex-414-css flex-375-css flex-320-css';
$article_flex = ' flex-child';
}elseif( !empty( $atts['style'] ) && $atts['style'] == 'sidebar' ){
$container_class = ' display-sidebar';
}else{
$container_class = ' display-text';
}
//投稿にクラス付与
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'] ) ){
if( $atts['term'] === 'current' ){
$args = array(
'post_type' => $post_type,
'posts_per_page' => $show,
'post__not_in' => array( $expost ),
'tax_query' => array(
array(
'taxonomy' => $atts['tax'],
'field' => 'slug',
'terms' => $term_slug
)
)
);
}else{
$args = array(
'post_type' => $post_type,
'tax_query' => array(
array(
'taxonomy' => $atts['tax'],
'field' => 'slug',
'terms' => $atts['term'],
),
),
'posts_per_page' => $show,
'offset' => $offset,
'meta_key' => $meta_key,
'meta_value' => $meta_value,
'meta_compare' => $meta_compare,
);
}
$query = new WP_Query( $args );
}elseif( !empty( $atts['tax'] ) && !empty( $atts['exclude_term'] ) ){
$args = array(
'post_type' => $post_type,
'tax_query' => array(
array(
'taxonomy' => $atts['tax'],
'field' => 'slug',
'terms' => $exclude_term,
'operator' => 'NOT IN'
),
),
'author' => $author_id,
'posts_per_page' => $show,
'offset' => $offset,
'post_parent' => $parent_ID,
'meta_key' => $meta_key,
'meta_value' => $meta_value,
'meta_compare' => $meta_compare,
);
$query = new WP_Query( $args );
}else{
$args = array(
'post_type' => $post_type,
'author' => $author_id,
'posts_per_page' => $show,
'offset' => $offset,
'post_parent' => $parent_ID,
'meta_key' => $meta_key,
'meta_value' => $meta_value,
'meta_compare' => $meta_compare,
);
$query = new WP_Query( $args );
}
if( $query->have_posts() ){
$sentence .= '<div class="loop-container">' . "\n" . '<div' . $id . ' class="shortcode-loop shortcode-loop-' . $post_type . $class . '">' . "\n" . '<div class="loop-title-container archive-tille-container shortcode-loop-header">' . $title . "\n" . '</div>' . "\n" . '<div class="article-container flex-dir-row' . $container_class . '">' . "\n";
while( $query->have_posts() ){
$query->the_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_status = ' date-display-true';
$date = '<p class="date date-published">' . get_the_date() . '</p>';
}
//記事タイトル
if( !empty( $atts['title_length'] ) ){
$length = $atts['title_length'];
$more = ' …';
$post_title = wp_html_excerpt( the_title_attribute( 'echo=0' ), $length, $more );
// $post_title = mb_strimwidth( strip_tags( the_title_attribute( 'echo=0' ) ), 0, $length, '', 'UTF-8' );
}else{
$post_title = the_title_attribute( 'echo=0' );
}
//要約
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() . '"';
$link_class = '';
$link_target = '';
}
$self_id = ' id="post-' . get_the_ID() . '"';
}
//サムネール
$thumbnail_size = 'thumbnail-169';
$default_thumbnail = get_stylesheet_directory_uri() . '/images/' . $thumbnail_size . '-default.png';
if( has_post_thumbnail() && !post_password_required() ){
$image_url = get_the_post_thumbnail_url( get_the_ID(), $thumbnail_size );
}else{
$image_url = $default_thumbnail;
}
$image_style = ' style="background-image: url( '.$image_url.' );"';
if( !empty( $atts['thumbnail'] ) && $atts['thumbnail'] == 'true' ){
$thumbnail = '<a class="article-image' . ' aspect-' . $thumbnail_size . '" href="' . get_permalink() . '"' . $image_style . '></a>';
$thumbnail_status = ' have-thumbnail';
}else{
$thumbnail = '';
$thumbnail_status = ' no-thumbnail';
}
//タグ
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 = '';
}
//「詳しく見る」ボタン
if( !empty( $atts['link_btn'] ) && $atts['link_btn'] == 'true' ){
$link_btn = '<p>詳しく見る</p>';
}
//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 );
}
}
//編集リンク
if( current_user_can( 'edit_post', get_the_ID() ) ){
$edit_link = get_option( 'p2_edit_link' );
$edit_link_url = get_edit_post_link();
if( $edit_link == 1 ){
}else{
$edit_this = '<footer class="entry-meta edit-link-wrap"><span class="edit-link"><a href="' . $edit_link_url . '" target="_blank" rel="noopener">' . __( 'Edit This' ) . '</a></span></footer>';
}
}
$sentence .= '<article' . $self_id . 'class="shortcode-article va-css' . $article_flex . $ranking . $article_class . $thumbnail_status . $date_status . $current . '">' . $thumbnail . '<div class="loop-content">' . $avatar . $author_display . '<header class="entry-header">' . $date . '<h2 class="entry-title post-title">' . '<a class="link-shortcode-title' . $link_class . '"' . $link_url . $link_target . '>' . $post_title . '</a>' . '</h2>' . '</header>' . $tags . $excerpt . $cf_data_archive . $link_btn . $edit_this . '</div></article>' . "\n";
$tags = '';
}
$sentence .= "\n" . '</div>' . $archive_link . "\n" . '</div>' . "\n" . '</div>' . "\n";
}
wp_reset_postdata( );
return $sentence;
}
add_shortcode( 'show_subloop', 'show_subloop' );
オプション
デフォルト
標準投稿、最新記事から4つ、日付、サムネールあり)
カスタム投稿
タクソノミ
「tax=”news_cat”」
ターム
「term=”breaking”」
著者絞り込み
「author=”ユーザー名”」
表示は「ブログ上の表示名」ですが、リンクにはユーザー名が出ちゃうのであまり意味ないか。
アーカイブへのリンクは該当著者の記事一覧になります。
表示数
「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=”一覧:重要なニュース”」= リンクアンカーを置き換えます。
編集リンク
「get_option( ‘p2_edit_link’ )」はグローバル変数によるオプションなので、条件分岐は削除しちゃってください。
そのほか、カスタムフィールドやWPP(人気記事リストを作ってくれるプラグイン)などにも対応してますが、コピペでは動かないので割愛。
固定ページでのツリー表示、ページ内遷移用のリンクなども必要だったのでくっつけてますが、普通は要らないか。
大分長くなっちゃったので、別ファイルにしてfunctions.phpに読み込んでくださいませ。
そのうちプラグインにしてみよう、、、かな
▼実際に貼り付けると▼
「show_subloop」
2023年03月31日
【複数選択対応】Search & Filter Pro 検索結果ページに検索ワードを出力する
標準投稿用のソースをありがたく参考にさせていただきました。
https://gatespace.jp/2012/03/28/show_categoryposts_shortcode/