Open In App

How to add AMP to Django Project?

Last Updated : 17 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

A blog mostly needs content but that doesn’t mean, your blog will be on top of Google search. For this you will need Speed, Security, user base and first of all search engines need to know that your blog exists. We will add AMP for speed.  This article is in continuation of Blog CMS Project in Django. Check this out here – Building Blog CMS (Content Management System) with Django

AMP

AMP (Accelerated Mobile Pages) is an open-source HTML framework developed by the AMP Open Source Project. It was originally created by Google as a competitor to Facebook Instant Articles and Apple News. AMP is optimized for mobile web browsing and intended to help webpages load faster.  They are limited in JavaScript.

Creating AMP template – 

We will create an app template in our blog templates folder and save it with .amp.html extension

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>


Handling Images in AMP –

As AMP are limited even with images and we use same images for both the amp and non-amp pages to overcome these, we will create another file which will help us alter images for amp when needed. Go to blog app directory and create templatetags directory. In templatetags directory create an empty __init__.py file. Paste below code in ampimg.py file and we are done

Python3




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


Creating Views For AMP –

Now go to your app views.py file and add the following template

Python3




# 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"


Add routes for amp

Now we will route our AMP page so that it is accessible, go to urls.py file of your app and add the route

Python3




urlpatterns = [
  .....
# amp route
    path('amp/<slug:slug>/', views.postdetailamp.as_view(), name ='post_detail_amp'),
  .....
]


Sample AMP post page

Sample post page

An extendable menu

An extensible side menu

Sample Mobile page

Sample Mobile Page

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads