[ADD] support for canonical urls in technical doc
authorXavier Morel <xmo@openerp.com>
Wed, 3 Sep 2014 14:34:52 +0000 (16:34 +0200)
committerXavier Morel <xmo@openerp.com>
Wed, 3 Sep 2014 14:34:52 +0000 (16:34 +0200)
* canonical_root setting is the path to the root of the canonical sphinx doc,
  if not set no canonical link is generated, must end with "/"
* canonical_branch defines the canonical branch to which to redirect, defaults
  to master

also various side-fixes:

* disabled permalinks in sphinx instead of hiding them via CSS
* improved generation of github links, removed _app global and setting of
  linkcode_resolve in conf.py

doc/_themes/odoodoc/github.py
doc/_themes/odoodoc/layout.html
doc/_themes/odoodoc/static/style.css
doc/_themes/odoodoc/static/style.less
doc/conf.py

index 2e07b67..0591a42 100644 (file)
@@ -3,53 +3,54 @@ import importlib
 import os.path
 from urlparse import urlunsplit
 
-# FIXME: better way to handle this?
-_app = None
 def setup(app):
-    global _app
-    _app = app
     app.add_config_value('github_user', None, 'env')
     app.add_config_value('github_project', None, 'env')
+    app.connect('html-page-context', add_doc_link)
 
-def linkcode_resolve(domain, info):
-    # TODO: js?
-    if domain != 'py':
-        return None
+    def linkcode_resolve(domain, info):
+        """ Resolves provided object to corresponding github URL
+        """
+        # TODO: js?
+        if domain != 'py':
+            return None
+        if not (app.config.github_user and app.config.github_project):
+            return None
 
-    module, fullname = info['module'], info['fullname']
-    # TODO: attributes/properties don't have modules, maybe try to look them
-    # up based on their cached host object?
-    if not module:
-        return None
+        module, fullname = info['module'], info['fullname']
+        # TODO: attributes/properties don't have modules, maybe try to look
+        #       them up based on their cached host object?
+        if not module:
+            return None
 
-    obj = importlib.import_module(module)
-    for item in fullname.split('.'):
-        obj = getattr(obj, item, None)
+        obj = importlib.import_module(module)
+        for item in fullname.split('.'):
+            obj = getattr(obj, item, None)
 
-    if obj is None:
-        return None
+        if obj is None:
+            return None
 
-    # get original from decorated methods
-    try: obj = getattr(obj, '_orig')
-    except AttributeError: pass
+        # get original from decorated methods
+        try: obj = getattr(obj, '_orig')
+        except AttributeError: pass
 
-    try:
-        obj_source_path = inspect.getsourcefile(obj)
-        _, line = inspect.getsourcelines(obj)
-    except (TypeError, IOError):
-        # obj doesn't have a module, or something
-        return None
+        try:
+            obj_source_path = inspect.getsourcefile(obj)
+            _, line = inspect.getsourcelines(obj)
+        except (TypeError, IOError):
+            # obj doesn't have a module, or something
+            return None
 
-    import openerp
-    project_root = os.path.join(os.path.dirname(openerp.__file__), '..')
-    return make_github_link(
-        os.path.relpath(obj_source_path, project_root),
-        line)
+        import openerp
+        project_root = os.path.join(os.path.dirname(openerp.__file__), '..')
+        return make_github_link(
+            app,
+            os.path.relpath(obj_source_path, project_root),
+            line)
+    app.config.linkcode_resolve = linkcode_resolve
 
-def make_github_link(path, line=None, mode="blob"):
-    config = _app.config
-    if not (config.github_user and config.github_project):
-        return None
+def make_github_link(app, path, line=None, mode="blob"):
+    config = app.config
 
     urlpath = "/{user}/{project}/{mode}/{branch}/{path}".format(
         user=config.github_user,
@@ -66,6 +67,18 @@ def make_github_link(path, line=None, mode="blob"):
         '' if line is None else 'L%d' % line
     ))
 
-def github_doc_link(pagename, mode='blob'):
-    return make_github_link(
-        'doc/%s%s' % (pagename, _app.config.source_suffix), mode=mode)
+def add_doc_link(app, pagename, templatename, context, doctree):
+    """ Add github_link function linking to the current page on github """
+    if not app.config.github_user and app.config.github_project:
+        return
+
+    def github_doc_link(mode='blob'):
+        """ returns the github URL for the current page
+
+        :param str mode: 'edit' for edition view
+        """
+        return make_github_link(
+            app,
+            'doc/%s%s' % (pagename, app.config.source_suffix),
+            mode=mode)
+    context['github_link'] = github_doc_link
index a803f91..efa9ff7 100644 (file)
 <!doctype html>
 {%- endblock -%}
 
+{%- block extrahead -%}
+  {%- if canonical -%}
+    <link rel="canonical" href="{{ canonical }}"/>
+  {%- endif -%}
+{%- endblock -%}
+
 {%- block content -%}
   <div class="document-super">
     {{ super() }}
     <div class="sphinxsidebarwrapper">
       {{ toctree(maxdepth=4, collapse=False, includehidden=True,
                  main_navbar=False, titles_only=False) }}
-    {% if github %}
-      <p><a href="{{ github(pagename) }}" class="github">
-        Edit on GitHub
-      </a></p>
-    {% endif %}
+      {% if github_link %}
+        <p><a href="{{ github_link() }}" class="github">
+          Edit on GitHub
+        </a></p>
+      {% endif %}
     </div>
   </div>
   {{ super() }}
index 20164ea..fdbf134 100644 (file)
@@ -6540,9 +6540,6 @@ body {
     margin-bottom: 0;
   }
 }
-.headerlink {
-  display: none;
-}
 .viewcode-link {
   font-weight: normal;
   float: right;
index 7b50804..f2eaba2 100644 (file)
@@ -348,10 +348,6 @@ body {
   }
 }
 
-// hide header ΒΆ link
-.headerlink {
-  display: none;
-}
 // move [source] link to the right
 .viewcode-link {
   font-weight: normal;
index daec9bb..005aefd 100644 (file)
@@ -119,6 +119,8 @@ html_static_path = ['_static']
 
 html_style = "odoo.css"
 
+html_add_permalinks = False
+
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
 #html_last_updated_fmt = '%b %d, %Y'
@@ -164,10 +166,20 @@ intersphinx_mapping = {
     'werkzeug': ('http://werkzeug.pocoo.org/docs/0.9/', None),
 }
 
-from odoodoc.github import linkcode_resolve, github_doc_link
 github_user = 'odoo'
 github_project = 'odoo'
 
-html_context = {
-    'github': github_doc_link
-}
+def setup(app):
+    app.connect('html-page-context', canonicalize)
+    app.add_config_value('canonical_root', None, 'env')
+    app.add_config_value('canonical_branch', 'master', 'env')
+def canonicalize(app, pagename, templatename, context, doctree):
+    if not app.config.canonical_root:
+        return
+
+    context['canonical'] = "{canonical_url}{canonical_branch}/{canonical_page}".format(
+        canonical_url=app.config.canonical_root,
+        canonical_branch=app.config.canonical_branch,
+        canonical_page=(pagename + '.html').replace('index.html', '')
+                                           .replace('index/', ''),
+    )