SpringBoot/thymeleafでAMP(Accelerated Mobile Pages)対応ページを、動的に生成してみます。
なお、STS3(3.9.6)+SpringBoot2.0+Tymeleaf3.0迄動作確認しています。
AMPカスタムタグに動的に値を渡すのは無理
amp-youtubeの利用方法を見るかぎり、動的に値を渡すのは無理そうです。
JavaScriptが使えませんからね。
最初、thymeleafの機能を使って、変数の置き換えをやれないかと思って、コントローラクラスで「amp1」という変数にVideo-idをセットして、以下のようにしてみましたが、ものの見事に失敗しました。
<amp-youtube width="480"
height="270"
layout="responsive"
data-videoid="${amp1}"
autoplay>
</amp-youtube>
やはり、AMPのカスタムタグは静的ページしか無理なのかな?
一瞬、そう思いましたが、ひとつアイディアがひらめきました。
コントローラクラスでHTMLを組み立ててしまえばいい
thymeleafには、「th:utext」というエスケープ無しに変数の値をテキストに展開してくれるカスタムタグがあります。
これを、Divタグとかに「<div th:utext="${msg}"></div>」のように使って、msgという変数に「<p>xxxxxxx</p>」みたいにHTMLをセットしておくと、「<div><p>xxxxxx</p></div>」みたいなHTMLを生成してくれます。
つまり、<amp-youtube> ~ </amp-youtube>までの全体をコントローラクラスで文字列として組み立てて、その変数をDivタグの「th:utext」に渡してやれば良いはずです。
早速、やってみます。
ベースは前回作ったサンプルにします。
まずはamp-youtubeの生成にチャレンジ
コントローラクラスに以下を追加します。
String vid = "Qkr60BoW4q0"; model.addAttribute("amp1","<amp-youtube width=\"480\" height=\"270\" layout=\"responsive\" data-videoid=\"" + vid + "\" autoplay> </amp-youtube>");
video-idをvidという変数にセットして、それを使って以下のHTMLを組み立てたものを、amp1という変数にセットしています。
<amp-youtube width="480"
height="270"
layout="responsive"
data-videoid="Qkr60BoW4q0"
autoplay>
</amp-youtube>
これを受けるHTML側はこうです。
<div class="content_fix" th:utext="${amp1}"></div>
これでいけるはずです。
ついでにamp-imgで画像のパスが展開されるかも試そう
thymeleafを使うにあたり、もうひとつ確認すべき部分があります。
それは、画像などの静的コンテンツへのパスです。
HTMLをtempleteフォルダに置き、静的コンテンツはstaticフォルダ配下に置くというのが、thymeleafのルールです。
そのため、単純にパスを書いてもうまくいきません。
@{・・}を使って、imgタグの場合だと以下のように書きます。
<img src="../static/images/hello.jpg" th:src="@{/images/hello.jpg}"></img>
ところが、AMPの場合は、IMGタグを使用禁止で、amp-img というカスタムタグを使う必要があります。
これに、th:srcが使えるか?も確認しておきます。
static/images の下に「boku.jpg」という画像を置き、以下を追加します。
<amp-img th:src="@{/images/boku.jpg}" width="100" height="80" alt="AMP"> </amp-img>
これでいけるか試します。
さて実行して表示確認します。
SpringBootアプリケーションを実行して、表示させてみます。
URLは前回と同じ「http:localhost:8080/amptest」です。
表示はこんな感じ
おお、いけてる。
画像も表示できてますね。(BOKUのプロフィールの写真ですが)
th:srcの展開はうまくいったみたいです。
この2通りのやり方がいけるなら、AMP対応ページを、SpringBootとthymeleafで動的に生成して表示することはできそうです。
これで、高速表示できるページができるなら、悪くない・・ですね。
まとめ
ただ。
自分としては、全面的にAMPページに移行したら良いとは思いませんけどね。
正直、AMP対応をしてメリットがデメリットを上回るページは対応する。
そうでなければ、当面、様子を見て今までのやり方でページを作る。
こんな感じの混在型にした方が良いんじゃないか?
そう思ってます。
最後に今回のソース全体です。
HTML部分です。
<!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <title> Hello World</title> <script async src="https://cdn.ampproject.org/v0.js"></script> <script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script> <link rel="canonical" href="http://localhost:8080/amptest"> <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> <style amp-custom> .content{ wide:100%; text-align:center; } .content_fix{ margin-left:2em; margin-right:2em; } h1 { text-align:center; color: red; } p{ margin-left:2em; margin-right:2em; margin-top:0.5em; margin-bottom:0.5em; } img{ width:auto; height:auto; } </style> <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> </head> <body> <h1>AMPで動画を表示してみる</h1> <div class="content"> <amp-img th:src="@{/images/boku.jpg}" width="100" height="80" alt="AMP"> </amp-img> <p th:text="${msg1}" /> <p th:text="${msg2}" /> </div> <div class="content_fix" th:utext="${amp1}"></div> </body> </html>
@Controller public class TestContoroller { @RequestMapping("/amptest") public String hello(Model model) { model.addAttribute("msg1","ギターをチョッパースタイルで叩きまくるギタープレイが超絶格好良い。"); model.addAttribute("msg2","TarO and JirOの Snake Bite ~ Silent Siren"); String vid = "Qkr60BoW4q0"; model.addAttribute("amp1","<amp-youtube width=\"480\" height=\"270\" layout=\"responsive\" data-videoid=\"" + vid + "\" autoplay> </amp-youtube>"); return "amp_test"; } }