サポート » テーマ » フィルターフックでrel=”noopener noreferrer”を追記する方法

  • 解決済 echizenya

    (@echizenya)


    いつもお世話になっています。
    下記の質問についてご存知の方がいらっしゃいましたらご教示を願います。

    【質問の主旨】

    投稿した記事内のaタグにおいて、rel=”noopener noreferrer”がついていないリンクが多数あります。
    フィルターフックを使うことで、rel=”noopener noreferrer”の属性をつけるためには、
    functions.phpにおいてどのような記述をすれば良いでしょうか

    【質問の補足】

    1.
    記事内のすべてのaタグに対して、rel=”noopener noreferrer”の属性をつけようと考えた理由は、
    target=”_blank”の属性を使っているaタグのセキュリティとパフォーマンスの向上を図るためです。
    より詳細な理由はこちらの記事を参考にしています。

    2.
    日本語版WordPress Condexでリンク関連のフィルターフックを確認しましたが、今回の質問に関連するフィルターを見つけることはできませんでした。

    3.
    ヘルプのページは2014年1月29日に投稿した記事で、本文中にaタグを使っていてrel=”noopener noreferrer”がありません。一方、最近投稿したような記事にはrel=”noopener noreferrer”をつけています。
    例)
    https://e-yota.com/idle_talk/hanekonma_watanabe_ken/

    以上、ご確認よろしくお願い申し上げます。

    ヘルプの必要なページ: [リンクを見るにはログイン]

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • モデレーター Takayuki Miyoshi

    (@takayukister)

    フィルターフックは the_content を、フィルター関数には wp_targeted_link_rel() を使えば実現可能と思います。

    ブロックエディターのインラインリンクで 新しいタブで開く を選択した場合は rel="noreferrer noopener" が自動的にセットされるようなので、ブロックエディターでの編集もひとつの手かもしれません。

    なお、参照された記事に示されているセキュリティとパフォーマンス上の問題のほかに、ユーザーの意図しない挙動により混乱を生じさせるアクセシビリティ上の問題もあるので注意が必要です。

    H83: 利用者の要求に応じて新しいウィンドウを開くために target 属性を使用して、そのことをリンクテキストで明示する

    target="_blank" の使用は必要最小限にとどめ、使用する場合はスクリーンリーダーを使用するユーザーにむけた案内テキストを添えるのが適切です。

    参考までに、WordPress 本体の管理画面で target="_blank" が使われる場合は次のようなマークアップになります:

    <a href="https://example.com/" target="_blank" rel="noopener noreferrer">
      リンクテキスト
      <span class="screen-reader-text">(新しいタブで開く)</span>
      <span aria-hidden="true" class="dashicons dashicons-external"></span>
    </a>
    トピック投稿者 echizenya

    (@echizenya)

    @takayukister さん。
    コメントありがとうございます!ここ1、2日の間、他の用事をこなしていたため、内容を精査することができませんでした。とり急ぎお礼を申し上げます。いただいたアドバイスでどのような結果が出たか改めてお知らせ申し上げます。

    トピック投稿者 echizenya

    (@echizenya)

    @takayukister さん。
    コメントありがとうございます。改めてお礼を申し上げます。
    いただいたコメントについて、4点ご回答いたします。各回答はクラシックエディタを使っているという前提です。もし1の回答について何か気が付いた点があり、その点についてお知らせくだされば大変助かります。

    1. wp_targeted_link_rel_noopener_noreferrer関数の追加

    フィルターフックは the_content を、フィルター関数には wp_targeted_link_rel() を使えば実現可能と思います。

    いただいたアドバイスにもとづいてfunction.phpに以下のコードを追記しました。

    // noopener noreferrer属性を付加する関数
    function wp_targeted_link_rel_noopener_noreferrer( $text ) {
      if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) {
          if ( ! is_serialized( $text ) ) {
              return str_replace('target=\"_blank\"','target=\"_blank\" rel=\"noopener noreferrer\"', $text );
          }
      }
      return $text;
    }
    
    // 投稿した記事が読み込まれた時点でwp_targeted_link_rel_noopener_noreferrer関数を実行する
    if ( !is_admin() ) {
      add_filter( 'the_content', 'wp_targeted_link_rel_noopener_noreferrer', 10, 2 );
    }

    ですがこのコードを追記しても、target="_blank"属性があって、かつrel="noopener noreferrer"が必要なリンク(aタグ)にrel="noopener noreferrer"が追加されることはありませんでした。

    2. ヘルプが必要なページの差し替え

    恐れ入ります。質問文で「ヘルプを必要とするページ」の提示が間違っていました。下記のURLに差し替えて確認していただければ助かります。

    https://e-yota.com/weblearning/post-688/

    差し替えた理由は「ヘルプを必要とするページ」の記事で使っているaタグは、そもそもtarget="_blank"を使っていなかったことに気が付いたからです。上記の記事のリンクではtarget="_blank"を使っていますが、rel="noopener noreferrer"が使用されていません。

    3. アクセシビリティの課題について

    参照された記事に示されているセキュリティとパフォーマンス上の問題のほかに、ユーザーの意図しない挙動により混乱を生じさせるアクセシビリティ上の問題もあるので注意が必要です。

    アクセシビリティについてもご指摘いただきありがとうございます。spanタグを使ってアクセシビリティの向上を図ることについては、この質問が解決済みになったあとに別の質問として投稿いたします。

    4. 現在使用しているコード

    1.で示したコメントは一旦削除した上で、各ブログ記事を公開している一般公開している状況です。

    以上、ご確認よろしくお願い申し上げます。

    • この返信は4年、 1ヶ月前にechizenyaが編集しました。理由: 必要なタグをつけることを忘れていたため編集
    モデレーター Takayuki Miyoshi

    (@takayukister)

    1. wp_targeted_link_rel_noopener_noreferrer関数の追加

    WordPress が標準で用意している wp_targeted_link_rel() を使えば要望されている処理が可能なので独自に関数を定義する必要はありません。

    add_filter( 'the_content', 'wp_targeted_link_rel' );

    必要なコードはこれだけです。

    トピック投稿者 echizenya

    (@echizenya)

    @takayukister さん。
    お忙しいところたびたびのアドバイスありがとうございます。いただいたアドバイスについて以下4点をご回答申し上げます。

    1. “Fatal error: Cannot redeclare”について

    WordPress が標準で用意している wp_targeted_link_rel() を使えば要望されている処理が可能なので独自に関数を定義する必要はありません。

    fuctions.phpの最下部に下記のコードを追記しました。

    function wp_targeted_link_rel( $text ) {
      // Don't run (more expensive) regex if no links with targets.
      if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) {
          if ( ! is_serialized( $text ) ) {
              $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text );
          }
      }
    
      return $text;
    }
    
    add_filter( 'the_content', 'wp_targeted_link_rel' );

    この状態でfuctions.phpを保存してリロードをすると、ブログサイトに下記の文言でエラーが表示され、サイト全体が閲覧できない状態になります。

    Fatal error: Cannot redeclare wp_targeted_link_rel() (previously declared in /var/www/html/wp-includes/formatting.php:3147) in /var/www/html/wp-content/themes/mytheme/functions.php on line 277
    サイトに重大なエラーがありました。

    エラーの文言を読むと「同じ関数が二重に宣言されている」と指摘されているように解釈ができます。

    2. PHP関数で二重定義を回避する方法

    “php 関数 二重 回避”というキーワードを使って、Google検索をしました。すると以下のQ&Aページを見つけることができました。

    function2重定義回避について
    https://teratail.com/questions/51695

    このページによると、PHP関数で二重定義を回避するためには元々の関数を定義しているファイルを書き換えることがベストアンサーとされています。ただ、WordPressにおいてwp-includes/formatting.phpはテーマファイルのように、WordPress開発者ではない方が任意で書き換えられるファイルではないと思います。

    3. 現在の状況

    1. で示したコードを使うとサイトが表示されないため、上記のコードを削除してる状態でブログサイトを運営している状態です

    4. 今後の質問について

    私が @takayukister さんの意図を汲むことができなくて、なかなか解決にいたらずまことに恐縮です。もしお手数がかかるようようでしたら、別途質問を投稿するつもりです。(「wp_targeted_link_rel関数を使ったときに関数の二重定義を回避する方法」などと言うタイトルで)

    いかがでしょうか?ご意見をお聞かせいただければ幸いです。以上、よろしくお願い申し上げます。

    • この返信は4年、 1ヶ月前にechizenyaが編集しました。理由: 引用タグをつけ忘れたたため
    • この返信は4年、 1ヶ月前にechizenyaが編集しました。理由: 誤字を修正
    Honda

    (@rocketmartue)

    function wp_targeted_link_rel( $text ) {
        // Don't run (more expensive) regex if no links with targets.
        if ( stripos( $text, 'target' ) !== false && stripos( $text, '<a ' ) !== false ) {
            if ( ! is_serialized( $text ) ) {
                $text = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', 'wp_targeted_link_rel_callback', $text );
            }
        }
     
        return $text;
    }

    は、コアで定義されていますのでfuctions.phpに追加すると二重定義になります。
    fuctions.phpに追加する必要はありません。
    三好さんが書かれている通り

    add_filter( 'the_content', 'wp_targeted_link_rel' );
    必要なコードはこれだけです。

    トピック投稿者 echizenya

    (@echizenya)

    @rocketmartue さん。
    コメントありがとうございます。

    add_filter( 'the_content', 'wp_targeted_link_rel' );
    必要なコードはこれだけです。

    ご指摘ありがとうございます。functions.phpの最下行に

    add_filter( 'the_content', 'wp_targeted_link_rel' );

    のコードのみをつけました。
    そうすると、target="_blank"属性があって、かつrel="noopener noreferrer"が必要なリンク(aタグ)にrel="noopener noreferrer"を追加することができました。アドバイス大変助かります。問題を解決することができました。今後ともどうぞよろしくお願いします。

    トピック投稿者 echizenya

    (@echizenya)

    @takayukister さん。
    おかげさまで問題を解決することができました!改めてお礼を申し上げます。

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • トピック「フィルターフックでrel=”noopener noreferrer”を追記する方法」には新たに返信することはできません。