产品页面
简介
此示例展示了如何在 AMP HTML 中构建产品页面。
元数据
页面索引需要 schema.org 标记,用于以下类型之一:Type、AggregateRating、Offers。 了解更多。
<script type="application/ld+json">
{
"@context": "http://schema.org/",
"@type": "Product",
"name": "Apple",
"image": "https://amp.js.cn/static/samples/img/golden_apple1_1024x682.jpg",
"description": "Lorem ipsum",
"mpn": "925872",
"brand": {
"@type": "Fruit",
"name": "Apple"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.4",
"reviewCount": "88"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"price": "1.99",
"priceValidUntil": "2020-11-05",
"itemCondition": "http://schema.org/UsedCondition",
"availability": "http://schema.org/InStock",
"seller": {
"@type": "Retail",
"name": "AMP by Example"
}
}
}
</script>
导航
使用 amp-sidebar 组件,让客户有机会快速跳转到您的任何产品类别。
<amp-sidebar id="drawermenu" layout="nodisplay">
<a href="/" class="caps text-decoration-none block p1">Products</a>
<hr/>
<a class="caps text-decoration-none block p1" href="/samples_templates/product_browse_page/preview/">Fruit</a>
<a class="caps text-decoration-none block p1" href="/samples_templates/product_browse_page/preview/">Vegetable</a>
<a class="caps text-decoration-none block p1" href="/samples_templates/product_browse_page/preview/">More</a>
</amp-sidebar>
带搜索的标题
AMP 支持表单,这意味着您可以直接将产品搜索集成到您的 AMP 中。 尝试搜索“Apple”。
您可以使用 CSS3 动画来丰富您的页面。 搜索框获得焦点时,扩展文本字段仅使用 CSS 实现。
<div class="header">
<a id="sample-menu" on="tap:drawermenu.toggle">
<amp-img srcset="/static/samples/img/ic_menu_white_1x_web_24dp.png 1x, /static/samples/img/ic_menu_white_2x_web_24dp.png 2x"
width="24" height="24"
alt="navigation"></amp-img>
</a>
<form method="GET" action="/documentation/examples/api/search" target="_top">
<input name="search" type="search" placeholder="Search">
<a id="sample-logo" href="/">Product</a>
<input type="submit" value="">
</form>
</div>
社交分享
社交分享扩展为分享按钮提供了一个通用界面。 在此处了解更多关于 amp-social-share
的信息。
<div class="m1">
<amp-social-share type="twitter"
width="30"
height="22"></amp-social-share>
<amp-social-share type="facebook"
width="30"
height="22"
data-attribution="254325784911610"></amp-social-share>
<amp-social-share type="email"
width="30"
height="22"></amp-social-share>
<amp-social-share type="pinterest"
width="33"
height="22"></amp-social-share>
</div>
视频
AMP 支持广泛的视频平台。 在这里,我们使用 amp-youtube
来展示产品视频。 您可以在此处找到所有支持的视频平台的概述。
在此示例中,我们不直接将视频嵌入到页面中,而是使用 amp-lightbox
组件将其显示在灯箱中。 在此处了解更多关于 amp-lightbox
的信息。
<button class="ampstart-btn caps m1 mb3" on="tap:watch-video-lightbox" >
Show Video
</button>
幻灯片预览画廊
在桌面上,我们添加了类似胶片的幻灯片预览。 每种产品颜色都有其自己的图像库和幻灯片预览。 我们使用 amp-bind 来更新页面,以选择与所选颜色对应的画廊和图像预览。 我们通过使用 amp-selector
实现了颜色选择。 在下面的“产品页面”部分中查找更多文档和信息。
绿色是页面加载时画廊的默认颜色。 点击预览图像将通过点击操作 on="tap:AMP.setState({product: {selectedSlideForGreen: 0}})"
在画廊中显示图像。
请参阅下文,了解更多关于我们如何使用 amp-bind
的信息。
<div class="product-gallery">
<ul [hidden]="product.selectedColor != 'green'">
<li>
<amp-img on="tap:AMP.setState({product: {selectedSlideForGreen: 0}})"
src="/static/samples/img/green_apple_1_60x40.jpg"
width="60" height="40"
class="selected"
[class]="product.selectedSlideForGreen == 0 ? 'selected' : '' "
tabindex="0" role="button">
</amp-img>
</li>
<li>
<amp-img on="tap:AMP.setState({product: {selectedSlideForGreen: 1}})"
src="/static/samples/img/green_apple_2_60x40.jpg"
width="60" height="40"
[class]="product.selectedSlideForGreen == 1 ? 'selected' : '' "
tabindex="1" role="button">
</amp-img>
</li>
</ul>
<ul hidden [hidden]="product.selectedColor != 'golden'">
<li>
<amp-img on="tap:AMP.setState({product: {selectedSlideForGolden: 0}})"
src="/static/samples/img/product1_alt1_60x40.jpg"
width="60" height="40"
class="selected fadeIn"
[class]="product.selectedSlideForGolden == 0 ? 'selected fadeIn' : '' "
tabindex="0" role="button">
</amp-img>
</li>
</ul>
<ul hidden [hidden]="product.selectedColor != 'red'">
<li>
<amp-img on="tap:AMP.setState({ product: {selectedSlideForRed : 0}})"
src="/static/samples/static/samples/img/red_apple_1_60x40.jpg"
width="60" height="40"
class="selected fadeIn"
[class]="product.selectedSlideForRed == 0 ? 'selected fadeIn' : '' "
tabindex="0" role="button">
</amp-img>
</li>
<li>
<amp-img on="tap:AMP.setState({ product: {selectedSlideForRed : 1}})"
src="/static/samples/static/samples/img/red_apple_2_60x46.jpg"
width="60" height="40"
[class]="product.selectedSlideForRed == 1 ? 'selected' : '' "
tabindex="1" role="button">
</amp-img>
</li>
</ul>
</div>
图片库
amp-carousel
组件非常适合产品图像库。 了解 amp-carousel
组件的工作原理 在此处。
请注意,我们如何通过使用变量 selectedSlideForGreen
和 selectedColor
的值绑定到 slide
和 class
。
<div class="product-gallery">
<amp-carousel id="green-apple-carousel"
width="1024" height="682"
layout="responsive"
type="slides"
[slide]="product.selectedSlideForGreen"
on="slideChange: AMP.setState({product: {selectedSlideForGreen: event.index}})"
class="fadeIn"
[hidden]="product.selectedColor != 'green'">
<amp-img src="/static/samples/img/green_apple_1_1024x682.jpg"
width="1024" height="682"
layout="responsive" on="tap:gallery-lightbox"
role="button" tabindex="0">
</amp-img>
<amp-img src="/static/samples/img/green_apple_2_1024x685.jpg"
width="1024" height="682"
layout="responsive" on="tap:gallery-lightbox"
role="button" tabindex="0">
</amp-img>
</amp-carousel>
<amp-carousel id="golden-apple-carousel"
width="1024" height="682"
layout="responsive"
type="slides"
[slide]="product.selectedSlideForGolden"
on="slideChange: AMP.setState({product: {selectedSlideForGolden: event.index}})"
hidden
class="fadeIn"
[hidden]="product.selectedColor != 'golden'">
<amp-img src="/static/samples/img/golden_apple1_1024x682.jpg"
width="1024" height="682"
layout="responsive" on="tap:gallery-lightbox"
role="button" tabindex="0">
</amp-img>
</amp-carousel>
<amp-carousel id="red-apple-carousel"
width="1024" height="682"
layout="responsive"
type="slides"
[slide]="product.selectedSlideForRed"
on="slideChange: AMP.setState({product: {selectedSlideForRed: event.index}})"
hidden
class="fadeIn"
[hidden]="product.selectedColor != 'red'">
<amp-img src="/static/samples/img/red_apple_1_1024x682.jpg"
width="1024" height="682"
layout="responsive" on="tap:gallery-lightbox"
role="button" tabindex="0">
</amp-img>
<amp-img src="/static/samples/img/red_apple_2_1024x793.jpg"
width="1024" height="682"
layout="responsive" on="tap:gallery-lightbox"
role="button" tabindex="0">
</amp-img>
</amp-carousel>
</div>
全屏图像
使用 amp-image-lightbox
组件,用户可以展开图像以填充视口。 通过点击产品图库中的每个图像,用户可以使用全屏查看产品图像。 在此处了解更多信息
<amp-image-lightbox id="gallery-lightbox" layout="nodisplay">
<div on="tap:gallery-lightbox.close" role="button"
tabindex="0">
<button class="ampstart-btn caps m2 close-gallery-button" on="tap:gallery-lightbox.close"
role="button" tabindex="0">
Close
</button>
</div>
</amp-image-lightbox>
产品配置
我们使用 amp-state
组件(amp-bind 的一部分)
来根据颜色和尺寸配置产品价格。 我们还配置了 defaultSize
以便在您在颜色之间切换时,如果先前选择的尺寸不适用于新颜色,则配置每个产品的尺寸
<amp-state id="product">
<script type="application/json">
{
"selectedColor": "green",
"selectedSize": "S",
"selectedSlideForRed": 0,
"selectedSlideForGolden": 0,
"selectedSlideForGreen": 0,
"moreItemsPageIndex": 0,
"hasMorePages": true,
"green": {
"id": "1",
"sizes": {
"S": "$5.99",
"M": "$5.99",
"L": "unavailable"
},
"defaultSize": "S"
},
"golden": {
"id": "2",
"sizes": {
"S": "$9.99",
"M": "unavailable",
"L": "$9.99"
},
"defaultSize": "L"
},
"red": {
"id": "3",
"sizes": {
"S": "$7.99",
"M": "$7.99",
"L": "$7.99"
},
"defaultSize": "M"
}
}
</script>
</amp-state>
产品价格
我们使用 amp-bind 来更新产品价格
具体取决于所选颜色。
我们将 text
属性绑定到表达式 product[product.selectedColor].sizes[product.selectedSize]
的值。 product
是“产品配置”部分中描述的 amp-state
json 的 id。
请注意,我们如何将 $1.99 值设置为默认价格:表达式不会在页面加载时进行评估。
我们使用 amp-selector
和 amp-bind
来更新页面,以显示价格、尺寸可用性、图库和图像预览。 每次您选择颜色时,我们都会使用 {selectedColor: event.targetOption}
调用 AMP.setState
。 这会触发所有绑定到 selectedColor
的属性和元素进行更新:价格(绑定到属性 [text]
)、图库、图像预览和尺寸选择器(均绑定到 [class]
)。
价格:$5.99
<p class="price-description">Price:
<span [text]="product[product.selectedColor].sizes[product.selectedSize]">$5.99</span>
</p>
产品页面
使用 amp-form 实现添加到购物车操作。 在我们的示例中,我们使用 amp-selector 来选择不同的产品属性。 按下 ADD TO CART
按钮会将产品添加到购物车页面,并使用您选择的属性。 请注意,该按钮 URL 包含查询 clientId={{ClientId}}
。 如果商品已成功添加到购物车,我们将用户重定向到购物车页面。 重定向目标通过服务器表单响应中的标头进行配置(提交后重定向)
access-control-expose-headers:AMP-Access-Control-Allow-Source-Origin,AMP-Redirect-To amp-redirect-to:http://ampbyexample.com/shopping_cart/?clientid=amp-123456789
我们使用 CLIENT_ID
变量来识别用户,这使得可以在重复访问 AMP 页面(通过 AMP 缓存或原始主机)时存储购物车。 通过使用 default-value="CLIENT_ID(cart)
声明隐藏的输入值,可以在 amp-form 内使用此变量。 在此处详细了解变量替换。
<form id="order" method="POST"
action-xhr="/documentation/examples/e-commerce/shopping_cart/add-to-cart"
target="_top" class="flex flex-wrap m1">
<div class="items-center flex">
<label for="color">Color:</label>
<amp-selector name="color"
layout="container"
[selected]="product.selectedColor"
on="select:AMP.setState({
product: {
selectedColor: event.targetOption,
selectedSlideForRed: 0,
selectedSlideForGreen: 0,
selectedSlideForYellow: 0,
selectedSize: product[event.targetOption].sizes[product.selectedSize] != 'unavailable' ? product.selectedSize : product[event.targetOption].defaultSize
}
})">
<ul class="p0 m1">
<li>
<div option="green" selected class="square green"></div>
</li>
<li>
<div option="golden" class="square golden"></div>
</li>
<li>
<div option="red" class="square red"></div>
</li>
</ul>
</amp-selector>
</div>
<div class="items-center flex">
<label for="quantity">Quantity:</label>
<amp-selector name="quantity" layout="container">
<ul class="p0 m1">
<li option="1" selected>1</li>
<li option="2">2</li>
<li option="3">3</li>
</ul>
</amp-selector>
</div>
<div class="items-center flex">
<label for="size">Size:</label>
<amp-selector name="size" layout="container"
on="select:AMP.setState({ product: {selectedSize: event.targetOption}})"
[selected]="(product[product.selectedColor].sizes[product.selectedSize] != 'unavailable')
? product.selectedSize
: product[product.selectedColor].defaultSize">
<ul class="p0 m1">
<li option="S" class=""
[class]="(product[product.selectedColor].sizes['S'] != 'unavailable')
? ''
: 'unavailable'">S</li>
<li option="M" class="" selected
[class]="(product[product.selectedColor].sizes['M'] != 'unavailable')
? ''
: 'unavailable'">M</li>
<li option="L" class="unavailable"
[class]="(product[product.selectedColor].sizes['L'] != 'unavailable')
? ''
: 'unavailable'">L</li>
</ul>
</amp-selector>
</div>
<div class="items-center flex my1">
<input type="submit" class="ampstart-btn caps" name="add-to-cart" value="add to cart">
</div>
<input type="hidden" name="name" value="Apple">
<input type="hidden" name="price" value="$1.99" [value]="product[product.selectedColor].sizes[product.selectedSize]">
<input type="hidden" name="id" value="1" [value]="product[product.selectedColor].id">
<input name="clientId" type="hidden" value="CLIENT_ID(cart)" data-amp-replace="CLIENT_ID">
<div submit-error>
<template type="amp-mustache">
Error! Looks like something went wrong with your shopping cart, please try to add an item again. {{error}}
</template>
</div>
</form>
标签面板
使用样式设置为标签面板的 amp-selector
来添加关于您的产品的其他数据。 了解如何在 AMP 中实现标签 在此处。
<amp-selector role="tablist"
layout="container"
class="ampTabContainer ampstart-headerbar-nav" keyboard-select-mode="select">
<div role="tab"
class="tabButton h4 ampstart-nav-item"
selected
option="a">ABOUT</div>
<div role="tabpanel"
class="tabContent p1 p">Fruit is rich in vitamins and minerals. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
<div role="tab"
class="tabButton h4 ampstart-nav-item"
option="b">SPECS</div>
<div role="tabpanel"
class="tabContent p1 p">Always wash fruit before eating. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div role="tab"
class="tabButton h4 ampstart-nav-item"
option="c">SIZE</div>
<div role="tabpanel"
class="tabContent p1 p">Size may vary. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
</amp-selector>
动态相关产品列表
使用 AMP,您可以轻松地提取不同的最新优惠或亮点,而无需更改页面。 为此,只需使用 amp-list
向 JSON 端点触发 CORS 请求,该端点会提供相关产品列表。 这些产品将填充到客户端的 amp-mustache 模板中。 在 此处了解更多关于 amp-list
的信息。
<amp-list class="items m1"
width="auto"
height="145"
layout="fixed-height"
src="/static/samples/json/related_products.json"
[src]="myState.items"
binding="no"
id="show-more-list">
<template type="amp-mustache">
<a class="text-decoration-none p1"
href="/documentation/examples/e-commerce/product_page/preview/">
<amp-img width="70.31"
height="46.8"
layout="fixed"
alt="{{name}}"
src="{{img}}"></amp-img>
<p class="name">{{name}}</p>
<p class="star">{{{stars}}}</p>
<p class="price">${{price}}</p>
</a>
</template>
</amp-list>
虽然目前 AMP 中无法实现无限滚动,但您可以使用 amp-bind
动态更改 amp-list
的 src,并向页面添加更多项目。我们将 src
属性绑定到 amp-state
组件的 id,以便 amp-list
将该组件中的项目用作 src
。 amp-state
的初始值通过将 src
值设置为与 amp-list
使用的端点相同的值来设置。 每次用户单击“显示更多”按钮时,我们都会将项目附加到 amp-state
,有关更多信息,请参见下文。
<amp-state id="myState" src="/static/samples/json/related_products.json">
</amp-state>
您可以使用 amp-form
和 submit-success
事件来显示或隐藏“显示更多”按钮:请注意我们如何根据服务器响应将 hasMorePages
变量设置为 false。
<form method="GET"
action="/documentation/examples/api/json/more_related_products_page"
action-xhr="/documentation/examples/api/json/more_related_products_page"
target="_top"
on="submit-success: AMP.setState({
myState: { items: myState.items.concat(event.response.items)},
product: {moreItemsPageIndex: product.moreItemsPageIndex + 1,
hasMorePages: event.response.hasMorePages}
});">
<input type="hidden" name="moreItemsPageIndex" value="0" [value]="product.moreItemsPageIndex">
<input type="submit" value="Show more"
class="ampstart-btn caps m1 mb3"
[hidden] = "!product.hasMorePages">
</form>
用户分析
分析必须在 body 中配置。 在这里,我们使用 Google Analytics 来跟踪页面浏览量。
<amp-analytics type="googleanalytics">
<script type="application/json">
{
"vars": {
"account": "UA-73836974-1"
},
"triggers": {
"default pageview": {
"on": "visible",
"request": "pageview",
"vars": {
"title": "Product"
}
}
}
}
</script>
</amp-analytics>
如果此页面上的解释未能涵盖您的所有问题,请随时与其他 AMP 用户联系,讨论您的具体用例。
前往 Stack Overflow 未解释的功能?AMP 项目强烈鼓励您的参与和贡献!我们希望您能成为我们开源社区的持续参与者,但我们也欢迎您对您特别感兴趣的问题进行一次性贡献。
在 GitHub 上编辑示例-
作者: @aghassemi