fetch feed 外部ブログのフィードを表示する。サムネール、文字列操作

ワードプレスのメモ

Google Feed APIが廃止になったとき、結構騒いだ記憶があります。

最近また要望があったので改めて実装して、結構苦労したのでメモ。

ソース

<div class="rss-feed sub-loop have-loop">
<?php //RSSフィード表示
include_once( ABSPATH . WPINC . '/feed.php' );
$rss = fetch_feed( array(
'RSSのURL-1',
'RSSのURL-2'
) );
$maxitems = 0;
if ( !is_wp_error( $rss ) ){ //フィード生成チェック
	//出力件数
	$maxitems = $rss->get_item_quantity( 10 ); 
	//記事配列を生成
	$rss_items = $rss->get_items( 0, $maxitems );
}
?>
<script>
$(document).ready(function(){
$(function(){
	$( '.rss-crousel' ).slick({
		infinite: true,
		dots: false,
		slidesToShow: 4,
		slidesToScroll: 1,
		autoplay:true,
		autoplaySpeed: 2500,
		lazyLoad: 'progressive',
		responsive: [{
			breakpoint: 769,
			settings: {
				slidesToShow: 3,
				slidesToScroll: 1,
			}
		},{
			breakpoint: 415,
			settings: {
				slidesToShow: 2,
				slidesToScroll: 1,
			}
		}]
	});
});
});
</script>

	<div class="loop-container"><div class="inner have-crousel">
		<div class="article-container rss-crousel multiple-item">

	<?php if ( $maxitems == 0 ){ ?>
			<article><?php _e( 'No items', 'my-text-domain' ); ?></article>
	<?php }else{ ?>
		<?php
foreach ( $rss_items as $item ){
$site_name_org = $item->get_feed()->get_title();
$site_name = preg_replace('/( | )/', '', $site_name_org );
$link = esc_url( $item->get_permalink() );
$title = esc_html( $item->get_title() );
$date = $item->get_date( 'Y年m月d日' );
$content = $item->get_content();
?>
				<article class="article flex-child flex-dir-row">
<?php
$first_img = '';
$preg_string = '/<img.+?src=[\'"]([^\'"]+?)[\'"].*?>/msi';
if( preg_match_all( $preg_string, $content, $match, PREG_PATTERN_ORDER) > 0 ){
	//jpg,jpegのみを抽出
	foreach( $match[1] as $image ){
		if( preg_match('/.*?(jpg|jpeg)/i', $image, $out ) ){
			$first_img = $image;
		break;
		}
	}
}
?>
<?php if( !empty( $first_img ) ){
	$bg_image = ' style="background-image: url( ' . $first_img . ' );"';
}else{
	$bg_image = ' style="background-image: url( ' . get_stylesheet_directory_uri() . '/images/thumbnail-default-medium.png );"';
} ?>
<a class="article-image" href="<?php echo $link; ?>"<?php echo $bg_image; ?> title="記事へリンク" target="_blank" rel="noreferrer noopener"></a>

					<div class="loop-content">
						<header class="entry-header">
							<p class="facility-name<?php echo ' ' . $site_name; ?>"><?php echo $site_name; ?></p>
							<div class="entry-meta entry-data date-display-true">
								<p class="date date-published"><?php echo $date; ?></p>
							</div>
							<h2 class="entry-title post-title"><a href="<?php echo $link; ?>" title="記事へリンク" target="_blank" rel="noreferrer noopener"><?php echo $title; ?></a></h2>
						</header>
					</div>
				</article>
		<?php 
	}
} ?>
			</div>
		</div>
	</div>
</div>

カルーセル処理にしたので「Slick」用のスクリプトが書いてあります。
Slickが有効になっていればクルクルするはず。
要らなければ<script>~</script>は削除して問題無し。

他にもいろいろHTMLタグが書いてありますが、これらは無視してください。

カルーセルさせる場合だけ、「rss-crousel」は必須

ポイント

4行目:複数フィードの取得

各支店のブログを表示する体だったので、

fetch_feed( array( “支店1” , “支店2” ) );

のように配列になっています。

実装の際には、カスタムフィールド(ACFの繰り返しフィールド)にフィードURLを入れると配列に格納される、とう風にしました。

ブログの追加、削除の際にいちいちメンテしなくていいように。

 

各支店の最大表示数を指定するリクエストもありましたが、これはムリでした。

foreachにcontinue処理を入れても、連続していないと意味ないし。

この辺は実際いじらないと意味が??ですね。
やろうとすると、一度データベースに取り込んで処理するような感じになるんだと思います。

62行目~:サムネールの取得

サムネールが設定されていることはマレなので、よくある「本文中の最初の画像を引っ張ってくる」を採用。

最初、絵文字の確率が高い*.gifだけ除外しましたが、*.pngも絵文字になってる場合があり、結局両方除外しました。

正規表現、、、大昔少し勉強しましたがほとんど忘却。
alt=”〇〇”など、余計な装飾を削るのにさんざん苦労。

結局、参考にした幾つかの記事のハイブリッドで成功。

「サイズで判定」という手もあるんだろうけれど、今回は調査も含めパス。

 

こういう取得方法なので、画像のサイズがバラバラです。

グリッド表示にするとガタガタして大変みっともない。ので背景として処理しています。

 

そして、大きい画像が貼ってあると当然表示も重くなります、、、

53、54行目:サイト名

サイト名の取得自体は「$item->get_feed()->get_title()」でいけるのですが、

これを記事のCSSクラス名に使用する、という暴挙にでています。

支店ごとにCSSを変えてチョ、ということなのですが、他にクラス名に使えそうな変数が無いので。

パーマリンクの文字列加工は、、、無理でしょう…

 

CSSは日本語も通るので、みっともないけどまぁいいか。

ただし、全角でも半角でもスペースが入っているとNGなので、どちらも文字列操作で削除しています。

 

お世話になった記事。感謝。

WordPressで複数ブログのRSSを取得して、日付・画像・サイト名・投稿名を表示させる方法


https://teratail.com/questions/86067