WordPressで2つのテーマ内ファイルを比較する方法!Theme Test Driveと親和性あり

      2018/04/07

theme-compare-top

WordPressで2つのテーマ内ファイルを比較する方法です。

テーマ内ファイルの変更を、安全かつ快適にできるようになりますよ!

SPONSORED LINK

テーマのテスト方法

テーマを構成しているPHPやCSSのファイルを直接変更していると、記述ミスでデザインが崩れたり、ページが表示できなくなったりする危険性があります。

Theme Test Drive

変更中の問題を防ぐためには、テーマをテストするプラグイン「Theme Test Drive」を使うと便利です。WordPress管理ページにログインしているユーザーだけ(テスト用の)別テーマで表示、他の閲覧者には今まで通りのテーマで表示ということができます。

theme-test-drive-1

同じサイトにアクセスしていても、管理ページにログインしている「自分」だけはテーマBを使って表示されるということです。こんな手順で作業すれば、問題を発生させることなくテーマの変更ができます。

  1. まずテーマAをコピーしてテーマBとする。
  2. Theme Test DriveでテーマBを表示するようにする。
  3. テーマB内のファイルを変更し、適宜表示を確認。
    • 途中ミスしてページが表示できなくなっても、ログインしていない閲覧者達には普段通り表示されます。心配ならログインしていない他のブラウザで「普通の閲覧者の表示」も確認しておきましょう。
  4. 納得いくデザインになったら、Theme Test Driveをオフにして、WordPressのテーマ設定をテーマBに切り替える。
  5. テーマBに入れた変更を、テーマAに適用する。
  6. 次回はAとBを入れ替えてテストする。

どのファイルを変更したかが分からなくなる

問題が発生して変更を元に戻したいときや、テーマBへの変更をテーマAに適用するときに、どこに変更を入れたのかが分からなくなることがよくあります。

theme-test-drive-2

スタイルの変更だけなら良いんですが、PHPも変更していると影響するファイルが多くて色んなファイルを一気に変更するなんてことがよくありますね。こうしていると一体どこに変更をいれたのか分からない。

PHPの比較って意外と面倒

PHPのファイル内容は普通には(外からは)見られません。URLでPHPファイルにアクセスしても、PHPを実行した結果が返ってくるだけで元のPHPの内容は分かりません。

すると単に比較するだけのために、両方のテーマの構成ファイルをFTPですべてダウンロードして、ローカルで比較しないといけなくなります。テーマによっては構成ファイルが5, 60なんてザラですね。「変更したのは3ファイルくらいだけどどれだっけ?」みたいな時に毎回全部ダウンロードなんてあまり賢くありません。

SPONSORED LINK

「テーマ内PHP/CSSを比較するPHP」を作成

そこで解決方法です。テーマ内の構成ファイルを比較するプログラムをPHPで作成し、サーバー上で実行して比較結果を表示させるようにしました。

比較結果

theme-compare2-quant

比較結果はこんな風に表示されます。単純なファイル内容一致判定なのでどこが異なるかまでは分かりませんが、どのファイルが変更されているのかは一目瞭然ですね!

ソースコード

以下ソースコードです。これをテーマフォルダ内に「wp-content/themes/○○/compare.php」などと置き、直接このファイルのURLにアクセスすると結果が表示されます。ポイントは4点。

  • まずにAを基準に比較。内容一致、内容不一致、Aにのみ存在するファイルに分ける。不一致の場合は日付を比較する。
  • 次にBを基準にBしかないファイルを探索。
  • style.css に書かれたテーマ名は異なって問題ない(むしろ同じだと不便)ので、「Theme Name:」の行は無視する。
  • 結果はHTMLの表形式にする。style.cssを呼んでテーマと同じ表デザインで表示。
<html>
<head>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="late.css">
    <style>
        .post {
            max-width: 700px;
            margin: 20px;
        }
    </style>
</head>
    
<body>
    <?php
    $dirA = '../[themeA]';
    $dirB = '../[themeB]';
    ?>
    <div class="post">
        <table>
            <tr>
                <th></th>
                <th>テーマA</th>
                <th>テーマB</th>
                <th>比較結果</th>
            </tr>
            <?php
            $same_file = $diff_file = '';
            
            $dir_handlerA = opendir($dirA);
            while(false !== ($fn = readdir($dir_handlerA))){
                $fileA = $dirA.'/'.$fn;
                $fileB = $dirB.'/'.$fn;
                if($fn !== '.' && $fn !== '..' && !is_dir($fileA)){
                    $contA = $contB = $mtimeA = $mtimeB = '';
                    if( file_exists($fileA) ) {
                        $contA = file_get_contents($fileA);
                        $mtimeA = date('m/d H:i', filemtime($fileA));
                    }
                    if( file_exists($fileB) ) {
                        $contB = file_get_contents($fileB);
                        $mtimeB = date('m/d H:i', filemtime($fileB));
                    }
                    // style.cssでは「Theme Name」行を無視
                    if($fn == 'style.css')
                    {
                        $contA = preg_replace('/^Theme Name:.*$/m', 'Theme Name:', $contA, 1);
                        $contB = preg_replace('/^Theme Name:.*$/m', 'Theme Name:', $contB, 1);
                    }
                    if($contA == $contB){
                        $result = '一致';
                    } else if($contA == '') {
                        $result = 'Bのみ存在';
                    } else if($contB == '') {
                        $result = 'Aのみ存在';
                    } else if( filemtime($fileA) > filemtime($fileB) ) {
                        $result = 'Aの方が新しい';
                    } else if( filemtime($fileA) < filemtime($fileB) ) {
                        $result = 'Bの方が新しい';
                    } else {
                        $result = '異なるが時刻は一致';
                    }
                    $current_file = <<<EOD
                    <tr>
                        <th>{$fn}</th>
                        <td>{$mtimeA}</td>
                        <td>{$mtimeB}</td>
                        <td>{$result}</td>
                    </tr>
EOD;
                    if($contA == $contB)
                        $same_file .= $current_file;
                    else
                        $diff_file .= $current_file;
                }
            }
            closedir($dir_handlerA);
            
            $dir_handlerB = opendir($dirB);
            while(false !== ($fn = readdir($dir_handlerB))){
                if($fn !== '.' && $fn !== '..' && !is_dir($dirB.'/'.$fn)
                  && !file_exists($dirA.'/'.$fn) ){
                    $mtimeB = date('m/d H:i', filemtime($dirB.'/'.$fn));
                    $diff_file .= <<<EOD
                    <tr>
                        <th>{$fn}</th>
                        <td></td>
                        <td>{$mtimeB}</td>
                        <td>Bのみに存在</td>
                    </tr>
EOD;
                }
            }
            closedir($dir_handlerB);
            
            echo $diff_file;
            echo $same_file;
            ?>

        </table>
    </div>
</body>
</html>

※ ファイル一覧の取得には以下のサイトを参考にしました。
[PHP]指定したディレクトリのファイル一覧を取得する « Codaholic

まとめ

これでテーマ間比較が簡単になりましたね!

安全・快適にデザイン変更を施しましょう。

itjo レスポンシブ 本文下

 - WordPress
 - , , ,