Add opengraph tags to some pages
authorMagnus Hagander <magnus@hagander.net>
Thu, 22 Oct 2020 12:08:29 +0000 (14:08 +0200)
committerMagnus Hagander <magnus@hagander.net>
Thu, 22 Oct 2020 12:14:12 +0000 (14:14 +0200)
Add template support for opengraph tags (which will enable things like
icons and preview on posts to twitter and facebook and other places) to
both base pages and documentation pages. Use this to actually add the
tags to docs pages (only v10+ will get text previews, but all should get
the titles and image) and news (only news from the project will get an
image, all get both title and text)

pgweb/docs/views.py
pgweb/news/views.py
templates/base/base.html
templates/docs/docspage.html

index a10664e14cc5db2b33ac5026796b1d55d949215f..9f071a50c1f43ec410520ffcb22e125f39fcbc34 100644 (file)
@@ -2,6 +2,7 @@ from django.shortcuts import render, get_object_or_404
 from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
 from django.http import HttpResponse, Http404
 from pgweb.util.decorators import login_required, allow_frames, content_sources
+from django.template.defaultfilters import strip_tags
 from django.db.models import Q
 from django.conf import settings
 
@@ -111,6 +112,14 @@ def docpage(request, version, filename):
         params=[fullname, fullname, fullname],
     ).order_by('-version__supported', 'version').only('version', 'file')
 
+    # If possible (e.g. if we match), remove the header part of the docs so that we can generate a plain text
+    # preview. For older versions where this doesn't match, we just leave it empty.
+    m = re.match(r'^<div [^>]*class="navheader"[^>]*>.*?</div>(.*)$', page.content, re.S)
+    if m:
+        contentpreview = strip_tags(m.group(1))
+    else:
+        contentpreview = ''
+
     return render(request, 'docs/docspage.html', {
         'page': page,
         'supported_versions': [v for v in versions if v.version.supported],
@@ -119,6 +128,13 @@ def docpage(request, version, filename):
         'title': page.title,
         'doc_index_filename': indexname,
         'loaddate': loaddate,
+        'og': {
+            'url': '/docs/{}/{}'.format(page.display_version(), page.file),
+            'time': page.version.docsloaded,
+            'title': page.title.strip(),
+            'description': contentpreview,
+            'sitename': 'PostgreSQL Documentation',
+        }
     })
 
 
index 24522f8d6d3abc32d890079d6dde667720097729..68a6cb75b3ce49b48d003b3130a536cde2888d89 100644 (file)
@@ -43,11 +43,23 @@ def item(request, itemid, slug=None):
     news = get_object_or_404(NewsArticle, pk=itemid)
     if news.modstate != ModerationState.APPROVED:
         raise Http404
+
+    fullurl = '/about/news/{}-{}/'.format(slugify(news.title), news.id)
     if slug != slugify(news.title):
-        return HttpResponsePermanentRedirect('/about/news/{}-{}/'.format(slugify(news.title), news.id))
+        return HttpResponsePermanentRedirect(fullurl)
+
     return render_pgweb(request, 'about', 'news/item.html', {
         'obj': news,
         'newstags': NewsTag.objects.all(),
+        'og': {
+            'url': fullurl,
+            'author': news.org.name if news.org.name != '_migrated' else '',
+            'time': datetime.datetime.combine(news.date, datetime.datetime.min.time()),
+            'title': news.title,
+            'description': news.content,
+            'noimage': news.org.mailtemplate == 'default',  # For now, control image by "using a custom logo"
+            'sitename': 'PostgreSQL News',
+        }
     })
 
 
index e6c3c1eb6b5aece8eb1806feeed25ef6bfe5922c..a2158a49c55ccbecb00ff5d0ae0118d7ade15b92 100644 (file)
@@ -6,7 +6,15 @@
   <meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" />
   {%block meta%}{%endblock%} {# used for custom meta tags such as description which we don't want for every page #}
   <meta name="theme-color" content="#336791"/>
-  <meta name="copyright" content="The PostgreSQL Global Development Group" />
+  <meta name="copyright" content="The PostgreSQL Global Development Group" />{%if og%}
+  <meta property="og:url" content="https://www.postgresql.org{{og.url}}" />
+  <meta property="og:type" content="article" />
+{%if og.author%}  <meta property="article:author" content="{{og.author}}" />{%endif%}
+  <meta property="article:published_time" content="{{og.time|date:"c"}}" />
+{%if not og.noimage%}  <meta property="og:image" content="https://www.postgresql.org/media/img/about/press/elephant.png" />{%endif%}
+  <meta property="og:title" content="{{og.title}}" />
+  <meta property="og:description" content="{{og.description|truncatewords:"20"}}" />
+  <meta property="og:site_name" content="{{og.sitename|default:"PostgreSQL"}}" />{%endif%}
   <link href="/media/css/fontawesome.css?{{gitrev}}" rel="stylesheet">
   <link rel="stylesheet" href="/media/css/bootstrap-4.4.1.min.css">
   <link rel="shortcut icon" href="/favicon.ico" />
index b73f2a71c2b8e1fd4b31b091311aab5ae07b5fce..f5f3e3b109ff623b610dfaaceb89a7b525e1aca0 100644 (file)
@@ -6,7 +6,14 @@
   <meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" />
   {%block meta%}{%endblock%} {# used for custom meta tags such as description which we don't want for every page #}
   <meta name="theme-color" content="#336791"/>
-  <meta name="copyright" content="The PostgreSQL Global Development Group" />
+  <meta name="copyright" content="The PostgreSQL Global Development Group" />{%if og%}
+  <meta property="og:url" content="https://www.postgresql.org{{og.url}}" />
+  <meta property="og:type" content="article" />
+  <meta property="article:published_time" content="{{og.time|date:"c"}}" />
+{%if not og.noimage%}  <meta property="og:image" content="https://www.postgresql.org/media/img/about/press/elephant.png" />{%endif%}
+  <meta property="og:title" content="{{og.title}}" />
+{%if og.description%}  <meta property="og:description" content="{{og.description|truncatewords:"20"}}" />{%endif%}
+  <meta property="og:site_name" content="{{og.sitename|default:"PostgreSQL"}}" />{%endif%}
   <link href="/media/css/fontawesome.css?{{gitrev}}" rel="stylesheet">
   <link rel="stylesheet" href="/media/css/bootstrap-4.4.1.min.css">
   <link rel="shortcut icon" href="/favicon.ico" />