webページの共通部分をテンプレート化する javascript

webページを作成しているとき、ヘッダーやフッターといった各ページに共通するものってありますよね。
皆さんはそのような共通部の管理はどのようにしていますか・・・?

色々調べてみると、

  • iframeを用いて外部ファイルをインクルード(異なるHTMLをiframe要素の枠の中に表示しているだけ)
  • SSIを使用したインクルード(サーバーサイドに追加設定の必要あり)
  • ajaxを使う(ajaxの設定部もテンプレート化したいんだけど。。。)
  • jQuery(上に同じく、jQueryの設定部もテンプレート化したいんだけど。。。)
  • javascriptを使う(超絶原始的)

などなど、色々な手法が出てきます。

共通部分の読み込みは私もよくjQueryを使用するのですが、jQueryの設定の記述も各ページ共通だからテンプレート化したい!

と思い、皆さんにも共有したいと思います。

htmlに共通テンプレートを読み込む機能は無いのか

やー、、、無いですね。(私が探した限りでは。)
この機能、絶対に必要だと思うのですが。。。

そこで私も、先程あげたiframeやらSSIやら色々試したのですが、最終的に行き着いた答えが。。。

『javascriptでテキストを出力する』

という超絶原始的な手法に行き着きました。
結論、この方法が一番シンプルで手っ取り早いかなと。はい。

そして、書き方を工夫すれば意外と見易く書けることに気づきました。

javascriptでheadの共通部分をテンプレート化してみる

複数ページにまたがるサイトですと、共通部分が多くなると思います。
特にheadの中身なんて、タイトル以外どのページも同じなのではないでしょうか?

そこで今回は、htmlのheadの共通部分を外部ファイル(javascript)として作成して読み込んでみます。
つまり、、、

<!DOCTYPE html>
<html>
<head>
    ##### ここに入る各ページ共通の設定をテンプレート化したい! #####
    <title>ページのタイトルだよ</title>
</head>
<body>
...

こういうことですね。

共通部分を出力するjavascriptを書く

今回書くjavascriptは、何の捻りもないjavascript。

document.write()関数で文字列を出力するのみ。
このjavascriptを各htmlファイルで読み込むことで、共通部の記述ができるわけだ。

とりあえず、名前をtemplate_head.jsとしよう。文字列の記述に一工夫加えることで見易くなります。

document.wtite()にて挿入したscriptについてはいくつかの問題があります。
ページ下部にまとめています。

var contents = [
    "<!-- Global site tag (gtag.js) - Google Analytics -->",
    '<script async src="https://www.googletagmanager.com/gtag/js?id=XXXXXXXXXXXXX"></script>',
    "<script>",
    " window.dataLayer = window.dataLayer || [];",
    " function gtag(){dataLayer.push(arguments);}",
    " gtag('js', new Date());",
    "",
    " gtag('config', 'XXXXXXXXXXXXX');",
    "</script>",
    "<link rel='stylesheet' href='https://use.fontawesome.com/releases/v5.6.3/css/all.css' integrity='sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/' crossorigin='anonymous'>",
    "<script type='text/javascript' src='jquery/jquery-3.3.1.js'></script>",
].join("¥n");

document.write( contents );

何の変哲もないjavascriptだが、出力したい文字列を記述するところに注目してほしい。

文字列で殴り書きするのではなく、文字列の配列を用いることで縦のラインを揃えることができる。

配列の最後を .join(“\n”) とすることで、配列の文字列を改行コードを挟んで結合している。

我ながら結構いいアイデアではないでしょうか。笑

テンプレートを読み込む

あとは、このjavascriptファイルを適当な場所に置き、元のhtmlで読み込んであげればいい。

例えば、template_head.jsを元のsample.htmlと同じ階層に置いた場合、次のようになる。

<!DOCTYPE html>
<html>
<head>
    <script src="./template_head.js"></script>
    <title>ページのタイトルだよ</title>
</head>
<body>
...

これで共通部分のテンプレート化は完了です。

document.write()によってscriptを追加した場合の問題点

document.write()関数でscriptを追加する際には少し注意が必要です。

ブラウザgoogle chrome(Chrome55以降)では、
2G接続ユーザは、document.write()によって追加されたキャッシュされていないscriptは実行されない。
という仕様になっています。

2G。つまり超低速回線(現在が4Gで5Gの試験運用が始まろうとしている。)ユーザは、document.write()によって追加されたscriptは読み込まれないということになります。

試しに、document.write()関数でscriptを実行すると、以下のようなwarningが表示されます。

A parser-blocking, cross site

今回はhead部の共通化について説明したが、この手法はheadではなくbody内でもどこでも使用できるので。
皆さんも参考にしてみてください。