Skip to content
Related Articles

Related Articles

Improve Article

How to add AMP to Django Project?

  • Last Updated : 17 Jun, 2021

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

 

 Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.  

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning – Basic Level Course




My Personal Notes arrow_drop_up
Recommended Articles
Page :