c# - 将 Google AMP(加速移动页面)应用到 ASP.NET Core 站点
问题描述
我正在尝试使用 ASPNET Core MVC 创建一个 AMP 页面。如果有的话,我找不到很多文件。对于 ASPNET,建议使用DisplayModes
创建 Google AMP Display。但是,ASPNet Core 不支持DisplayModes
,我正在尝试想办法解决它。任何建议将不胜感激!
@model Models.Article
@{
Layout = null;
}
<!doctype html>
<html amp>
<head>
<meta charset="utf-8">
<link rel="canonical" href="/article.cshtml">
<link rel="amphtml" href="/article.amp.cshtml">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<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>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
<article>
<h2>@Html.DisplayFor(model => model.Title)</h2>
<div>@Convert.ToDateTime(Model.PublishedDate).ToString("dddd, MMMM d, yyyy")</div>
</article>
</body>
</html>
解决方案
有几种方法可以实现这样的目标。一种可能性是根据路线动态更改布局,即对 AMP 使用模板 X,否则使用 Y。
更强大的解决方案是视图位置扩展器。这通常也被认为是显示模式的继承者。视图位置扩展器基本上是一种机制,允许您对 Razor 引擎查找视图的物理位置进行后处理。因此,您可以使用它来有条件地修改或扩展视图所在的路径。
在您的情况下,您可能希望更改行为,以便在通过 AMP 访问您的网站时,Razor 应首先查找 a <view>.amp.cshtml
,然后再返回<view>.cshtml
.
为此,您必须实施IViewLocationExpander
. 在PopulateViews
您必须检测您是否处于 AMP 模式下;然后ExpandViewLocations
您可以修改视图位置。
这可能看起来有点像这样(未经测试,作为如何解决这个问题的想法):
public class AmpViewLocationExpander : IViewLocationExpander
{
private const string ValueKey = "ampmode";
public void PopulateValues(ViewLocationExpanderContext context)
{
// magic utility method that determines whether this is within an AMP context
var isAmp = context.ActionContext.HttpContext.IsAmp();
// persist the value on the context to allow the cache to consider this
context.Values[ValueKey] = isAmp.ToString();
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
// when in AMP mode
if (context.Values.TryGetValue(ValueKey, out var isAmpValue) && isAmpValue == "True")
{
return ExpandAmpViewLocations(viewLocations);
}
// otherwise fall back to default locations
return viewLocations;
}
private IEnumerable<string> ExpandAmpViewLocations(IEnumerable<string> viewLocations)
{
foreach (var location in viewLocations)
{
// yield the AMP version first
yield return location.Replace("{0}", "{0}.amp");
// then yield the normal version as a fallback
yield return location;
}
}
}
一旦你有了它,你只需要AddMvc
在你的调用之后注册扩展器ConfigureServices
:
services.AddMvc()
.AddRazorOptions(options =>
{
options.ViewLocationExpanders.Add(new AmpViewLocationExpander());
});
然后您只需为 AMP 创建备用视图。
推荐阅读
- scala - 为什么找不到火花参考?
- groovy - 如何使测试用例失败 - 带有 Groovy 的 Cucumber
- wordpress - 在哪里编辑注册表错误消息?
- php - 如何从php数组中计算相同的值
- javascript - 我想在静态方法中访问我的类的属性,我该怎么办?可能吗?
- python-3.x - Python 线程“TypeError:_testmethod() 采用 2 个位置参数,但给出了 12 个”
- java - “java.io.StreamCorruptedException:无效的流标头:3C3F786D”,同时尝试在主报告中合并多个子报告
- javascript - 使用选择框启用按钮
- java - 替换过大的复合键
- android - 当 bottomSheet 最小化和最大化时移动谷歌徽标