Posted at

AMPテンプレートからはじめる AMPで実装するリスト表示


はじめに

AMPコンポーネントを組み合わせて一般的なリスト表示を実現する。

今回はQiita API v2を使って新着の記事一覧を取得し、ページネーションを実現する。

Qiita API v2


実装したいもの


  • 今回は以下のスクリーンショット赤枠の部分を実現する事とする。(https://qiita.com/tags/amp?page=1)

  • 完全に模倣することはせず、それっぽい感じに実装する。

  • 記事のタイトルとユーザー名、タグ、ユーザーアイコンが表示されたリストを実現する。

image.png


使用するAMP component


amp-bind


  • データバインディング及びカスタムステートフルインタラクティブを実現。

amp-bind


amp-list


  • JSONを動的に取得し、レンダリングを実現。

amp-list


amp-mustache

amp-mustache

mustache.js


実装手順


下準備


AMP テンプレートの準備

<!doctype html>

<html amp lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Hello, AMPs</title>
<link rel="canonical" href="https://amp.dev/ja/documentation/guides-and-tutorials/start/create/basic_markup">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<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>Welcome to the mobile web</h1>
</body>
</html>


使用するAMP componentの準備

<!doctype html>

<html amp lang="en">
<head>
・・・
<link rel="canonical" href="https://amp.dev/ja/documentation/guides-and-tutorials/start/create/basic_markup">
<meta name="viewport" content="widt
h=device-width,minimum-scale=1,initial-scale=1"
>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
・・・
</html>

Create your AMP HTML page


リストを作成する


記事のタイトルとユーザー名、タグの情報を表示

<!doctype html>

<html amp lang="en">
<head>
・・・
</head>
<body>
<amp-list class="paged-amp-list"
layout="fixed-height"
height="720"
src="https://qiita.com/api/v2/items"
binding="no"
items="."
single-item
id="App">
<template type="amp-mustache">
<div class="items">
<div class="user-info-area">
<div class="title">{{title}}</div>
<div class="user-name">by {{user.name}}</div>
<div class="tag-area">
<i class="fas fa-tags"></i>
{{#tags}}
<span>{{name}}</span>
{{/tags}}
</div>
</div>
</div>
</template>
</amp-list>
</body>
</html>

image.png

amp-list

amp-mustache

amp-list src

amp-list binding

amp-list items


ユーザーのアイコンを表示



  • amp-img を使って画像を表示する。

<!doctype html>

<html amp lang="en">
<head>
・・・
</head>
<body>
<amp-list class="paged-amp-list"
layout="fixed-height"
height="720"
src="https://qiita.com/api/v2/items"
binding="no"
items="."
single-item
id="App">
<template type="amp-mustache">
<div class="items">
<div class="image-area">
<amp-img
class="image"
width="40"
height="40"
src="{{user.profile_image_url}}"></amp-img>
</div>
<div class="user-info-area">
<div class="title">{{title}}</div>
<div class="user-name">by {{user.name}}</div>
<div class="tag-area">
<i class="fas fa-tags"></i>
{{#tags}}
<span>{{name}}</span>
{{/tags}}
</div>
</div>
</div>
</template>
</amp-list>
</body>
</html>

image.png

amp-img


記事ページへのリンクを追加


  • aタグ追加

<!doctype html>

<html amp lang="en">
<head>
・・・
</head>
<body>
<amp-list class="paged-amp-list"
layout="fixed-height"
height="720"
src="https://qiita.com/api/v2/items"
binding="no"
items="."
single-item
id="App">
<template type="amp-mustache">
<div class="items">
<a href="{{url}}" class="item">
<div class="image-area">
<amp-img
class="image"
width="40"
height="40"
src="{{user.profile_image_url}}"></amp-img>
</div>
<div class="user-info-area">
<div class="title">{{title}}</div>
<div class="user-name">by {{user.name}}</div>
<div class="tag-area">
<i class="fas fa-tags"></i>
{{#tags}}
<span>{{name}}</span>
{{/tags}}
</div>
</div>
</a>
</div>
</template>
</amp-list>
</body>
</html>

amp-list-demo2.gif


ページネーションの実装



  • amp-bindsetStateを使って実現する。


  • pageNumberが変化したタイミングでqiita apiを叩いて、情報を取得する。

[src]="'https://qiita.com/api/v2/items?page=' + pageNumber"

<!doctype html>

<html amp lang="en">
<head>
・・・
</head>
<body>
<amp-list class="paged-amp-list"
layout="fixed-height"
height="720"
src="https://qiita.com/api/v2/items"
[src]="'https://qiita.com/api/v2/items?page=' + pageNumber"
binding="no"
items="."
single-item
id="App">
<template type="amp-mustache">
<div class="items">
<a href="{{url}}" class="item">
<div class="image-area">
<amp-img
class="image"
width="40"
height="40"
src="{{user.profile_image_url}}"></amp-img>
</div>
<div class="user-info-area">
<div class="title">{{title}}</div>
<div class="user-name">by {{user.name}}</div>
<div class="tag-area">
<i class="fas fa-tags"></i>
{{#tags}}
<span>{{name}}</span>
{{/tags}}
</div>
</div>
</a>
</div>
</template>
</amp-list>
<div class="navigation">
<button class="button"
hidden
[hidden]="pageNumber < 2"
on="tap: AMP.setState({ pageNumber: pageNumber - 1 })"
>
Previous
</button>
<button class="button"
[hidden]="page ? pageNumber >= page.items.pageCount : false"
on="tap: AMP.setState({ pageNumber: pageNumber ? pageNumber + 1 : 2 })">
Next
</button>
</div>
</body>
</html>

amp-bind updating-state-with-amp.setstate()


fontawesome でタグのアイコンを表示


  • タグのアイコン部分はfontawesomeを使う。

<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">

<!doctype html>

<html amp lang="en">
<head>
・・・
<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>
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
</head>
<body>
・・・
</body>
</html>

image.png


最低限のCSSをあてる

<!doctype html>

<html amp lang="en">
<head>
・・・
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
<style amp-custom>
.paged-amp-list {
margin: 20px;
}

.item {
display: block;
margin-bottom: 20px;
border-bottom: solid 1px #e8e8e8;
text-decoration: none;
color: black;
}

.image {
display: block;
}

.image-area {
display: table-cell;
padding: 15px;
}

.user-info-area {
display: table-cell;
vertical-align: top;
padding: 15px;
}

.navigation {
text-align: center;
}

.button {
display: inline-block;
width: 160px;
padding: 0.8em;
text-align: center;
text-decoration: none;
color: #fff;
background:#0C88CA;
border-bottom:4px solid #005691;
border-radius: 4px;
}
</style>
</head>
<body>
・・・
</body>
</html>

amp-list-demo5.gif