amp
This commit is contained in:
@@ -66,7 +66,19 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
this.StatusCode(404);
|
||||
return View(nameof(FourOhFour));
|
||||
}
|
||||
return View(model: currentPost);
|
||||
return View("Post", model: new PostViewModel() { Post = currentPost, IsAmp = false });
|
||||
}
|
||||
[Route("{postUrl}/amp")]
|
||||
[OutputCache(Duration = 31536000, VaryByParam = "postUrl")]
|
||||
[ResponseCache(Duration = 900)]
|
||||
public IActionResult PostAmp(string postUrl)
|
||||
{
|
||||
if(!postCache.UrlToPost.TryGetValue(postUrl, out var currentPost))
|
||||
{
|
||||
this.StatusCode(404);
|
||||
return View(nameof(FourOhFour));
|
||||
}
|
||||
return View("Post", model: new PostViewModel() { Post = currentPost, IsAmp = true });
|
||||
}
|
||||
[Route("/Error")]
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace TerribleDev.Blog.Web.Controllers
|
||||
Urls = postCache.PostsAsLists.Select(a => new SiteMapItem() { LastModified = DateTime.UtcNow, Location = a.CanonicalUrl }).ToList()
|
||||
};
|
||||
sitemap.Urls.AddRange(sitewideLinks);
|
||||
sitemap.Urls.AddRange(postCache.PostsAsLists.Select(a => new SiteMapItem() { LastModified = DateTime.UtcNow, Location = a.AMPUrl }).ToList());
|
||||
ser.Serialize(this.Response.Body, sitemap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Concurrent;
|
||||
using Schema.NET;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TerribleDev.Blog.Web
|
||||
{
|
||||
@@ -69,6 +70,7 @@ namespace TerribleDev.Blog.Web
|
||||
var postSettings = ParseYaml(ymlRaw);
|
||||
var resolvedUrl = !string.IsNullOrWhiteSpace(postSettings.permalink) ? postSettings.permalink : fileName.Split('.')[0].Replace(' ', '-').WithoutSpecialCharacters();
|
||||
var canonicalUrl = $"https://blog.terrible.dev/{resolvedUrl}/";
|
||||
var ampUrl = $"https://blog.terrible.dev/{resolvedUrl}/amp/";
|
||||
return new Post()
|
||||
{
|
||||
PublishDate = postSettings.date.ToUniversalTime(),
|
||||
@@ -77,6 +79,7 @@ namespace TerribleDev.Blog.Web
|
||||
Title = postSettings.title,
|
||||
RelativeUrl = $"/{resolvedUrl}/",
|
||||
CanonicalUrl = canonicalUrl,
|
||||
AMPUrl = ampUrl,
|
||||
UrlWithoutPath = resolvedUrl,
|
||||
Content = new Lazy<IPostContent>(() =>
|
||||
{
|
||||
@@ -107,8 +110,12 @@ namespace TerribleDev.Blog.Web
|
||||
},
|
||||
},
|
||||
};
|
||||
// regex remove picture and source tags
|
||||
var regex = new Regex(@"<source[^>]*>|</source>|<picture[^>]*>|</picture>", RegexOptions.IgnoreCase);
|
||||
var ampContent = regex.Replace(postContent, "");
|
||||
return new PostContent()
|
||||
{
|
||||
AmpContent = new HtmlString(ampContent),
|
||||
Content = new HtmlString(postContent),
|
||||
Images = postImages,
|
||||
ContentPlain = postContentPlain,
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
{
|
||||
public interface IPost
|
||||
{
|
||||
string AMPUrl { get; set; }
|
||||
string CanonicalUrl { get; set; }
|
||||
string UrlWithoutPath { get; set; }
|
||||
string RelativeUrl { get; set; }
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
{
|
||||
public interface IPostContent
|
||||
{
|
||||
public HtmlString AmpContent { get; set; }
|
||||
HtmlString Content { get; set; }
|
||||
HtmlString Summary { get; set; }
|
||||
string ContentPlain { get; set; }
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
[DebuggerDisplay("{Title}")]
|
||||
public class Post : IPost
|
||||
{
|
||||
public string AMPUrl { get; set; }
|
||||
public string CanonicalUrl { get; set; }
|
||||
public string UrlWithoutPath { get; set; }
|
||||
public string RelativeUrl { get; set; }
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace TerribleDev.Blog.Web.Models
|
||||
|
||||
public class PostContent : IPostContent
|
||||
{
|
||||
public HtmlString AmpContent { get; set; }
|
||||
public HtmlString Content { get; set; }
|
||||
public HtmlString Summary { get; set; }
|
||||
public string ContentPlain { get; set; }
|
||||
|
||||
9
src/TerribleDev.Blog.Web/Models/PostViewModel.cs
Normal file
9
src/TerribleDev.Blog.Web/Models/PostViewModel.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace TerribleDev.Blog.Web.Models
|
||||
{
|
||||
public class PostViewModel
|
||||
{
|
||||
public IPost Post { get; set; }
|
||||
public bool IsAmp { get; set; } = false;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,9 @@ using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
@@ -29,25 +31,29 @@ namespace TerribleDev.Blog.Web.Taghelpers
|
||||
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
var path = Href;
|
||||
var paths = Href.Split(',');
|
||||
|
||||
// Get the value from the cache, or compute the value and add it to the cache
|
||||
var fileContent = await Cache.GetOrCreateAsync("InlineStyleTagHelper-" + path, async entry =>
|
||||
var fileContent = await Cache.GetOrCreateAsync("InlineStyleTagHelper-" + paths, async entry =>
|
||||
{
|
||||
var fileProvider = HostingEnvironment.WebRootFileProvider;
|
||||
if(HostingEnvironment.IsDevelopment())
|
||||
{
|
||||
var changeToken = fileProvider.Watch(path);
|
||||
entry.AddExpirationToken(changeToken);
|
||||
}
|
||||
var result = paths.Select(async path => {
|
||||
if(HostingEnvironment.IsDevelopment())
|
||||
{
|
||||
var changeToken = fileProvider.Watch(path);
|
||||
entry.AddExpirationToken(changeToken);
|
||||
}
|
||||
|
||||
entry.SetPriority(CacheItemPriority.NeverRemove);
|
||||
entry.SetPriority(CacheItemPriority.NeverRemove);
|
||||
|
||||
var file = fileProvider.GetFileInfo(path);
|
||||
if (file == null || !file.Exists)
|
||||
return null;
|
||||
var file = fileProvider.GetFileInfo(path);
|
||||
if (file == null || !file.Exists)
|
||||
return null;
|
||||
|
||||
return await ReadFileContent(file);
|
||||
return await ReadFileContent(file);
|
||||
});
|
||||
var allFinished = await Task.WhenAll(result);
|
||||
return string.Join("\n", allFinished);
|
||||
});
|
||||
|
||||
if (fileContent == null)
|
||||
|
||||
79
src/TerribleDev.Blog.Web/Taghelpers/InlineJS.cs
Normal file
79
src/TerribleDev.Blog.Web/Taghelpers/InlineJS.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TerribleDev.Blog.Web.Taghelpers
|
||||
{
|
||||
[HtmlTargetElement("inline-script")]
|
||||
public class InlineScriptTagHelper : TagHelper
|
||||
{
|
||||
[HtmlAttributeName("src")]
|
||||
public string Src { get; set; }
|
||||
|
||||
private IWebHostEnvironment HostingEnvironment { get; }
|
||||
private IMemoryCache Cache { get; }
|
||||
|
||||
|
||||
|
||||
public InlineScriptTagHelper(IWebHostEnvironment hostingEnvironment, IMemoryCache cache)
|
||||
{
|
||||
HostingEnvironment = hostingEnvironment;
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
var paths = Src.Split(',');
|
||||
|
||||
// Get the value from the cache, or compute the value and add it to the cache
|
||||
var fileContent = await Cache.GetOrCreateAsync("InlineScriptTagHelper-" + paths, async entry =>
|
||||
{
|
||||
var fileProvider = HostingEnvironment.WebRootFileProvider;
|
||||
var result = paths.Select(async path => {
|
||||
if(HostingEnvironment.IsDevelopment())
|
||||
{
|
||||
var changeToken = fileProvider.Watch(path);
|
||||
entry.AddExpirationToken(changeToken);
|
||||
}
|
||||
|
||||
entry.SetPriority(CacheItemPriority.NeverRemove);
|
||||
|
||||
var file = fileProvider.GetFileInfo(path);
|
||||
if (file == null || !file.Exists)
|
||||
return null;
|
||||
|
||||
return await ReadFileContent(file);
|
||||
});
|
||||
var allFinished = await Task.WhenAll(result);
|
||||
return string.Join("\n", allFinished);
|
||||
});
|
||||
|
||||
if (fileContent == null)
|
||||
{
|
||||
output.SuppressOutput();
|
||||
return;
|
||||
}
|
||||
|
||||
output.TagName = "script";
|
||||
output.Attributes.RemoveAll("href");
|
||||
output.Content.AppendHtml(fileContent);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadFileContent(IFileInfo file)
|
||||
{
|
||||
using (var stream = file.CreateReadStream())
|
||||
using (var textReader = new StreamReader(stream))
|
||||
{
|
||||
return await textReader.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,43 @@
|
||||
@inject BlogConfiguration config
|
||||
@model IPost
|
||||
@model PostViewModel
|
||||
@{
|
||||
ViewData["Title"] = @Model.Title;
|
||||
ViewData["Title"] = Model.Post.Title;
|
||||
ViewData["amp"] = Model.IsAmp;
|
||||
}
|
||||
|
||||
<cache vary-by-route="postUrl">
|
||||
@Html.DisplayForModel()
|
||||
@Html.DisplayFor(m => m.Post, "Post")
|
||||
</cache>
|
||||
|
||||
@section Head {
|
||||
<meta name="description" content="@Model.Content.Value.SummaryPlainShort" />
|
||||
<meta name="description" content="@Model.Post.Content.Value.SummaryPlainShort" />
|
||||
<meta property="og:type" content="blog">
|
||||
<meta property="og:title" content="@Model.Title">
|
||||
<meta property="og:url" content="@Model.CanonicalUrl">
|
||||
<meta property="og:title" content="@Model.Post.Title">
|
||||
<meta property="og:url" content="@Model.Post.CanonicalUrl">
|
||||
<meta property="og:site_name" content="@config.Title">
|
||||
<meta property="og:description" content="@Model.Content.Value.SummaryPlainShort">
|
||||
<meta property="og:updated_time" content="@Model.PublishDate.ToString("O")">
|
||||
<meta property="og:description" content="@Model.Post.Content.Value.SummaryPlainShort">
|
||||
<meta property="og:updated_time" content="@Model.Post.PublishDate.ToString("O")">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="@Model.Title">
|
||||
<meta name="twitter:description" content="@Model.Content.Value.SummaryPlainShort">
|
||||
<meta name="twitter:title" content="@Model.Post.Title">
|
||||
<meta name="twitter:description" content="@Model.Post.Content.Value.SummaryPlainShort">
|
||||
<meta name="twitter:site" content="@@TerribleDev">
|
||||
<meta name="twitter:creator" content="@@TerribleDev">
|
||||
<link rel="canonical" href="@Model.CanonicalUrl" />
|
||||
@foreach(var image in Model.Content.Value.Images.Take(6))
|
||||
<link rel="canonical" href="@Model.Post.CanonicalUrl" />
|
||||
<link rel="amphtml" href="@Model.Post.AMPUrl">
|
||||
@foreach(var image in Model.Post.Content.Value.Images.Take(6))
|
||||
{
|
||||
<meta property="og:image" content="@image">
|
||||
}
|
||||
@if(Model.Content.Value.Images.Count > 0)
|
||||
@if(Model.Post.Content.Value.Images.Count > 0)
|
||||
{
|
||||
<meta name="twitter:image" content="@(Model.Content.Value.Images[0])">
|
||||
<meta name="twitter:image" content="@(Model.Post.Content.Value.Images[0])">
|
||||
}
|
||||
<meta property="og:image" content="https://www.gravatar.com/avatar/333e3cea32cd17ff2007d131df336061?s=640" />
|
||||
<script type="application/ld+json">
|
||||
@Html.Raw(Model.Content.Value.JsonLDString)
|
||||
@Html.Raw(Model.Post.Content.Value.JsonLDString)
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
@Html.Raw(Model.Content.Value.JsonLDBreadcrumbString)
|
||||
@Html.Raw(Model.Post.Content.Value.JsonLDBreadcrumbString)
|
||||
</script>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
@model IPost
|
||||
|
||||
@{
|
||||
var amp = ViewData["amp"] as bool? ?? false;
|
||||
}
|
||||
<article itemprop="blogPost">
|
||||
<h1 itemprop="headline" class="headline">@Model.Title</h1>
|
||||
<time class="headlineSubtext" itemprop="datePublished" content="@Model.PublishDate.ToString()">@Model.PublishDate.ToString("D")</time>
|
||||
@Model.Content.Value.Content
|
||||
@if(amp)
|
||||
{
|
||||
@Model.Content.Value.AmpContent
|
||||
}
|
||||
else
|
||||
{
|
||||
@Model.Content.Value.Content
|
||||
}
|
||||
@if (Model.tags.Count > 0)
|
||||
{
|
||||
<div>
|
||||
|
||||
@@ -1,17 +1,36 @@
|
||||
|
||||
@{
|
||||
Layout = null;
|
||||
var amp = ViewData["amp"] as bool? ?? false;
|
||||
}
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() { dataLayer.push(arguments); }
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-48128396-1');
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var script = document.createElement('script');
|
||||
script.src = 'https://www.googletagmanager.com/gtag/js?id=UA-48128396-1';
|
||||
script.async = true
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
</script>
|
||||
|
||||
@if(amp)
|
||||
{
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() { dataLayer.push(arguments); }
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-48128396-1');
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var script = document.createElement('script');
|
||||
script.src = 'https://www.googletagmanager.com/gtag/js?id=UA-48128396-1';
|
||||
script.async = true
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
</script>
|
||||
}
|
||||
else
|
||||
{
|
||||
<amp-analytics type="gtag" data-credentials="include">
|
||||
<script type="application/json">
|
||||
{
|
||||
"vars" : {
|
||||
"gtag_id": "UA-48128396-1",
|
||||
"config" : {
|
||||
"UA-48128396-1: { "groups": "default" }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</amp-analytics>
|
||||
}
|
||||
@@ -1,9 +1,20 @@
|
||||
<nav class="navBar hide" id="navBar">
|
||||
@{
|
||||
var amp = ViewData["amp"] as bool?;
|
||||
}
|
||||
|
||||
<nav class="navBar hide" id="navBar">
|
||||
<div class="navContent">
|
||||
<picture class="navHero">
|
||||
@if(amp == true)
|
||||
{
|
||||
<img src="/content/tommyAvatar4.jpg" alt="An image of TerribleDev" class="round navHero" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<picture class="navHero">
|
||||
<source srcset="" type="image/webp" alt="An image of TerribleDev" data-src="/content/tommyAvatar4.jpg.webp" class="lazy round" />
|
||||
<img src="" alt="An image of TerribleDev" data-src="/content/tommyAvatar4.jpg" class="lazy round" />
|
||||
</picture>
|
||||
}
|
||||
<span>Tommy "Terrible Dev" Parnell</span>
|
||||
<ul class="sidebarBtns">
|
||||
<li><a href="/" class="link-unstyled">Home</a></li>
|
||||
|
||||
@@ -1,43 +1,67 @@
|
||||
@inject BlogConfiguration config
|
||||
|
||||
@{
|
||||
var amp = ViewData["amp"] as bool? ?? false;
|
||||
var htmlTag = amp ? "amp" : "";
|
||||
var boilerplate = @"<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>";
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" @htmlTag>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<environment names="Production">
|
||||
<partial name="Gtm" />
|
||||
</environment>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="author" content="Tommy "TerribleDev" Parnell" />
|
||||
<meta name="theme-color" content="#4A4A4A" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="alternate" type="application/atom+xml" async title="RSS" href="/rss.xml">
|
||||
<link rel="manifest" href="~/manifest.json" async asp-append-version="true">
|
||||
<link asp-append-version="true" rel="icon" async href="~/favicon.ico" />
|
||||
<link rel="alternate" type="application/atom+xml" title="RSS" href="/rss.xml">
|
||||
<link rel="manifest" href="~/manifest.json" asp-append-version="true">
|
||||
<link asp-append-version="true" rel="icon" href="~/favicon.ico" />
|
||||
<title>@ViewData["Title"] - @config.Title</title>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" rel="stylesheet" href="~/css/site.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
|
||||
@if(amp)
|
||||
{
|
||||
@Html.Raw(boilerplate);
|
||||
<inline-style amp-custom href="css/site.css,css/site.desktop.css,css/site.mobile.css"></inline-style>
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" rel="stylesheet" href="~/css/site.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" media="screen and (min-width: 769px)" rel="stylesheet" href="~/css/site.desktop.css" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" media="screen and (min-width: 769px)" rel="stylesheet" href="~/css/site.desktop.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" media="screen and (max-width: 768px)" rel="stylesheet" href="~/css/site.mobile.css" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" media="screen and (max-width: 768px)" rel="stylesheet" href="~/css/site.mobile.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" rel="preload" as="script" href="~/js/swi.js" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" rel="preload" as="script" href="~/js/site.min.js" />
|
||||
</environment>
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" media="screen and (min-width: 769px)" rel="stylesheet" href="~/css/site.desktop.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" media="screen and (max-width: 768px)" rel="stylesheet" href="~/css/site.mobile.css" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" media="screen and (max-width: 768px)" rel="stylesheet" href="~/css/site.mobile.min.css" />
|
||||
</environment>
|
||||
<environment names="Development">
|
||||
<link asp-append-version="true" rel="preload" as="script" href="~/js/swi.js" />
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<link asp-append-version="true" rel="preload" as="script" href="~/js/site.min.js" />
|
||||
</environment>
|
||||
}
|
||||
|
||||
|
||||
@if(amp)
|
||||
{
|
||||
Html.Raw("<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>
|
||||
}
|
||||
@RenderSection("Head", false)
|
||||
</head>
|
||||
<body>
|
||||
@@ -53,12 +77,22 @@
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
@RenderSection("Scripts", required: false)
|
||||
<environment names="Development">
|
||||
<script asp-append-version="true" src="~/js/swi.js" async></script>
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<script asp-append-version="true" src="~/js/site.min.js" async></script>
|
||||
</environment>
|
||||
@if(amp)
|
||||
{
|
||||
<amp-script>
|
||||
<inline-script src="js/swi.js"></inline-script>
|
||||
</amp-script>
|
||||
}
|
||||
else
|
||||
{
|
||||
@RenderSection("Scripts", required: false)
|
||||
<environment names="Development">
|
||||
<script asp-append-version="true" src="~/js/swi.js" async></script>
|
||||
</environment>
|
||||
<environment names="Production">
|
||||
<script asp-append-version="true" src="~/js/site.min.js" async></script>
|
||||
</environment>
|
||||
}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user