chiark / gitweb /
m.htmlsanity: introduce and use new format_siteurl filter.
authorVladimír Vondruš <mosra@centrum.cz>
Tue, 24 Oct 2017 16:23:08 +0000 (18:23 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Tue, 24 Oct 2017 16:23:08 +0000 (18:23 +0200)
I needed a way to prepend SITEURL to page, article, tag etc URLs that's
consistent with current (wrong) Pelican way of doing it:

    '/'.join([SITEURL, url])

That of course doesn't work when `url` is an absolute URL, so I'm using
urljoin (but still staying compatible with the above). This is now also
used throughout the template -- I mistakenly assumed that when SITEURL
is set, all page.url etc. properties already have it, but that's
apparently *not* the case, which caused me a bit of headache the past
months.

16 files changed:
doc/plugins/htmlsanity.rst
pelican-plugins/m/htmlsanity.py
pelican-theme/templates/archives.html
pelican-theme/templates/article.html
pelican-theme/templates/article_footer.html
pelican-theme/templates/article_header.html
pelican-theme/templates/author.html
pelican-theme/templates/base.html
pelican-theme/templates/base_blog.html
pelican-theme/templates/base_blog_section.html
pelican-theme/templates/category.html
pelican-theme/templates/index.html
pelican-theme/templates/page.html
pelican-theme/templates/pagination.html
pelican-theme/templates/tag.html
site/pelicanconf.py

index 09d142bb3e1a9d3b953abd17d7d9eb42fc439352..a2fb2977429d4866230e9fcef2dded93eb0cc53d 100644 (file)
@@ -29,7 +29,8 @@ HTML sanity
 
 .. role:: html(code)
     :language: html
-
+.. role:: jinja(code)
+    :language: jinja
 .. role:: py(code)
     :language: py
 
@@ -275,6 +276,17 @@ making use of both fields could look like this:
     :legal: This article is released under `CC0 {filename}/license.rst`_.
     :cover: {filename}/img/article-cover.jpg
 
+`SITEURL formatting`_
+---------------------
+
+Convenience filter replacing the common expression :jinja:`{{ SITEURL }}/{{ page.url }}`
+with a formatter that makes use of `urljoin <https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin>`_ so it does the right thing also when
+dealing with absolute URLs and even when they start with just ``//``:
+
+.. code:: jinja
+
+    {{ page.url|format_siteurl }}
+
 `Text hyphenation`_
 -------------------
 
index 77fb7053caf4ac2835897e0b755c51a28abb010c..6bf4f31855cd96fece7d344425d50fc833e81726 100644 (file)
@@ -26,7 +26,7 @@ import os.path
 import re
 
 import six
-from six.moves.urllib.parse import urlparse, urlunparse
+from six.moves.urllib.parse import urlparse, urlunparse, urljoin
 
 from docutils.writers.html5_polyglot import HTMLTranslator
 from docutils.transforms import Transform
@@ -53,6 +53,7 @@ smart_quotes = False
 hyphenation_lang = 'en'
 docutils_settings = {}
 intrasite_link_regex = ''
+siteurl = ''
 
 words_re = re.compile("""\w+""", re.UNICODE|re.X)
 
@@ -697,9 +698,15 @@ def expand_link_pelican371(link, content):
 def expand_links(text, content):
     return content._update_content(text, content.get_siteurl())
 
+# To be consistent with both what Pelican does now with '/'.join(SITEURL, url)
+# and with https://github.com/getpelican/pelican/pull/2196
+def format_siteurl(url):
+    return urljoin(siteurl + ('/' if not siteurl.endswith('/') else ''), url)
+
 def configure_pelican(pelicanobj):
     pelicanobj.settings['JINJA_FILTERS']['render_rst'] = render_rst
     pelicanobj.settings['JINJA_FILTERS']['expand_links'] = expand_links
+    pelicanobj.settings['JINJA_FILTERS']['format_siteurl'] = format_siteurl
     pelicanobj.settings['JINJA_FILTERS']['hyphenate'] = hyphenate
     pelicanobj.settings['JINJA_FILTERS']['dehyphenate'] = dehyphenate
 
@@ -712,12 +719,13 @@ def configure_pelican(pelicanobj):
         pelicanobj.settings['JINJA_FILTERS']['expand_link'] = expand_link
 
     global enable_hyphenation, smart_quotes, hyphenation_lang, \
-        docutils_settings, intrasite_link_regex
+        docutils_settings, intrasite_link_regex, siteurl
     enable_hyphenation = pelicanobj.settings.get('M_HTMLSANITY_HYPHENATION', False)
     smart_quotes = pelicanobj.settings.get('M_HTMLSANITY_SMART_QUOTES', False)
     hyphenation_lang = pelicanobj.settings['DEFAULT_LANG']
     docutils_settings = pelicanobj.settings['DOCUTILS_SETTINGS']
     intrasite_link_regex = pelicanobj.settings['INTRASITE_LINK_REGEX']
+    siteurl = pelicanobj.settings['SITEURL']
 
 def add_reader(readers):
     # TODO: remove when 3.8 with https://github.com/getpelican/pelican/pull/2163
index 08589117bbfc2f678b8104abf9073f64c2e11d27..ded6964b9aec96767ecd3237c3d9f24924c13f75 100644 (file)
@@ -3,10 +3,10 @@
 {% block head %}
   {{- super() -}}
   {% if articles_page.has_previous() %}
-  <link rel="prev" href="{{ articles_previous_page.url }}" />
+  <link rel="prev" href="{{ articles_previous_page.url|format_siteurl }}" />
   {% endif %}
   {% if articles_page.has_next() %}
-  <link rel="next" href="{{ articles_next_page.url }}" />
+  <link rel="next" href="{{ articles_next_page.url|format_siteurl }}" />
   {% endif %}
 {% endblock head %}
 
index a9be63f1dc0ea6b5a57d29bad691a91198a5d473..0a00ee679eed38f00c2fe39e7532855e4fde50b4 100644 (file)
@@ -10,8 +10,8 @@
   <meta name="keywords" content="{{ article.tags|join(", ") }}" />
   <meta property="og:title" content="{{ article.title }}" />
   <meta name="twitter:title" content="{{ article.title }}" />
-  <meta property="og:url" content="{{ article.url }}" />
-  <meta name="twitter:url" content="{{ article.url }}" />
+  <meta property="og:url" content="{{ article.url|format_siteurl }}" />
+  <meta name="twitter:url" content="{{ article.url|format_siteurl }}" />
   <meta property="og:description" content="{{ article.summary|striptags }}" />
   <meta name="twitter:description" content="{{ article.summary|striptags }}" />
   {% if article.cover %}
           <div class="m-container">
             <div class="m-row">
               <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-left">{{ article.locale_date }}</div>
-              <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-right">{% for author in article.authors %}<a href="{{ author.url }}">{{ author }}</a>{% endfor %}</div>
+              <div class="m-col-t-6 m-col-s-5 m-push-s-1 m-text-right">{% for author in article.authors %}<a href="{{ author.url|format_siteurl }}">{{ author }}</a>{% endfor %}</div>
             </div>
             <div class="m-row">
               <div class="m-col-t-12 m-col-s-10 m-push-s-1 m-col-m-8 m-push-m-2">
                 {% set title = article.title.split(' — ') %}
-                <h1><a href="{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title }}">
+                <h1><a href="{{ article.url|format_siteurl }}" rel="bookmark" title="Permalink to {{ article.title }}">
                   {{ title[0] }}
                 </a></h1>
                 {% if title|length >= 2 %}
@@ -69,7 +69,7 @@
     <footer class="m-container">
       <div class="m-row">
         <div class="m-col-m-10 m-push-m-1 m-nopadb">
-          <p>Posted {% if article.authors %}by {% for author in article.authors %}<a href="{{ author.url }}">{{ author }}</a>{% endfor %}{% endif %} on <time datetime="{{ article.date.isoformat() }}">{{ article.locale_date }}</time> in <a href="{{ article.category.url }} ">{{ article.category }}</a>.{% if article.tags %} Tags: {% for tag in article.tags %}<a href="{{ tag.url }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}{% endfor %}.{% endif %}</p>
+          <p>Posted {% if article.authors %}by {% for author in article.authors %}<a href="{{ author.url|format_siteurl }}">{{ author }}</a>{% endfor %}{% endif %} on <time datetime="{{ article.date.isoformat() }}">{{ article.locale_date }}</time> in <a href="{{ article.category.url|format_siteurl }} ">{{ article.category }}</a>.{% if article.tags %} Tags: {% for tag in article.tags %}<a href="{{ tag.url|format_siteurl }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}{% endfor %}.{% endif %}</p>
         </div>
       </div>
     </footer>
index b69bad590c1d3b74b6f7ee5674cc9c8ab2685472..0b31bef767b6c1731a1ce12398c2237f73800774 100644 (file)
@@ -1,3 +1,3 @@
 <footer>
-  <p>Posted {% if article.authors %}by {% for author in article.authors %}<a href="{{ author.url }}">{{ author }}</a>{% endfor %}{% endif %} on <time datetime="{{ article.date.isoformat() }}">{{ article.locale_date }}</time> in <a href="{{ article.category.url }} ">{{ article.category }}</a>.{% if article.tags %} Tags: {% for tag in article.tags %}<a href="{{ tag.url }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}{% endfor %}.{% endif %}</p>
+  <p>Posted {% if article.authors %}by {% for author in article.authors %}<a href="{{ author.url|format_siteurl }}">{{ author }}</a>{% endfor %}{% endif %} on <time datetime="{{ article.date.isoformat() }}">{{ article.locale_date }}</time> in <a href="{{ article.category.url|format_siteurl }} ">{{ article.category }}</a>.{% if article.tags %} Tags: {% for tag in article.tags %}<a href="{{ tag.url|format_siteurl }}">{{ tag }}</a>{% if not loop.last %}, {% endif %}{% endfor %}.{% endif %}</p>
 </footer>
index 626ab8f307d19e3388e03864e0284508d66090bc..cc3be45e73cb8247f564dabb49f0c5adcd95dced 100644 (file)
@@ -1,5 +1,5 @@
 <header>
-  <h1><a href="{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">
+  <h1><a href="{{ article.url|format_siteurl }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">
     <time class="m-date" datetime="{{ article.date.isoformat() }}">
       {% set month, day, year = article.locale_date.split(' ') %}
       {{ month }} <span class="m-date-day">{{ day }}</span> {{year}}
index 51cf82499b8430b0cccacf0be1252b7818d89ce8..9ed264998dedd76464f0f7139041b60a5b6aa2a9 100644 (file)
@@ -4,6 +4,6 @@
 
 {% block content_title %}
       <div class="m-info m-note">
-        Showing only posts by <em>{{ author }}</em>. <a href="{{ BLOGURL }}/">Show all posts.</a>
+        Showing only posts by <em>{{ author }}</em>. <a href="{{ BLOGURL|format_siteurl }}">Show all posts.</a>
       </div>
 {% endblock %}
index 8124b170c76e968addc42123efa03d0b601cacc1..b30071251f47285249bfa29abef1a63dedf50625 100644 (file)
           {% endif %}{% endfor %}
         </ul>
         {% else %}
-        <h3><a href="{{ BLOGURL }}">Blog</a></h3>
+        <h3><a href="{{ BLOGURL|format_siteurl }}">Blog</a></h3>
         <ul>
           {% for cat, null in categories %}
-          <li><a href="{{ cat.url }}">{{ cat }}</a></li>
+          <li><a href="{{ cat.url|format_siteurl }}">{{ cat }}</a></li>
           {% endfor %}
         </ul>
         {% endif %}
index 597c88d4b761db3b5e734d37926d1dbba7c3853b..6e9dbb8cf174d0688dcd2b94bc77d6888fd12020 100644 (file)
@@ -18,7 +18,7 @@
         <h3>Cate&shy;gories</h3>
         <ol class="m-block-bar-m">
           {% for cat, null in categories %}
-          <li><a href="{{ cat.url }}">{{ cat }}</a></li>
+          <li><a href="{{ cat.url|format_siteurl }}">{{ cat }}</a></li>
           {% endfor %}
         </ol>
       </div>
@@ -27,7 +27,7 @@
         <ul class="m-tagcloud">
           {% set max_articles_per_tag = tags|map(attribute='1')|map('length')|sort|last %}
           {% for tag, articles in tags|sort(attribute='0') %}
-          <li class="m-tag-{{ (5*(articles|length)/max_articles_per_tag)|round(0, 'ceil')|int }} "><a href="{{ tag.url }}">{{ tag }}</a></li>
+          <li class="m-tag-{{ (5*(articles|length)/max_articles_per_tag)|round(0, 'ceil')|int }} "><a href="{{ tag.url|format_siteurl }}">{{ tag }}</a></li>
           {% endfor %}
         </ul>
       </div>
       <h3>Cate&shy;gories</h3>
       <ol class="m-block-bar-m">
         {% for cat, null in categories %}
-        <li><a href="{{ cat.url }}">{{ cat|hyphenate }}</a></li>
+        <li><a href="{{ cat.url|format_siteurl }}">{{ cat|hyphenate }}</a></li>
         {% endfor %}
       </ol>
       <h3>Tag cloud</h3>
       <ul class="m-tagcloud">
         {% set max_articles_per_tag = tags|map(attribute='1')|map('length')|sort|last %}
         {% for tag, articles in tags|sort(attribute='0') %}
-        <li class="m-tag-{{ (5*(articles|length)/max_articles_per_tag)|round(0, 'ceil')|int }} "><a href="{{ tag.url }}">{{ tag }}</a></li>
+        <li class="m-tag-{{ (5*(articles|length)/max_articles_per_tag)|round(0, 'ceil')|int }} "><a href="{{ tag.url|format_siteurl }}">{{ tag }}</a></li>
         {% endfor %}
       </ul>
     </nav>
index 1dfaf35024ac4f4157a39be371b6cd4da2d567a3..8072d378badda068d41d903cf67fe56061aaadc8 100644 (file)
@@ -3,10 +3,10 @@
 {% block head %}
   {{- super() -}}
   {% if articles_page.has_previous() %}
-  <link rel="prev" href="{{ articles_previous_page.url }}" />
+  <link rel="prev" href="{{ articles_previous_page.url|format_siteurl }}" />
   {% endif %}
   {% if articles_page.has_next() %}
-  <link rel="next" href="{{ articles_next_page.url }}" />
+  <link rel="next" href="{{ articles_next_page.url|format_siteurl }}" />
   {% endif %}
 {% endblock head %}
 
index 3b91c063d86441455f88ba6a9fc2abfd686b3505..22e71c51a08171c37925c6177a6b98398db4a153 100644 (file)
@@ -4,6 +4,6 @@
 
 {% block content_title %}
       <div class="m-info m-note">
-        Showing only posts in <em>{{ category }}</em>. <a href="{{ BLOGURL }}/">Show all posts.</a>
+        Showing only posts in <em>{{ category }}</em>. <a href="{{ BLOGURL|format_siteurl }}">Show all posts.</a>
       </div>
 {% endblock %}
index 08589117bbfc2f678b8104abf9073f64c2e11d27..ded6964b9aec96767ecd3237c3d9f24924c13f75 100644 (file)
@@ -3,10 +3,10 @@
 {% block head %}
   {{- super() -}}
   {% if articles_page.has_previous() %}
-  <link rel="prev" href="{{ articles_previous_page.url }}" />
+  <link rel="prev" href="{{ articles_previous_page.url|format_siteurl }}" />
   {% endif %}
   {% if articles_page.has_next() %}
-  <link rel="next" href="{{ articles_next_page.url }}" />
+  <link rel="next" href="{{ articles_next_page.url|format_siteurl }}" />
   {% endif %}
 {% endblock head %}
 
index cd7d7172ac13e636f53ddc36d7002c626e668be4..f3dd08c881ba72b3f5ffb11bdd7ddf586867c05e 100644 (file)
@@ -20,8 +20,8 @@
   {% endif %}
   <meta property="og:title" content="{{ page.title }}" />
   <meta name="twitter:title" content="{{ page.title }}" />
-  <meta property="og:url" content="{% if page.url %}{{ page.url }}{% else %}{{ SITEURL }}{% endif %}" />
-  <meta name="twitter:url" content="{% if page.url %}{{ page.url }}{% else %}{{ SITEURL }}{% endif %}" />
+  <meta property="og:url" content="{% if page.url %}{{ page.url|format_siteurl }}{% else %}{{ SITEURL }}{% endif %}" />
+  <meta name="twitter:url" content="{% if page.url %}{{ page.url|format_siteurl }}{% else %}{{ SITEURL }}{% endif %}" />
   <meta property="og:description" content="{{ page.summary|striptags }}" />
   <meta name="twitter:description" content="{{ page.summary|striptags }}" />
   {% if page.cover %}
index c62e8994d43ae924d8029216e5c5c490a1dae2c0..da0ae46066786608e268b4c3c65ce38ece656c9c 100644 (file)
@@ -1,7 +1,7 @@
 {% if DEFAULT_PAGINATION %}
 <div class="m-article-pagination">
-  {%- if articles_page.has_previous() %}<a href="{{ articles_previous_page.url }}">&laquo; newer articles</a> | {% endif -%}
+  {%- if articles_page.has_previous() %}<a href="{{ articles_previous_page.url|format_siteurl }}">&laquo; newer articles</a> | {% endif -%}
   page {{ articles_page.number }}
-  {%- if articles_page.has_next() %} | <a href="{{ articles_next_page.url }}">older articles &raquo;</a>{% endif -%}
+  {%- if articles_page.has_next() %} | <a href="{{ articles_next_page.url|format_siteurl }}">older articles &raquo;</a>{% endif -%}
 </div>
 {% endif %}
index 1dd694c1d6d0f60a306325d99a3593f29941cc4b..9a81fad171d1625a34e02cad8c9530ae437cd3c2 100644 (file)
@@ -4,6 +4,6 @@
 
 {% block content_title %}
       <div class="m-info m-note">
-        Showing only posts tagged <em>{{ tag }}</em>. <a href="{{ BLOGURL }}/">Show all posts.</a>
+        Showing only posts tagged <em>{{ tag }}</em>. <a href="{{ BLOGURL|format_siteurl }}">Show all posts.</a>
       </div>
 {% endblock %}
index 29eeba810c87647678b4cc044afee735dd786815..b01d4c1b1af87aa075c54494742c22c52d0089aa 100644 (file)
@@ -30,7 +30,7 @@ SITENAME = 'm.css'
 SITEURL = ''
 
 BLOGNAME = 'm.css example articles'
-BLOGURL = '/examples'
+BLOGURL = 'examples/'
 
 STATIC_URL = '/{path}'