過去に、AMP HTML の Blog テーマを作成しました。
Mezzanine AMP 対応のテーマを作成してみました。 | Monotalk
上記テーマと通常のテーマは、Mezzanine の Device Handling という機能を使ってテーマを切り替えており、URLは 通常テーマ も AMPテーマも同様です。
Device Handling — Mezzanine 4.2.3 documentation
現状の実装だと、以下2点が微妙に思いましたので、Django の AMP 関連 のライブラリを参考に、テーマの振り分け処理を変更してみました。
-
Device Handling 機能が削除される
Device Handling は、新しいバージョンで削除されるようです。
Pagination not rendering (and possibly other inclusion tags) · Issue #1780 · stephenmcd/mezzanine -
同一 URL で、AMP ページと通常ページを保持するのはあまり一般的な作りではなさそう
Google は レスポンシブ ウェブ デザイン を推奨しています。
レスポンシブ ウェブ デザイン | Search | Google Developers
現状、この Blog のテーマの切り替え方は動的な配信に当たります。説明を読む限りはあまりお勧めされていないように感じます。1
動的な配信 | Search | Google Developers
そして、同一 URL で、通常ページと、AMPページを配信している例を見たことがないのでおそらく一般的なやり方ではないのかと思います。2
参考
実装には、以下 StackOverFlow の記事と、djagno-plugin を参考にしました。
* amp html - Accelerated mobile pages in django? - Stack Overflow
-
shtalinberg/django-amp-tools: Accelerated mobile pages (AMP) in django
-
blturner/django-amp: A small toolset for rendering Google AMP pages for Django projects
実装、実施したこと
実装は、ほとんどshtalinberg/django-amp-tools: Accelerated mobile pages (AMP) in django を拝借して作成しました。
django-amp-tools
は クエリストリングにより、ページの振り分けを行いますが、クエリストリングではなく、URLで振り分けを実施したかったので、Middleware の処理を修正しています。
実装すること、実施することをまとめると、以下4点です。
* 通常ページ、AMPページのURLでフラグを設定する、middlewareを作成する。
* middleware で設定したフラグを元に、テンプレートを切り替える loaderを作成する。
* settings.py に作成したmiddlewareを定義する。
* urls.py に、AMP のページをマッピングする。
MiddleWare の作成
- middleware.py
process_request
で、URL に、/amp/
を含む場合は、フラグを設定しています。
from amp_start_blog_post import set_amp_detect class AMPDetectionMiddleware(object): def __init__(self, get_response=None): self.get_response = get_response # One-time configuration and initialization. def __call__(self, request): # Code to be executed for each request before # the view (and later middleware) are called. response = self.get_response(request) # Code to be executed for each request/response after # the view is called. return response def process_request(self, request): if '/amp/' in request.path: set_amp_detect(is_amp_detect=True, request=request) else: set_amp_detect(is_amp_detect=False, request=request)
ユーティリティメソッド
__init__.py
には、utility メソッドを記載しています。
これは、shtalinberg/django-amp-tools: Accelerated mobile pages (AMP) in django の __init__.py
のまま使用しています。
threadlocal で、フラグを保持する処理、フラグの値を元に、テンプレートフォルダ名称を返すメソッドが定義されています。
- __init__py
# -*- coding: utf-8 -*- import threading from amp_start_blog_post.settings import settings __version__ = '0.0.1' _local = threading.local() def set_amp_detect(is_amp_detect=False, request=None): request = request or getattr(_local, 'request', None) if request: request.is_amp_detect = is_amp_detect _local.is_amp_detect = is_amp_detect def get_amp_detect(request=None): is_amp_detect = False request = request or getattr(_local, 'request', None) # check if is_amp_detect is set on request if not is_amp_detect and hasattr(request, 'is_amp_detect'): is_amp_detect = request.is_amp_detect # if set out of a request-response cycle its stored on the thread local if not is_amp_detect: is_amp_detect = getattr(_local, 'is_amp_detect', False) return settings.AMP_TOOLS_TEMPLATE_FOLDER if is_amp_detect else u""
Loader の作成
Loader も shtalinberg/django-amp-tools: Accelerated mobile pages (AMP) in django を拝借しました。
記載が長いので、Github へのリンクを記載します。
Loader には、Loader
と、CachedLoader
があり、CacheedLoader を使用しました。
AMP ページへのアクセスの場合は、AMP のテンプレートを取得する処理を行っています。
Template の格納先フォルダは、AMP_TOOLS_TEMPLATE_FOLDER
で、プリフィックスは、AMP_TOOLS_TEMPLATE_PREFIX
で切り替えることができます。
settings.py の編集
Device Handling の設定を削除、loader の変更を行います。
-
mezzanine Device Handling の設定の削除
############################# # Device Settings ############################# #DEVICE_DEFAULT = "" #DEVICE_USER_AGENTS = ( # ("amp_start_blog_post", ("Android", "BlackBerry", "iPhone" # )), # )
-
loader の変更
'loaders': [ ('amp_start_blog_post.loaders.CachedLoader', [ 'amp_start_blog_post.loaders.Loader', 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]), ],
-
Middleware の追加
"amp_start_blog_post.middleware.AMPDetectionMiddleware",
urls.py の変更
mezzanine-blog の url を /amp
配下にマッピングします。
- urls.py
mezzanine.urls
の直上に、blog アプリケーションの url をマッピングしました。
# ----------------------------- # Mezzanine's Blog app for AMP # ----------------------------- blog_installed = "mezzanine.blog" in settings.INSTALLED_APPS if blog_installed: BLOG_SLUG = settings.BLOG_SLUG.rstrip("/") if BLOG_SLUG: BLOG_SLUG += "/" blog_patterns = [ url("^amp/%s" % BLOG_SLUG, include("mezzanine.blog.urls")), ] urlpatterns += blog_patterns urlpatterns += [ url("^", include("mezzanine.urls")), # MOUNTING MEZZANINE UNDER A PREFIX # --------------------------------- # You can also mount all of Mezzanine's urlpatterns under a # URL prefix if desired. When doing this, you need to define the # ``SITE_PREFIX`` setting, which will contain the prefix. Eg: # SITE_PREFIX = "my/site/prefix" # For convenience, and to avoid repeating the prefix, use the # commented out pattern below (commenting out the one above of course) # which will make use of the ``SITE_PREFIX`` setting. Make sure to # add the import ``from django.conf import settings`` to the top # of this file as well. # Note that for any of the various homepage patterns above, you'll # need to use the ``SITE_PREFIX`` setting as well. # ("^%s/" % settings.SITE_PREFIX, include("mezzanine.urls")) ]
作成した python スクリプト
AMP の テーマファイルの一部として以下、Github リポジトリにチェックインしました。
kemsakurai/mezzanine-theme-amp-start-blog-post: mezzanine theme based by amp start
切り替えとしては、上手くできました。
しばらくたったら、Google Seach Console で様子を見て、問題があれば修正しようかと思います。
以上です。
コメント