将 Google AMP(加速移动页面)应用于 ASP.NET Core 站点 [英] Apply Google AMP (Accelerated Mobile Pages) to ASP.NET Core site

查看:19
本文介绍了将 Google AMP(加速移动页面)应用于 ASP.NET Core 站点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ASPNET Core MVC 创建一个 AMP 页面.我找不到很多文件(如果有的话).对于 ASPNET,建议使用 DisplayModes 来创建 Google AMP 显示.但是,ASPNet Core 不支持 DisplayModes,我正试图找到一种方法来解决它.任何建议将不胜感激!

@model Models.Article@{布局 = 空;}<!doctype html><html ><头><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}到{visibility:visible}}</style><noscript><风格放大器样板>身体 {-webkit-animation:无;-moz-动画:无;-ms-动画:无;动画:无}</style></noscript><script async src="https://cdn.ampproject.org/v0.js"></script><身体><文章><h2>@Html.DisplayFor(model =>model.Title)</h2><div>@Convert.ToDateTime(Model.PublishedDate).ToString("dddd, MMMM d, yyyy")

</文章>

解决方案

有几种方法可以实现这样的目标.一种可能性是根据路线动态更改您的布局,即使用模板 X 表示 AMP,否则使用 Y 模板.

更强大的解决方案是视图位置扩展器.这通常也被认为是显示模式的继承者.视图位置扩展器基本上是一种机制,允许您对 Razor 引擎将在其中查找视图的物理位置进行后处理.因此,您可以使用它来有条件地修改或扩展您的视图所在的路径.

在您的情况下,您可能希望更改行为,以便在通过 AMP 访问您的网站时,Razor 应首先查找 <view>.amp.cshtml,然后再回退到 .cshtml.

为了做到这一点,您必须实施 IViewLocationExpander.在 PopulateViews 您必须检测您是否处于 AMP 模式;并在 ExpandViewLocations然后您可以修改视图位置.

这看起来有点像这样(未经测试,作为关于如何解决这个问题的想法):

公共类 AmpViewLocationExpander : IViewLocationExpander{private const string ValueKey = "ampmode";public void PopulateValues(ViewLocationExpanderContext 上下文){//确定这是否在 AMP 上下文中的魔术实用程序方法var isAmp = context.ActionContext.HttpContext.IsAmp();//将值保留在上下文中以允许缓存考虑这一点context.Values[ValueKey] = isAmp.ToString();}公共 IEnumerableExpandViewLocations(ViewLocationExpanderContext 上下文,IEnumerable查看位置){//当处于 AMP 模式时if (context.Values.TryGetValue(ValueKey, out var isAmpValue) && isAmpValue == "True"){返回 ExpandAmpViewLocations(viewLocations);}//否则回退到默认位置返回视图位置;}私有 IEnumerableExpandAmpViewLocations(IEnumerable viewLocations){foreach(viewLocations 中的 var 位置){//首先产生 AMP 版本yield return location.Replace("{0}", "{0}.amp");//然后将普通版本作为后备收益率返回位置;}}}

一旦你有了它,你只需要在你的 ConfigureServices 中的 AddMvc 调用之后注册扩展器:

services.AddMvc().AddRazorOptions(options =>{options.ViewLocationExpanders.Add(new AmpViewLocationExpander());});

然后您只需为 AMP 创建备用视图.

I'm trying to create an AMP page with ASPNET Core MVC. I haven't been able to find many documents if any. For ASPNET, it was suggested to use DisplayModes to create a Google AMP Display. However, ASPNet Core doesn't support DisplayModes and I'm trying to figure a way to work around it. Any suggestions would be greatly appreciated!

@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>

解决方案

There are a few ways to achieve something like this. One possibility would be to dynamically change your layout depending on the route, i.e. use template X for AMP or Y otherwise.

A more powerful solution would be the view location expander. This is also generally considered as a successor to the display modes. The view location expander is basically a mechanism that allows you to post-process the physical locations where the Razor engine will look for views. So you can use this to conditionally modify or expand the paths where your views are located.

In your case, you might want to change the behavior so that when accessing your site through AMP, Razor should first look for a <view>.amp.cshtml before falling back to <view>.cshtml.

In order to do that, you would have to implement IViewLocationExpander. In PopulateViews you would have to detect whether you are within AMP mode or not; and in ExpandViewLocations you could then modify the view locations.

That could look somewhat like this (untested, as an idea on how to approach this):

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;
        }
    }
}

Once you have that, you only have to register the expander after the AddMvc call within your ConfigureServices:

services.AddMvc()
    .AddRazorOptions(options =>
    {
        options.ViewLocationExpanders.Add(new AmpViewLocationExpander());
    });

And then you only need to create your alternate views for AMP.

这篇关于将 Google AMP(加速移动页面)应用于 ASP.NET Core 站点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