ほぼ実用性はないと思うけれど、WordPressで入力した文章をブラウザに表示するときに、一部の単語を他の文字やリンクに置き換える方法をお伝えします。
やりたいこと
イメージをつかむために、実例でやりたいことをお伝えします。
次のような文章を、投稿画面で入力したとします。
僕はいつも Yahoo! で検索しています
それしか使ったことないです (涙)
この記事をブラウザに表示するときに、(笑)を🙂に、(涙)を😥に、そしてYahoo!をリンクに置き換えます。
さらに、けーちゃんの前に画像を挿入します。
次のような結果になります。
単語を他の文字に置き換えることはあまりないかもしれませんね。
一方リンク置き換えは、ニュース記事などを見ていると記事中の人物名や重要なキーワードなどがリンクになっていることがよくあるので、需要がありそうな気がします。
方法は3つ
記事中の文字置き換え方法には様々な手段がありますが、今回は次の3つを挙げます。
英語圏顔文字変換機能を利用
WordPressには :) などの英語圏で使用されている顔文字を 🙂 などの絵文字に変換する機能があります。
この機能を使用すると、任意の文字を絵文字や画像に変換することができます。
ただし、行の途中で任意の文字を使用する場合、前後にスペースを置く必要があります。
記事を入力するときに注意が必要なので、少し使いにくいかもしれません。
任意の文字を絵文字や画像に変換するには、smiliesフィルターで英語圏顔文字変換機能に変換したい文字を追加します。
smiliesフィルターで呼ばれる関数は、対象文字の連想配列を引数として受け取ります。
その配列を操作することで、対象文字を変更できます。
- function my_smile( $smiles ){
- $add_smiles = [
- '(笑)'=>'🙂',
- '(涙)'=>'😥',
- 'Yahoo!'=>'<a href="https://www.yahoo.co.jp/">Yahoo!</a>',
- 'けーちゃん'=>'<img src="https://xxxx.xxx/kchan.png" alt="けーちゃん">けーちゃん'
- ];
- return array_merge( $smiles , $add_smiles );
- }
- add_filter( 'smilies' , 'my_smile');
引数の$smilesには英語圏顔文字のデータが入っています。
このデータに追加してあげれば、後はWordPress側で処理してくれます。
データは置き換えたい文字をキーとして、置き換え後の文字を値とします。
置き換え後の文字にaタグやimgタグを入れておくと、そのまま使ってくれます。
英語圏顔文字の変換がいらないときは、array_merge()関数で配列を結合しないで$add_smilesをリターンすればOKです。
'けーちゃん'=>'kchan.png'
便利な気がしますが、おススメできません。
理由は画像のパス指定を他のフィルターでおこなう必要があることです。
ムダに処理を増やすのは避けた方がいいです。
それよりも問題なのが、次のようなタグが生成される点です。
<img src="" alt="" class="wp-smiley" style="height: 1em; max-height: 1em;" />
インラインのスタイル属性が付与されています。
これはAMP化したとき、問題になります。
AMPはインライン属性を許可していないのでエラーになってしまうのです。
変換機能を自作
前項のWordPressの英語圏顔文字変換機能を利用するケースは、記事入力時に対象文字の前後にスペースを挿入する必要があるため、とてもめんどうです。
そこで既存の機能に頼らずに、自分で置き換え機能を構築してみます。
今回は既存の英語圏顔文字変換機能のコードを参考にしました。
完成したのが次のコードです。
- // データの初期化
- function my_replace_data_init(){
- global $my_replace_data;
- $my_replace_data = [
- // 対象データ
- 'data' =>[
- '(笑)'=>'🙂',
- '(涙)'=>'😥',
- 'Yahoo!'=>'<a href="https://www.yahoo.co.jp/">Yahoo!</a>',
- 'けーちゃん'=>'<img src="https://xxxx.xxx/kchan.png" alt="けーちゃん">けーちゃん'
- ],
- // 除外タグ
- 'ignore_tag' => 'code|pre|style|script|textarea'
- ];
- $my_replace_data['search'] = (function($data) {
- $keys = array_map(function($n){return preg_quote($n,'/');},array_keys( $data ));
- rsort( $keys );
- return '/(' . implode( '|' , $keys ) . ')/';
- })($my_replace_data['data']);
- $my_replace_data['ignore_start'] = '/^<(' . $my_replace_data['ignore_tag'] . ')/';
- $my_replace_data['ignore_end'] = '/^<\/(' . $my_replace_data['ignore_tag'] . ')/';
- }
- // 文字の置き換え処理
- function my_string_replace( $content ){
- global $my_replace_data;
- if( !isset( $my_replace_data ) ){
- my_replace_data_init();
- }
- list('ignore_start' => $ignore_start, 'ignore_end' => $ignore_end , 'search' => $search , 'data' => $data) = $my_replace_data;
- $split = preg_split( '/(<.*?>)/', $content, -1, PREG_SPLIT_DELIM_CAPTURE ); // Capture the tags as well as in between.
- $length = count( $split );
- $ignore_count = 0;
- $replace_all_count = 0;
- for ( $i = 0; $i < $length; $i++ ) {
- $text = $split[ $i ];
- if( preg_match( $ignore_start, $text ) ){
- $ignore_count ++;continue;
- }
- if( preg_match( $ignore_end, $text ) ){
- $ignore_count --;continue;
- }
- if( $ignore_count > 0 ) { continue; }
- $replace_count=0;
- $split[ $i ] = preg_replace_callback( $search ,function ($matches) use ( $data ){
- return $data[ $matches[0] ];
- },$text,-1,$replace_count);
- $replace_all_count += $replace_count;
- }
- return $replace_all_count === 0 ? $content : implode("",$split);
- }
- add_filter('the_content','my_string_replace',30);
参考にしたコードがcode、pre、style、script、textareaタグ内での置き換えをおこなっていないので、上のコードも同様な処理をおこなっています。
基本的には受け取った文字列をタグで分割して、一行ずつ内容を確認しているだけです。
JavaScriptで置き換え
3つ目の方法は、JavaScriptでの置き換えです。
前項までの二つの方法はサーバー側の処理でしたが、こちらはスマホやパソコン側での処理になります。
次のコードを、jsファイルとして保存します。
- (()=>{
- // 対象データ
- const replaceData = {
- "(笑)" :"🙂",
- "(涙)" :"😥",
- "Yahoo!" : '<a href="https://www.yahoo.co.jp/">Yahoo!</a>',
- "けーちゃん" : '<img src="https://xxxx.com/kchan.png" alt="けーちゃん">けーちゃん'
- };
- // 除外タグ
- const ignoreTag = ["code","pre","style","script","textarea","ins"]
- .map( e=>e.toUpperCase() );
- const replaceRegx = new RegExp( "("
- + Object.keys(replaceData)
- .sort( (a,b)=>a<b ? 1 : -1 )
- .map( e=>e.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&") )
- .join("|")
- + ")");
- const replaceText = text =>{
- const r = text.replace(replaceRegx , m=>replaceData[m] );
- return r === text ? null : r;
- }
- const replaceTextNode = startElement=>{
- if( startElement === null || startElement.childNodes === null) return;
- const firstChild = node =>{
- return node.childNodes ? node.childNodes[0] : nextElement(node);
- };
- const nextElement = node =>{
- if( node.nextSibling ) return node.nextSibling;
- return node.parentNode === startElement ? null : nextElement(node.parentNode);
- };
- let currentElement = firstChild(startElement);
- while( currentElement){
- if( currentElement.nodeType === Node.ELEMENT_NODE
- && ignoreTag.indexOf( currentElement.tagName ) < 0 ){
- currentElement = firstChild(currentElement);
- continue;
- }
- if( currentElement.nodeType === Node.TEXT_NODE ){
- const r = replaceText(currentElement.nodeValue);
- if( r !== null ){
- const addElement = document.createElement("span");
- addElement.innerHTML = r;
- currentElement.replaceWith(addElement);
- currentElement = addElement;
- }
- }
- currentElement = nextElement( currentElement );
- }
- };
- window.addEventListener( "DOMContentLoaded" , ()=> {
- replaceTextNode( document.body );
- });
- })();
上のコードは除外するタグを変数ignoreTag で指定しています。
この中に ins がありますが、これはグーグルアドセンスが挿入した広告で使用されているので、影響がないように除外しています。
次にjsファイルを読み込むために、wp_enqueue_script()関数をfunction.phpなどで実行します。
- wp_enqueue_script( 'myreplace' ,'jsファイルのパス' );
どの方法がいいのか
今回挙げた3つの方法のうち、どれを選択すべきかは状況次第です。
ただ、少々使いにくいので一つ目のWordPressの英語圏顔文字変換機能を利用は、候補から外れることが多いと思います。
二つ目はサーバー側の処理時間が増えるのがデメリットです。
とはいえ、極端に遅くなるというほどではありません。
三つ目はサーバー側の負担が減るので、PV数が非常に多いサイトなら三つ目の方法がよいケースもあります。
しかしブラウザ側での読み込み終了までの時間が増えるので、SEO的に不利になる可能性があります。
あくまで可能性です。必ず不利になるということではありません。
PV数が非常に多くなることはほとんどないので、どちらかというと二つ目がおススメです。
■Googleで他サイト検索
■僕がおススメするアフィリエイト教材
■マーケティング施策ツール





こんにちは。