WordPress 指定のキーワードの自動リンク

WordPress フォーラムに「指定のキーワードに自動的にリンクを貼るプラグインで日本語に対応したもを探しています」というような内容のトピックが起ったので調べてみました。

指定のキーワードに自動的にリンクを貼るプラグインを、いくつか見つけることができましたが、日本語 (分かち書なし) に対応しているものはありませんでした。(ご存知の方はコメントお願いします)

単語を正しく抽出(形態素解析)するのはパフォーマンスなど実装が難しいですが、単純文字列でもいいというケースは多いと思います。また、キーワードとリンクの設定も WordPress の標準機能であるリンクマネージャーを使用することで僅かなコードで実装することができそうだったので作ってみました。

functions.php

下記のコードをテーマの functions.php に追記するだけで完了です。これで WordPress のリンクマネージャーが使える (管理画面のメニューに「リンク」が追加される) ようになります。このリンクマネージャーに登録したリンクのタイトルをキーワードとして、投稿や固定ページの本文(コンテンツ)のキーワード(単語ではなく単純文字列)に自動的にリンクが貼られるようになります。

// Enable Link Manager. 
add_filter( 'pre_option_link_manager_enabled', '__return_true' );

/**
 * Filters the post content.
 *
 * @since 0.0.1
 * @since 0.0.2 Changed the keyword to be set after sorting in descending order.
 * 
 * @param string $content Content.
 * @return string Content.
 */
function auto_linker_the_content( $content ) {
	$links = array();

	$bookmarks = get_bookmarks( array ( 'orderby' => 'name', 'order' => 'DESC' ) );
	foreach ( (array) $bookmarks as $bookmark ) {
		$links[ $bookmark->link_name ] = array( 'url' => $bookmark->link_url, 'blank' => '_blank' === $bookmark->link_target );
	}

	if ( 0 === count( $links ) ) {
		return $content;
	}

	$regex = implode( '|', array_map( function( $key ) { return preg_quote( $key, '/' ); }, array_keys( $links ) ) );
	$regex = "/($regex)/i";

	$textarr = wp_html_split( $content );
	$ignore_elements = array( 'a', '/a', 'code', '/code', 'pre', '/pre', 'option', '/option' );
	$inside_block = array();
	foreach ( $textarr as &$element ) {
		if ( 0 === strpos( $element, '<' ) ) {
			$offset = 1;
			$is_end_tag = false;

			if ( 1 === strpos( $element, '/' ) ) {
				$offset = 2;
				$is_end_tag = true;
			}

			preg_match( '/^.+(\b|\n|$)/U', substr( $element, $offset ), $matches );
			if ( $matches && in_array( $matches[0], $ignore_elements, true ) ) {
				if ( ! $is_end_tag ) {
					array_unshift( $inside_block, $matches[0] );
				} elseif ( $inside_block && $matches[0] === $inside_block[0] ) {
					array_shift( $inside_block );
				}
			}
		} else {
			if ( empty( $inside_block ) ) {
				if ( false === strpos( $element, 'http://' ) && false === strpos( $element, 'https://' ) ) {
					$element = preg_replace_callback( $regex, function( $matches ) use ( $links ) {
						$key = $matches[0];
						$target = $links[$key]['blank'] ? ' target="_blank" rel="noopener"' : '';
						return '<a href="' . esc_url( $links[$key]['url'] ) . '"' . $target . '>' . $key . '</a>';
					}, $element );
				}
			}
		}
	}

	return join( $textarr );
}

add_action( 'the_content', 'auto_linker_the_content', 12 );

プラグイン

同様の機能を持つプラグインも作成しました。プラグインで簡単に設定したいという方は、こちらをどうぞ。

auto-linker.0.0.2.zip

変更履歴

バージョン説明
0.0.1最初のリリース。
0.0.2キーワード (リンクのタイトル) を降順ソートしてから設定するようにしました。

コメントを残す

メールアドレスが公開されることはありません。

日本語でコメントを入力してください。(スパム対策)