[WordPress]プラグインを使わずにブログカードを実装する(ブロックエディタ使用)
2021.05.04
ずっとどうやってやればいいのかわからずに実装できなかったんですが、ブロックエディタでURLを取得して、そこから処理を行うという方法を取りました。
*コピペで簡単!っていう内容ではないです。
実装したい内容
URLが内部リンクであれば、postidから情報を取得する。外部リンクであればOpenGraphを使用して情報を取得し、別タブ表示を行う。
**
本来であればURLをコピペしただけで反映したかったのだけど、どうしてもブロックエディタの魔の手から逃れられず(iframeになるやつ)、独自でブロック要素を追加して、そのURLを取得して処理するようにした。
**
ショートコードでやる方法はたくさんあったんだけど、ブロックエディタ時代にショートコード使いたくないし、ショートコードって記述結構めんどくさい気がするの。
実装内容
blockeditor.js
blocks.registerBlockType("hks-orgblock/txtlink-block", {
title: __("URLリンク", "txtlinkbox"),
icon: "carrot",
category: "hks_orgblock",
attributes: {
content: {
type: "string",
source: "text",
selector: "a",
},
},
edit: function (props) {
var content = props.attributes.content;
function onChangeContent(newContent) {
props.setAttributes({ content: newContent });
}
return el(RichText, {
tagName: "a",
className: props.className,
onChange: onChangeContent,
value: content,
});
},
save: function (props) {
return el(RichText.Content, {
tagName: "a",
className: "txtlink-block",
value: props.attributes.content,
});
},
});
まずはブロックエディタに追加する。テーマに埋め込む機能でなければ、プラグインを使ってURLを入力するものを作ればそもそもここは必要ないと思う。
functions.php
add_filter('the_content', 'hks_link_post');
filterを使用して本文を表示前に書き換えます。「本文内にclass名があれば」の判定かけているので、処理的にちょっと気になるところ。
function hks_link_post($contents){
// 追加したブロックのclass名取得
$pattern = "/<a class=\"wp-block-hks-orgblock-txtlink-block.*?\">(.*?)<\/a>/s";
return preg_replace_callback($pattern, function ($matches) {
$site_url = home_url(); // サイトのURL取得
$linkurl = $matches[1];
$str = '';
if (false !== strpos($linkurl, $site_url)) {
// 内部リンク
$postid = url_to_postid($linkurl); // URLから記事id取得
$title = esc_html(get_the_title($postid)); // idからタイトル取得
// サムネイル取得,なければOGPを吐く
if(has_post_thumbnail($id)) {
$thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'thumbnail');
if (!empty($thumbnail)) {
$thumbnail = $thumbnail[0];
}
}else{
$thumbnail = get_template_directory_uri().'/common/img/ogp.png';
}
$str = '<div class="entry-item linkcard"><a class="entry-item__link" href="'.$linkurl.'"><div class="entry-item__bg"><img src="'.$thumbnail.'" alt="" loading="lazy"></div><div class="entry-item-btm"><p class="entry-item__ttl">'.$title.'</p><p class="linkcard__st">あわせて読みたい</p></div></a></div>';
return $str;
}else{
// 外部リンク
$graph = '';
require_once(__DIR__."/../common/lib/OpenGraph.php");
$graph = OpenGraph::fetch($linkurl);
$title = $graph->title;
$thumbnail = '';
$thumbnail = $graph->image;
if ($thumbnail === '') {
$screenShot = 'https://s.wordpress.com/mshots/v1/'. urlencode(esc_url(rtrim( $linkurl, '/' ))) .'?w=200&h=200';
$thumbnail = '<img src="'. $screenShot .'" width="'. $img_width .'" />';
}
$str = '<div class="entry-item linkcard"><a class="entry-item__link" href="'.$linkurl.'" target="_blank"><div class="entry-item__bg"><img src="'.$thumbnail.'" alt="" loading="lazy"></div><div class="entry-item-btm"><p class="entry-item__ttl">'.$title.'</p><p class="linkcard__st">関連記事</p></div></a></div>';
return $str;
}
}, $contents);
}
add_filter('the_content', 'hks_link_post');
内部リンクはURLから情報を取得して、外部リンクはOpen Graph Protocol helper for PHPを使用しています。
$str = '<div class="entry-item linkcard"><a class="entry-item__link" href="'.$linkurl.'" target="_blank"><div class="entry-item__bg"><img src="'.$thumbnail.'" alt="" loading="lazy"></div><div class="entry-item-btm"><p class="entry-item__ttl">'.$title.'</p><p class="linkcard__st">関連記事</p></div></a></div>';
この部分で吐き出しHTMLを扱っています。構成やclass名は適宜。
まとめ
技術メモ的なもの。こうしたらいいよってあれば教えてほしいです。
書いてて思ったけど、ブロックエディタでやるならタイトルを自分でかけるようにしたり、「あわせて読みたい」「関連記事」とかの文字も変えれるようにとか…。でも編集部分増えると記事書くのめんどくさくなるんだよな〜。
Comment