WordPressのパスワード保護している記事のtitleも変更する

今現在、WordPressでパスワード保護された記事の本文やコメントは非表示になりますが、titleエレメントやRSSなんかは非表示になりません。
今回は非推奨になったwp_titleとWordPress 4.4から登場したadd_theme_support('title-tag')を有効化したテーマ等で使うwp_get_document_title()でも使える方法でいきます。

序でに「非公開:」や「保護中:」って文字も削除・変更しちゃいますー。

まずは完成したWordPressのプラグインコード。

<?php
/*
Plugin Name: Change Password POST Title
Plugin URI: http://blog.wolfs.jp/20160513-3616/
Description: パスワードで保護された記事のタイトルを変更します。
Version: 1.0.0
Author: Kerberos
Author URI: http://blog.wolfs.jp/
*/
 
class changePasswordPostTitle {
    private $plugin_dir = ABSPATH.'/wp-content/plugins/change_password_post_title/feed/';
    private $post_password_title = '[パスワードで保護された記事]';
 
    public function __construct() {
        add_filter('the_title', array($this, 'the_title'), 10, 2);
        add_filter('pre_get_document_title', array($this, 'pre_get_document_title'));
        add_filter('protected_title_format', array($this, 'protected_title_format'));
 
        add_filter('aioseop_title_single', array($this, 'aioseop_title'));
        add_filter('aioseop_title_page', array($this, 'aioseop_title'));
 
        remove_action('do_feed_rss2', 'do_feed_rss2');
        remove_action('do_feed_atom', 'do_feed_atom');
        add_action('do_feed_rss2', array($this, 'do_feed_rss2'), 10, 1);
        add_action('do_feed_atom', array($this, 'do_feed_atom'), 10, 1);
    }
 
 
    public function the_title($title = '', $currentID = 0) {
        global $post;
 
        if ($currentID !== 0) {
            if (post_password_required($currentID) === true) {
                if ($post->ID == $currentID && is_admin() === false) {
                    return $this->post_password_title;
                }
            }
 
            return $this->remove_title_prefix($title);
        }
 
        return $title;
    }
 
    public function pre_get_document_title($title) {
        if (is_single() === true || is_page() === true) {
            if (post_password_required($post->ID) === true) {
                return $this->post_password_title;
            }
 
            return $this->remove_title_prefix($title);
        }
 
        return $title;
    }
 
    public function protected_title_format($title) {
        global $post;
 
        if (post_password_required($post->ID) === false) {
            return '&#x1F512; %s';
        }
 
        return $this->post_password_title;
    }
 
    public function aioseop_title($title) {
        global $post;
 
        if (post_password_required($post->ID) === true) {
            return $this->post_password_title;
        }
 
        return $title;
    }
 
    private function remove_title_prefix($title) {
        $search[0] = '/^' . str_replace('%s', '(.*)', preg_quote(__('Protected: %s'), '/' )) . '$/';
        $search[1] = '/^' . str_replace('%s', '(.*)', preg_quote(__('Private: %s'), '/' )) . '$/';
 
        return preg_replace($search, '$1', $title);
    }
 
 
    public function do_feed_rss2($for_comments) {
        if ($for_comments) {
            load_template($this->plugin_dir.'feed-rss2-comments.php');
        }
    }
 
    public function do_feed_atom($for_comments) {
        if ($for_comments) {
            load_template($this->plugin_dir.'feed-atom-comments.php');
        }
    }
}
 
new changePasswordPostTitle();
?>

フィルターのフック名と関数は同じ名前にしてあるのでわかると思うので、その辺は略しますw
このプラグインでパスワード保護ページはこうなります:サンプルページ

the_title

これが一番メンドウなやつ。

<?php
if (post_password_required($postID) === true) {
    if ($post->ID == $currentID && is_admin() === false) {
        return $this->post_password_title;
    }
}
?>

なんでこんなちょっとメンドウな事になっているかと言うと、このthe_titleはいろんな所に使われているので$post->IDから獲得したIDのみを使っているとthe_titleを使っている他の所(アーカイブや検索結果、最近の記事など)にも影響がでちゃうんです。
なので、引数で渡されたPostIDと比較して同じなら実行するようにします。

