SpringBoot+Tymeleafで非AMPページと、AMPページの混在での動きを確認します。
STS3(3.9.6)+SringBoot2.0+Tymeleaf3.0迄動作確認しています。
今回やってみること
まあ、凝ったことをするのは・・アレ・・なので、以下のようなことをします。
- ① 非AMPページ:SELECTで曲名を選んで、実行ボタンを押す。
- ② AMPページ:選択されたVideo-idの動画を表示する。
- ③ AMPページ:リンクをクリックして、非AMPページへ遷移する。
- ④ 非AMPページ:表示していた曲をSELECTEDとして表示する
こういうのは、よくありがちな行き来の例になると思いますので。
非AMPページ(曲を選択する画面)を用意します
こんな感じの画面です。
「Qkr60BoW4q0」と表示しているのは、選択中の曲のVIDEO-IDです。
最初にソースを表示して、後で解説します。
コントローラクラス
最初にコントローラクラスのこの画面を表示させる部分です。
@RequestMapping(value = "/inpg01", method = RequestMethod.GET) public String index(SongInputForm form, Model model,@RequestParam(name ="videoid", required = false) String videoid) { model.addAttribute("songInputForm", form); model.addAttribute("selectItems",getSelectedItems()); if(form.getSelectedItem()== null){ form.setSelectedItem("Qkr60BoW4q0"); } if(videoid != null){ form.setSelectedItem(videoid); } return "inpg01"; } private Map<String,String> getSelectedItems(){ Map<String, String> selectMap = new LinkedHashMap<String, String>(); selectMap.put("Qkr60BoW4q0", "TaRo&JiRo /silent siren"); selectMap.put("HIEdkeWZwQM", "superfly / ビリリエモーション"); selectMap.put("uM_z5PXRE3E", "ローリング・ストーンズ/ジャンピンジャックフラッシュ"); selectMap.put("WK0z87WrhGo", "ニュース/パワー・オブ・ラブ"); return selectMap; }
上記の「 getSelectedItems()」メソッドで今回は、簡易にSELECTの選択肢をセットしています。
KEYがVIDEOーID、VALUEが曲名になるMapを生成して、Modelにセットすることで、HTML側から参照できるようにしてます。
あと、ポイントになるのが、index()メソッドの引数に追加している「@RequestParam(name ="videoid", required = false) String videoid」です。
こうすることで、URLパラメータで「?videoid=XXXXXXXX」のようにして値を受け取ることができます。
required=falseとしているのは、URLパラメータを必須にしないという意味です。
こうしておかないと、渡すべき値がない時でも、URLパラメータをつけないとエラーになるので、必ずつけるようにしてます。
続けて、HTMLです。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sample App</title> <link href="../static/css/styles.csss" th:href="@{/css/styles.css}" rel="stylesheet"/> </head> <body> <div class="box"> <h1>Video-id</h1> <form role="form" id="SongInputForm" action="/outpg01" th:action="@{/outpg01}" th:object="${songInputForm}" method="post"> <p>Please select Video-Id</p> <p th:text="*{selectedItem}"></p> <select id="singleSelect" name="selectedItem"> <option value="">---</option> <option th:each="item : ${selectItems}" th:value="${item.key}" th:text="${item.value}" th:selected="${item.key} == *{selectedItem}">singleSelect</option> </select> <button type="submit">実行</button> </form> </div> </body> </html>
まあ、普通のthymeleafのHTMLです。
さきほど、SELECTの選択肢をセットした SelectedItemの値を「th:each="item : ${selectItems}"」でループして表示しています。
CSS
CSSは、staticフォルダのcssフォルダにおいて参照してます。
こんな程度しか書いてませんが。
@CHARSET "UTF-8"; html { font-size:16px } body { font-family: 'メイリオ','Hiragino Kaku Gothic Pro',sans-serif; background-color:white; } .box{ wide:100%; text-align:center; } p{ margin-left:1em; margin-right:auto; margin-top:0.5em; margin-bottom:0.5em; }
そしてFormクラスです。
画面で選択された値(KEYの方)を保持して、画面間で引き継ぐ変数を定義します。
public class SongInputForm implements Serializable { private static final long serialVersionUID = 109099L; private String selectedItem; public String getSelectedItem() { return selectedItem; } public void setSelectedItem(String selectedItem) { this.selectedItem = selectedItem; } }
出力側(AMP対応ページ)を用意する。
まず、実行ボタンが押された時に、処理を行うメソッドです。
コントローラクラスに追加します。
@RequestMapping(value = "/outpg01", method = RequestMethod.POST) public String confirm(@Validated @ModelAttribute SongInputForm form, BindingResult result, Model model) { if (result.hasErrors()) { return index(form, model,null); } String vid = form.getSelectedItem(); model.addAttribute("returnUrl","http://localhost:8080/inpg01?videoid=" + vid); model.addAttribute("amp1","<amp-youtube width=\"480\" height=\"270\" layout=\"responsive\" data-videoid=\"" + vid + "\" autoplay> </amp-youtube>"); return "outpg01"; }
入力画面の<form>のactionで「/outpg01」と指定されているのを受けて、「confirm」メソッドが実行されるというお約束にそってます。
選択されたVIDEO-IDは、Formクラスを経由して、「 String vid = form.getSelectedItem();」でうけとって、セットします。
あとはそれを使って表示するだけなので、前々回と変わりません。
注意が必要なのは、入力画面に戻るためのリンクを組み立てている以下の部分です。
model.addAttribute("returnUrl","http://localhost:8080/inpg01?videoid=" + vid);
URLパラメータで選択されたVIDEO-IDを渡す形にURLを作ってます。
単純にリンクで画面遷移しても、Formの内容は引き継がれません。
こうしないと情報を渡せないからです。
<form>を使って引き継ぐ方法は、AMP対応ページでは使えるけど使わない・・と前回決めたのでね。
これをうけるHTMLです。
<!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Sample App</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/amp01"> <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> <div class="content" th:object="${songInputForm}"> <h1>AMPで動画を表示してみる</h1> <a th:href="${returnUrl}" target="_blank">動画選択画面へ</a> <div class="content_fix" th:utext="${amp1}"></div> </div> </body> </html>
ほぼ、前々回のAMPページサンプルと変わりません。
注意が必要なのは、以下の部分です。
<a th:href="${returnUrl}" target="_blank">動画選択画面へ</a>
returnUrlで組み立てたURLを表示するわけですが、「target="_blank"」を指定しています。
実は、AMP対応ページでの「a」タグのtarget属性は_blank以外は駄目・・らしいので、注意が必要です。
さて実行してみよう。
tomcatを8080ポートで動かしているので、「http:localhost:8080/inpg01」でアクセス。
それで、「ビリリエモーション」を選択して、実行ボタンを押します。
そしたら、AMPページでビリリエモーションが再生。
その状態で、動画選択画面へをクリックして画面遷移します。
いちおう、ビリリエモーションのIDが引き継がれて、初期選択状態になってます。
まあ、こんなもんでしょうね。
まとめ
4回ほど、AMP対応ページで遊んでみました。
確かに表示の速さは体感できるほど改善されるので、非常によいなと思う半面、速度を実現するための様々な制限があることもわかりました。
まあ、万能な技術なんてありませんから・・当然なんですけど。
でも、Springbootとthymeleafの組み合わせなら、工夫次第で、非AMPとAMPのページを適材適所配置することも可能かもしれないな・・と・・現時点での個人的見解です。
ではでは。