投稿日:2023年5月13日
プラグイン Twenty20 Image Before-After をアイキャッチに設定する方法を開発(プラグイン化)したので紹介したいと思います。
▲このように表示されます。テーマはLightningを使っています。
実際に動作するサイトはこちら です。
▼このように表示されます。
実際に動きます。中心のスライダーを左右に動かしてみてください。
仕様
▲投稿画面に「Twenty20アイキャッチ」というボタンを出力します。
ボタンをクリックすると投稿IDと、記事中のTwenty20のショートコードを取得し、データベースに保存します。
▲保存された内容。ボタンクリックと同時にtwenty20_shotcodeという名前でテーブルを作り、idとショートコードを挿入します。
▲アイキャッチ画像を設定すると、▼アイキャッチ画像が優先されます。
ページ表示(リロード)と共にデータベースからは削除されます。
▲記事ページです。
「最近の投稿」のアイキャッチも動かすことができます。
「次の記事」と「前の記事」はマウスホバーで情報がプルアップするので触れません。
こちらが実際に動く記事ページ になります。
ソースコード
▲必要なファイルです。
それぞれ下表のような役割になっています。
twenty20Top.css | トップページに適用するCSS。 |
output_twenty20.css | 投稿ページの「Twenty20アイキャッチ」ボタンのCSS。 |
output_twenty20.js | ajaxでidとショートコードをput_twenty_val.phpに渡します。 |
mydb.php | データベース接続を行っています。今回ソースの説明は省略。 |
put_twenty_val.php | データベースを作成すると共に、output_twenty20.jsのajaxから受け取ったidとショートコードをデータベースに挿入します。 |
twenty20_eyecatch.php | 今回の要のphp。トップページ、投稿ページの条件分岐によりTwenty20をアイキャッチの出し分けを行います。 |
.twentytwenty-container {
position: initial !important;
height: initial !important;
}
▲positionはJavaScriptで上書きできましたが、heightがTwenty20のCSSの方が優先されるらしく、このような書き方でないと適用できませんでした。
#inputBtn {
float: right;
margin-top: 1em;
border: 1px solid #2271b1;
color: #2271b1;
border-radius: 3px;
font-size: 1em;
padding: .25em .75em;
transition: .3s;
}
#inputBtn:hover {
cursor: pointer;
background-color: #dbdfdf;
}
▲投稿ページ「Twenty20アイキャッチ」ボタンのCSS。
jQuery(function ($) {
if (!($('#post').length)) {
return;
}
var inputBtn = '<input type="button" id="inputBtn" class="inputBtn" name="inputBtn" value="Twenty20アイキャッチ">'; // タグ設定
$('#postdivrich').after(inputBtn); //タグ出力
$('#inputBtn').on('click', function () {
let postParameter = $(location).attr('search'),// urlからパラメータを取得
postId=postParameter.match(/\?post=(.+?)\&/);// urlパラメータからpost IDを取得
let articleContents = ($('.wp-editor-area').text()), //記事内の文字を取得
twenty20ShortCode = articleContents.match(/\Twenty20 need two images./); //twenty20のショートコードを取得
if (!twenty20ShortCode) {
alert('Twenty20を設定し更新してください。')
}
let eyecatchImg = $('#postimagediv img'); // アイキャッチが設定されている場合
if (eyecatchImg.length > 0) {
alert('アイキャッチ画像が設定されている場合、\nアイキャッチにTwenty20は適用されません。\nアイキャッチ画像が優先されます。');
} else { // アイキャッチが設定されていない場合、データベースへ追加
$.ajax({
type: 'POST',
url: "../wp-content/plugins/twenty20_eyecatch/put_twenty_val.php",// ディレクトリwp-adminから見ているので、←こう書かないとディレクトリが取得できない。
data: {
'id': postId[1], //post ID
'shortCode': twenty20ShortCode[0], //twenty20ショートコード
},
success: function () {
}
});
alert('データベースへ登録しました。');
}
});
});
▲投稿ページに「Twenty20アイキャッチ」ボタンを出力し、クリックすると記事中のTwenty20のショートコードを取得、post idと共にajaxでput_twenty_val.phpへ値を渡します。
<?php
require_once("mydb.php"); //データベース接続関数を読み込み
$pdo = db_connect(); //データベースへ接続
$id = $_POST['id']; // JavaScrioptからpost IDを取得
$shortcode = $_POST['shortCode']; // JavaScrioptからTwenty20ショートコードを取得
// ▼▼▼ テーブル作成
$sql = 'CREATE TABLE IF NOT EXISTS twenty20_shortcode (
id int(11), -- id
shortcode_val varchar(100), -- ショートコード値
PRIMARY KEY(id)-- idを主キーに
) engine=innodb default charset=utf8';
$pdo->query($sql); //sql実行
// ▼▼▼ データ登録
$stmt = $pdo->prepare('REPLACE INTO twenty20_shortcode (id, shortcode_val) VALUES (:id, :shortcode)'); // データベースに追加
$stmt->bindValue(':id', $id); //post ID登録
$stmt->bindValue(':shortcode', $shortcode); //twenty20ショートコードを登録
$stmt->execute(); //実行
$pdo = null; //データベースを閉じる
▲output_twenty20.jsから受け取ったid、ショートコードの値をデータベースへ挿入します。
17行目の REPLACE INTO は、データベースにあれば無視し、なければ追加する書き方になります。idを基準にしたいので、12行目でidを PRIMARY KEY に設定しておく必要があります。
<?php
/*
Plugin Name: Twenty20 Eyecatch
Description: Twenty20の画像比較表示をアイキャッチに設定するプラグイン
Version: 1.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; //直接アクセス回避
// ▼▼▼ Twenty20 Eyecatch
// アイキャッチ画像が設定されていたら、そちらを優先。されてなかったらTwenty20を表示させる
// アイキャッチを設定すると、すでにデータベースに登録していた場合、削除する
///////////////////////////////////////////////////////////////////////////
// ▼▼▼ トップページ
function add_tt()
{
$n=0; // アイキャッチがない場合のカウント初期化
if (is_home() || is_front_page()) { //トップページだったら
if(have_posts()){ //投稿ページがあったら
while(have_posts()){ // ループ
the_post();
switch (has_post_thumbnail()){ // アイキャッチの有無確認
case true: // アイキャッチが設定されていたら
$no_eyecacth_post_id=get_the_ID();
global $wpdb; // グローバル変数
$wpdb->get_results("DELETE FROM twenty20_shortcode WHERE id=$no_eyecacth_post_id"); // 設定されていたフィールドを削除
break;
case false: // アイキャッチが設定されてなかったら
$n=$n+1; // カウント
$no_eyecacth_post_id=get_the_ID(); // 投稿IDを取得
wp_enqueue_style('twenty20_top', plugins_url().'/twenty20_eyecatch/css/twenty20Top.css'); // twenty20Top.cssを読み込む
global $wpdb; // グローバル変数
$twenty20_sc = $wpdb->get_results("SELECT * FROM twenty20_shortcode"); // データベースからショートコードを取得
$no_eyecacth_id = $wpdb->get_results("SELECT * FROM twenty20_shortcode WHERE id = $no_eyecacth_post_id"); // データベースから投稿IDを取得
if ($no_eyecacth_id) {
foreach ($no_eyecacth_id as $twenty20Sc) {
echo do_shortcode($twenty20Sc->shortcode_val); // ショートコードを設定
?>
<script>
jQuery(function($) {
$('#post-<?php echo $no_eyecacth_post_id; ?> .vk_post_imgOuter').removeAttr('style'); // スタイルを空に
$('#post-<?php echo $no_eyecacth_post_id; ?> .vk_post_imgOuter').empty(); // 投稿のアイキャッチを空に
let twenty20Thumbnail = $('#twenty20-<?php echo $n; ?>.twenty20').prop('outerHTML'); // ラッパーを取得
$('#twenty20-<?php echo $n; ?>.twenty20').remove(); // 仮表示したTwenty20を削除
$('#post-<?php echo $no_eyecacth_post_id; ?> .vk_post_imgOuter').prepend(twenty20Thumbnail); //Twenty20をアイキャッチに格納
$('#twenty20-<?php echo $n; ?>.twenty20').dblclick(function() { // アイキャッチをダブルクリックでパーマリンクに遷移
window.location.href = "<?php the_permalink($no_eyecacth_post_id); ?>"
});
$('#twenty20-<?php echo $n; ?>.twenty20').css('margin-bottom', 0); // スタイル設定
});
</script>
<?php
}
}
}
}
}
}
}
add_action('lightning_site_body_prepend', 'add_tt');
///////////////////////////////////////////////////////////////////////////
// ▼▼▼ 投稿ページ
function add_tt_page()
{
$n=0; // アイキャッチがない場合のカウント初期化
if (is_single()) { //投稿ページだったら
switch (has_post_thumbnail()){ // アイキャッチの有無確認
case true: // アイキャッチが設定されていたら
$no_eyecacth_post_id=get_the_ID();
global $wpdb; // グローバル変数
$wpdb->get_results("DELETE FROM twenty20_shortcode WHERE id=$no_eyecacth_post_id");
case false: // アイキャッチが設定されてなかったら
global $wpdb; // グローバル変数
$twenty20_sc = $wpdb->get_results("SELECT * FROM twenty20_shortcode"); // データベースからショートコードを取得
if ($twenty20_sc) {
foreach ($twenty20_sc as $twenty20Sc) {
$n=$n+1; // カウント
echo do_shortcode($twenty20Sc->shortcode_val); // ショートコードを設定
?>
<script>
jQuery(function($) {
$('#post-<?php echo $twenty20Sc->id; ?> .vk_post_imgOuter').removeAttr('style'); // スタイルを空に
$('#post-<?php echo $twenty20Sc->id; ?> .vk_post_imgOuter').empty(); // 投稿のアイキャッチを空に
let twenty20Thumbnail = $('#twenty20-<?php echo $n; ?>').prop('outerHTML'); // ラッパーを取得
$('#post-<?php echo $twenty20Sc->id ; ?> .vk_post_imgOuter').prepend(twenty20Thumbnail); //Twenty20をアイキャッチに格納
$('#twenty20-<?php echo $n; ?>').remove(); // 仮表示したTwenty20を削除
$('#twenty20-<?php echo $n; ?>.twenty20').dblclick(function() { // アイキャッチをダブルクリックでパーマリンクに遷移
window.location.href = "<?php the_permalink($twenty20Sc->id); ?>"
});
$('#twenty20-<?php echo $n; ?>.twenty20').css({ // スタイル設定
marginBottom : 0,
marginTop :'-62%'
});
});
</script>
<?php
}
}
}
}
}
add_action('lightning_site_body_prepend', 'add_tt_page');
// ▼ 投稿編集ページ、固定編集ページだったらoutput_twenty20.jsとoutput_twenty20.cssを出力
function admin_func()
{
echo '<script type="text/javascript" src="'.plugins_url().'/twenty20_eyecatch/js/output_twenty20.js"></script>';
echo '<link rel="stylesheet" href="'.plugins_url().'/twenty20_eyecatch/css/output_twenty20.css" />';
}
add_action('admin_head', 'admin_func');
▲2〜3行目はプラグインに必要な記述です。
トップページ(14〜60行目)と投稿ページ(64〜104行目)で処理を分けました。
それぞれPHP中でJavaScriptの処理を入れてます。
JavaScriptの内容は、一度Twenty20を任意の場所に表示させ、その要素を取得した後に削除。アイキャッチ画像が配置されるタグに出力させるという仕様です。
投稿ページ内のアイキャッチ画像の有無の条件分岐 switch には break; を入れてません。
これは「最近の投稿」でアイキャッチ画像の有無に関わらず、投稿の数だけ出力をしないといけないからです。
break; を入れてしまうと、アイキャッチ画像が設定されているものを出力後、Twenty20ショートコードが出力されなくなってしまいます。
再度、記載しておきます。
実際に動作するサイトはこちら です。
以前に似たようなプラグイン TwentyTwenty でトップページのアイキャッチ画像に適用したことがあります。
TwentyTwentyはjQueryライブラリ も公開されておりWordPressでなくても手軽に実装することができます。
ただプラグインの最終更新日が9年前になっているので使用するのを躊躇しました。
上記の理由でTwenty20 Image Before-After を検証してみました。
せっかくなのでアクションフックや子テーマでのカスタマイズではなく、プラグイン化してみました。
ただテーマ Lightningでの検証だったのでLightningでないと動作しないのが否めません。
さらに検証し汎用性を持たせ、配布できるくらいまで作り込もうと思います。
最後まで読んでくださりありがとうございました。