is_admin()を指定しているのは、上でも書いたようにthe_titleは管理画面の記事一覧にも適用されてしまうので管理画面では適用しないようにしました。
最後に$this->remove_title_prefixで「非公開:」と「保護中:」の文字を削除して処理完了。
 

pre_get_document_title

これはWordPress 4.4から実装された関数でadd_theme_support('title-tag')を有効化したテーマ等用でtitleエレメント作成用の物。

<?php
if (is_single() === true || is_page() === true) {
    if (post_password_required($post->ID) === true) {
        return $this->post_password_title;
    }
 
    return $this->remove_title_prefix($title);
}
?>

is_single()とis_page()でページを指定しているのは、それ以外のページでは記事のタイトルがtitleエレメントで出ないから。
後はpost_password_requiredで記事にパスワードが設定されているかを判定して、最後に$this->remove_title_prefixで不要文字の削除。
 

protected_title_format

これはパスワードで保護された記事のタイトル、テーマ内のthe_titleのみに適用されるフィルター。

<?php
if (post_password_required($post->ID) === false) {
    return '&#x1F512; %s';
}
 
return $this->post_password_title;
?>

post_password_requiredでパスワード保護か判定して、認証済みの場合はタイトルに鍵マークを追加して、元のタイトルを表示しています。
例:「🔒 記事タイトル」

これは$this->remove_title_prefixで「保護中:」の文字を消したので「これは保護されている記事ですよ」みたいな物が欲しかった為ですw
必要ないならadd_filter部分でコメントアウトしちゃってください。
 

aioseop_title_

これはプラグイン「All In One SEO Pack」を導入している方向け。
All In One SEO Packを導入しているとWordPressのフィルターでは対応できないので、専用に用意されたフィルターでフィルタリングします。

他の所もフィルタリングする場合はadd_filterでaioseop_title_?をフィルターすれば問題ないと思います。
 

RSS

rssはテーマとほぼ同じ構造だけれどフックが全くないのでrssのテンプレートをごっそり変更するしかありません。
なのでremove_actionでWordPressのrssをごっそり削ってadd_actionで自前のrssテンプレートへ変更します。

テンプレート丸ごとは長いので、変更箇所のみ記載していきます。
wp-includesディレクトリ内にあるfeed-atom-comments.php、feed-rss2-comments.phpをプラグインフォルダへコピー。
各ファイルを開くと
 $comment_post = $GLOBALS['post'] = get_post( $comment->comment_post_ID );
って部分があるのでその下に下記コードを追加。
 if (post_password_required($comment->comment_post_ID) === true) continue;

繋げてみると・・・

<?
if ( have_comments() ) : while ( have_comments() ) : the_comment();
    $comment_post = $GLOBALS['post'] = get_post( $comment->comment_post_ID );
    if (post_password_required($comment->comment_post_ID) === true) continue;
......
?>

こんな感じ。

ようやく一通りのタイトルを変更する事ができましたー!
実際弄ってみて、タイトルを扱う関数って結構多くてビックリしましたw

関連するかもしれない記事



トラックバックURL


スパム対策のためトラックバックURLを動的に生成しています。
生成されるトラックバックURLはコンテンツURLと紐付けされますので、コンテンツURLで指定したサイト以外では使用できませんのでご注意ください。
トラックバックの注意事項などの詳しい説明は About ページを閲覧してください。
「コンテンツURL」を入力し「URL生成」ボタンを押してください。
トラックバックを送る際はあなたの記事やコンテンツにこの記事のURLを書くかリンクしておいてください。
URLがない場合はスパムとして削除され以降の全トラックバックは拒否されます。

コメントを残す

メールアドレスは公開されません、また は必須項目です。
このブログに初めてコメントする方は こちら をご覧ください。


画像認証は待機中です、先にコメント本文を入力して下さい。

コメントを送信しています、しばらくお待ち下さい...
(Akismetスパムデータベース及びブラックリストへの照会を行っています)


キャンセルをした場合でもコメント投稿が完了している場合があります