WordPressの固定ページ内で<script>
タグを使用する際、ショートコードが正しく展開されないという問題に遭遇することがあります。この記事では、この問題の解決方法を解説します。
問題の例
例えば、以下のようなショートコードを設定していたとします:
//shortcodes.php または functions.php
$urls = array(
'topthemeurl' => 'https://example.com/wp-content/themes/your-theme',
'commonsurl' => 'https://example.com/wp-content/themes/your-theme/commons'
);
function register_shortcodes() {
global $urls;
foreach ($urls as $key => $value) {
add_shortcode($key, function () use ($value) {
return $value;
});
}
}
固定ページ内で以下のように記述した場合:
<link rel="preload" href="[topthemeurl]/js/script.js" as="script">
<script src="[topthemeurl]/js/script.js"></script>
<link>
タグではショートコードが正しく展開されますが、<script>
タグでは展開されないという問題が発生します:
<!-- 結果(view-source) -->
<link rel="preload" href="https://example.com/wp-content/themes/your-theme/js/script.js" as="script">
<script src="[topthemeurl]/js/script.js"></script>
解決方法
この問題を解決するには、functions.php
に以下のコードを追加します:
//scriptタグ内のショートコードを処理する
add_filter('the_content', 'process_shortcodes_in_script', 99);
function process_shortcodes_in_script($content) {
if (false === strpos($content, '<script')) {
return $content;
}
//DOMDocumentを使用してHTMLを解析
$dom = new DOMDocument();
//HTML5のタグを適切に処理するための設定
libxml_use_internal_errors(true);
$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
//scriptタグを検索
$scripts = $dom->getElementsByTagName('script');
//各scriptタグに対して処理
foreach ($scripts as $script) {
//src属性を取得
$src = $script->getAttribute('src');
if ($src) {
//src属性内のショートコードを処理
$new_src = do_shortcode($src);
$script->setAttribute('src', $new_src);
}
}
//変更を適用したHTMLを返す
$new_content = $dom->saveHTML();
//余分なタグを削除
$new_content = preg_replace('/<(!DOCTYPE|html|body).*?>|<\/(html|body)>/', '', $new_content);
return $new_content;
}
コードの説明
このコードは以下のような流れで動作します:
-
the_content
フィルターを使用して、ページコンテンツが表示される前に処理を行います - コンテンツ内に
<script>
タグが存在するか確認します - DOMDocumentを使用してHTMLを解析します
- すべての
<script>
タグを見つけ、src
属性内のショートコードを処理します - 処理したHTMLを返します
注意点
- このコードはページのコンテンツ全体を処理するため、パフォーマンスに若干の影響がある可能性があります
- 複雑なHTML構造を持つページでは、予期しない結果が生じる可能性があります
- UTF-8エンコーディングを使用していることを前提としています
使用例
このコードをfunctions.php
に追加後は、固定ページ内で以下のように記述できます:
<link rel="preload" href="[topthemeurl]/js/script.js" as="script">
<script src="[topthemeurl]/js/script.js"></script>
両方のタグで正しくショートコードが展開され、以下のような結果となります:
<link rel="preload" href="https://example.com/wp-content/themes/your-theme/js/script.js" as="script">
<script src="https://example.com/wp-content/themes/your-theme/js/script.js"></script>
まとめ
この方法を使用することで、WordPressの固定ページ内の<script>
タグでもショートコードを使用できるようになります。これは特に以下のような場合に便利です:
- テーマのディレクトリパスを動的に管理したい場合
- マルチサイト環境でスクリプトのパスを柔軟に制御したい場合
- 下層に別のWordPressをインストールしている場合のパス管理
必要に応じてコードをカスタマイズし、自身の環境に最適な形で利用してください。