WordPressでコード表示を美しく行う「Highlight Code Block(HCB)」と、記事販売サービス「Codoc(コードク)」を併用していると、以下のような問題が起こることがあります。
- Codoc経由で表示される記事で、コードブロックがハイライトされない
- コピー用のボタンが表示されない
この記事では、それらの問題を解消するための「後から読み込まれるHCBブロックに対して、Prism.jsとClipboard.jsを強制適用する」ためのコードをご紹介します。
目次
codocの有料記事コンテンツ内でHighlighting Code Blockを表示する方法
CodocなどのJavaScriptで後から読み込まれるコンテンツにも、PrismのシンタックスハイライトとClipboardボタンを確実に適用します。
以下のコードを、functions.phpに追記してください。
設置コード
add_action('wp_footer', 'force_hcb_for_codoc_fallback');
function force_hcb_for_codoc_fallback() {
?>
<script>
document.addEventListener("DOMContentLoaded", function () {
let hcb_processed = new WeakSet();
const observer = new MutationObserver(() => {
document.querySelectorAll('.hcb_wrap').forEach((wrap, index) => {
if (hcb_processed.has(wrap)) return;
hcb_processed.add(wrap);
const code = wrap.querySelector('code');
if (!code) return;
// Prism.jsによるハイライトを強制適用
if (typeof Prism !== 'undefined' && Prism.highlightElement) {
Prism.highlightElement(code);
}
// コピー用ボタンがなければ追加
if (wrap.querySelector('.hcb-clipboard')) return;
const btn = document.createElement('button');
btn.className = 'hcb-clipboard';
btn.setAttribute('data-clipboard-target', `[data-hcb-clip="${index + 1}"]`);
btn.setAttribute('data-clipboard-action', 'copy');
btn.setAttribute('aria-label', 'コピー');
wrap.appendChild(btn);
code.setAttribute('data-hcb-clip', index + 1);
});
// ClipboardJS初期化
if (typeof ClipboardJS !== 'undefined') {
new ClipboardJS('.hcb-clipboard').on('success', function (e) {
e.trigger.classList.add('-done');
setTimeout(() => {
e.trigger.classList.remove('-done');
}, 3000);
});
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
</script>
<?php
}解説
MutationObserverを使って、後から追加される.hcb_wrap要素を検知- 各
.hcb_wrapに対して Prism.js のシンタックスハイライトを適用 - ClipboardJS のコピー用ボタンも動的に追加・初期化
WeakSetを使って、既に処理したブロックをスキップすることでパフォーマンスと二重処理を防止
使用上の注意
Prism.jsおよびClipboardJSは、あらかじめ読み込まれている必要があります。Highlight Code Blockプラグインを使用していることが前提です。
まとめ
codocのような特殊な条件下ではJSやCSSが効いてないブロックがあったりするので、注意しておきましょう。
この記事で紹介しているコードは、GitHubのMOTOKI-LLC/WAZA-codeにもまとめています。



