投稿日:2023年5月13日

プラグイン Twenty20 Image Before-After アイキャッチに設定する方法を開発(プラグイン化)したので紹介したいと思います。

▲このように表示されます。テーマはLightningを使っています。
実際に動作するサイトはこちら です。

Twenty20 Image Before-After

▼このように表示されます。
実際に動きます。中心のスライダーを左右に動かしてみてください。

 仕様

▲投稿画面に「Twenty20アイキャッチ」というボタンを出力します。
ボタンをクリックすると投稿IDと、記事中のTwenty20のショートコードを取得しデータベースに保存します。

▲保存された内容。ボタンクリックと同時にtwenty20_shotcodeという名前でテーブルを作り、idとショートコードを挿入します。

▲アイキャッチ画像を設定すると、▼アイキャッチ画像が優先されます。
ページ表示(リロード)と共にデータベースからは削除されます。

▲記事ページです。
「最近の投稿」のアイキャッチも動かすことができます。
「次の記事」「前の記事」はマウスホバーで情報がプルアップするので触れません。
こちらが実際に動く記事ページ になります。

 ソースコード

▲必要なファイルです。
それぞれ下表のような役割になっています。

twenty20Top.cssトップページに適用するCSS。
output_twenty20.css投稿ページの「Twenty20アイキャッチ」ボタンのCSS。
output_twenty20.jsajaxで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 でトップページのアイキャッチ画像に適用したことがあります。
TwentyTwentyjQueryライブラリ も公開されておりWordPressでなくても手軽に実装することができます。
ただプラグインの最終更新日が9年前になっているので使用するのを躊躇しました。

上記の理由でTwenty20 Image Before-After を検証してみました。

せっかくなのでアクションフックや子テーマでのカスタマイズではなく、プラグイン化してみました。
ただテーマ Lightningでの検証だったのでLightningでないと動作しないのが否めません。
さらに検証し汎用性を持たせ、配布できるくらいまで作り込もうと思います。

最後まで読んでくださりありがとうございました。

関連サイト
Pocket