如何在Django项目中添加AMP
一个博客主要需要内容,但这并不意味着,你的博客会在谷歌搜索中名列前茅。为此,你将需要速度、安全、用户群,首先搜索引擎需要知道你的博客存在。我们将添加AMP以提高速度。这篇文章是Django中博客内容管理系统项目的延续。请看这里 – 用Django构建博客内容管理系统
AMP
AMP(加速移动页面)是一个开源的HTML框架,由AMP开源项目开发。它最初是由谷歌创建的,作为Facebook即时文章和苹果新闻的竞争者。AMP针对移动网络浏览进行了优化,旨在帮助网页更快加载。它们在JavaScript中是有限的。
创建AMP模板 –
我们将在我们的博客模板文件夹中创建一个应用程序模板,并将其保存为.amp.html扩展名。
{% load ampimg %}
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<title>{{ object.title }}</title>
<meta name="description" content="{{ object.metades}}" />
<meta property="og:title" content="{{ object.title }}">
<meta property="og:site_name" content="GeeksForGeeks">
<meta property="og:url" content="{% url 'post_detail_amp' object.slug %}">
<meta property="og:description" content="{{ object.metades }}">
<meta property="og:type" content="article">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1">
<link rel="preload" as="script" href="https://cdn.ampproject.org/v0.js">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<script async custom-element="amp-auto-ads" src="https://cdn.ampproject.org/v0/amp-auto-ads-0.1.js"></script>
<script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
<style amp-custom>
body { font-family: 'Raleway', sans-serif; }
footer { text-align: center;
height: 29px;
font-size: 1.2em;
}
#banner {
font-size: 1em;
width: 100%;
text-align: center; }
button {
font-size: 17px;
text-decoration: none;
border: none;
border-radius: 29px;}
#amp_page { font-size: 18px; }
.headerbar {
height: 70px;
top: 0;
width: 100%;
display: flex;
align-items: center;
}
.site-name {
font-size:20px;
font-family: monospace;
margin: auto;
}
#banner {
margin-top: 70px;
text-align: center;
}
.hamburger {
padding-left: 25px;
}
.sidebar {
font-size: 29px;
padding: 60px;
margin: 0;
}
.sidebar > li {
list-style: none;
margin-bottom:10px;
}
.sidebar li a {
text-decoration: none;
font-family: sans-serif;
}
.close-sidebar {
font-size: 1.8em;
padding-left: 25px;
}
#storycontent {text-align: center; }
.storyimages { min-width: 100%;
margin: 0 auto; }
</style>
<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 rel="canonical" href="{% url 'post_detail' object.slug %}">
<link rel="manifest" href="/manifest.json">
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Article",
"headline": "{{ object.title }}",
"description": "{{ object.metades }}",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "{% url 'post_detail' object.slug %}"
},
"author": {
"@type": "Person",
"name": "{{ object.author.first_name }} {{ object.author.last_name }}"
},
"publisher": {
"@type": "Organization",
"name": "GeeksForGeeks",
},
"datePublished": "{{ object.created_on }}",
"dateModified": "{{ object.created_on }}",
"mentions": "{{ object.source }}"
}
</script>
</head>
<body>
<header class="headerbar">
<div role="button" on="tap:sidebar1.toggle" tabindex="0" class="hamburger">☰</div>
<div class="site-name">GeeksForGeeks</div>
</header>
<amp-sidebar id="sidebar1" layout="nodisplay" side="left">
<div role="button" aria-label="close sidebar" on="tap:sidebar1.toggle" tabindex="0" class="close-sidebar">✕</div>
<ul class="sidebar">
<li><a href="{% url 'posts' %}">Posts</a></li>
<li><a href="{% url 'feed' %}">RSS</a></li>
</ul></amp-sidebar>
<div class="container text-center" id="banner"><h1>{{ object.title }}</h1></div>
<div class="container"><h3 style="text-align: center;">{{ object.author.first_name }} {{ object.author.last_name }} | {{ object.created_on }}</h3>
<p id="amp_page">For Dark mode and better view on desktop, Go to our <span><a href="{% url 'post_detail' object.slug %}"><button class="btn btn-outline-primary">Desktop page</button></a></span></p>
<p id="storycontent">{{ object.content | ampimg | safe }}</p>
</div>
<footer>© GeeksForGeeks</footer>
</body>
</html>
在AMP中处理图片 –
由于AMP在图片方面的限制,我们在Amp和非Amp页面上使用相同的图片来克服这些问题,我们将创建另一个文件来帮助我们在需要时改变Amp的图片。进入博客应用目录,创建templatetags目录。在templatetags目录下创建一个空的init.py文件。将以下代码粘贴到ampimg.py文件中,我们就完成了
import re
from django import template
register = template.Library()
@register.filter(name ="ampimg")
def ampimg(content):
img_pattern = r'(<img [^>]+>)'
img_tags = re.findall(img_pattern, content)
img_src_pattern = r'src ="([^"]+)"'
for img in img_tags:
try:
img_src = re.findall(img_src_pattern, img)[0]
except Exception as NoImgSrc:
img_src = None
if img_src:
amp_img = "<amp-img class =\"storyimages\" src =\"{0}\" width =\"360\" height =\"320\" layout =\"responsive\" alt =\"storyimage\">".format(img_src)
content = content.replace(img, amp_img)
return content
为AMP创建视图 –
现在到你的应用程序views.py文件中,添加以下模板
# importing models and libraries
from django.shortcuts import render
from .models import posts
from django.views import generic
from django.views.decorators.http import require_GET
from django.http import HttpResponse
# class based view for each post in amp template
class postdetailamp(generic.DetailView):
model = posts
template_name = "page.amp.html"
添加安培的路线
现在,我们将为我们的AMP页面提供路由,以便它可以被访问,进入你的应用程序的urls.py文件并添加路由。
urlpatterns = [
.....
# amp route
path('amp/<slug:slug>/', views.postdetailamp.as_view(), name ='post_detail_amp'),
.....
]
示例AMP帖子页面
样本帖子页面
一个可扩展的菜单
一个可扩展的侧面菜单
样本移动页面