浏览代码

Added hyperlinks for builtin template tags and filters to code samples in docs.

Implemented in javascript because doing it 'properly' is pretty much impossible with Sphinx and Pygments.

Refs #12249



git-svn-id: http://code.djangoproject.com/svn/django/trunk@13135 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Luke Plant 15 年之前
父节点
当前提交
b09581394e
共有 5 个文件被更改,包括 88 次插入7 次删除
  1. 1 1
      docs/Makefile
  2. 41 2
      docs/_ext/djangodocs.py
  3. 6 1
      docs/_static/djangodocs.css
  4. 37 0
      docs/_templates/layout.html
  5. 3 3
      docs/topics/auth.txt

+ 1 - 1
docs/Makefile

@@ -31,7 +31,7 @@ clean:
 	-rm -rf $(BUILDDIR)/*
 
 html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	$(SPHINXBUILD) -b djangohtml $(ALLSPHINXOPTS) $(BUILDDIR)/html
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
 

+ 41 - 2
docs/_ext/djangodocs.py

@@ -4,12 +4,28 @@ Sphinx plugins for Django documentation.
 
 import docutils.nodes
 import docutils.transforms
+try:
+    import json
+except ImportError:
+    try:
+        import simplejson as json
+    except ImportError:
+        try:
+            from django.utils import simplejson as json
+        except ImportError:
+            json = None
+import os
 import sphinx
 import sphinx.addnodes
 try:
     from sphinx import builders
 except ImportError:
     import sphinx.builder as builders
+try:
+    import sphinx.builders.html as builders_html
+except ImportError:
+    builders_html = builders
+from sphinx.util.console import bold
 import sphinx.directives
 import sphinx.environment
 try:
@@ -56,7 +72,8 @@ def setup(app):
     app.add_directive('versionadded', parse_version_directive, 1, (1, 1, 1))
     app.add_directive('versionchanged', parse_version_directive, 1, (1, 1, 1))
     app.add_transform(SuppressBlockquotes)
-    
+    app.add_builder(DjangoStandaloneHTMLBuilder)
+
     # Monkeypatch PickleHTMLBuilder so that it doesn't die in Sphinx 0.4.2
     if sphinx.__version__ == '0.4.2':
         monkeypatch_pickle_builder()
@@ -218,7 +235,6 @@ def monkeypatch_pickle_builder():
         import cPickle as pickle
     except ImportError:
         import pickle
-    from sphinx.util.console import bold
     
     def handle_finish(self):
         # dump the global context
@@ -248,3 +264,26 @@ def monkeypatch_pickle_builder():
 
     builders.PickleHTMLBuilder.handle_finish = handle_finish
 
+
+class DjangoStandaloneHTMLBuilder(builders_html.StandaloneHTMLBuilder):
+    """
+    Subclass to add some extra things we need.
+    """
+
+    name = 'djangohtml'
+
+    def finish(self):
+        super(DjangoStandaloneHTMLBuilder, self).finish()
+        if json is None:
+            self.warn("cannot create templatebuiltins.js due to missing simplejson dependency")
+            return
+        self.info(bold("writing templatebuiltins.js..."))
+        xrefs = self.env.reftargets.keys()
+        templatebuiltins = dict([('ttags', [n for (t,n) in xrefs if t == 'ttag']),
+                                 ('tfilters', [n for (t,n) in xrefs if t == 'tfilter'])])
+        outfilename = os.path.join(self.outdir, "templatebuiltins.js")
+        f = open(outfilename, 'wb')
+        f.write('var django_template_builtins = ')
+        json.dump(templatebuiltins, f)
+        f.write(';\n')
+        f.close();

+ 6 - 1
docs/_static/djangodocs.css

@@ -98,7 +98,12 @@ pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-widt
 dt .literal, table .literal { background:none; }
 #bd a.reference { text-decoration: none; }
 #bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; }
- 
+
+/* Restore colors of pygments hyperlinked code */
+#bd .highlight .k a:link, #bd .highlight .k a:visited { color: #000000; text-decoration: none; border-bottom: 1px dotted #000000; }
+#bd .highlight .nf a:link, #bd .highlight .nf a:visited { color: #990000; text-decoration: none; border-bottom: 1px dotted #990000; }
+
+
 /*** notes & admonitions ***/
 .note, .admonition { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; }
 .admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;}

+ 37 - 0
docs/_templates/layout.html

@@ -16,6 +16,43 @@
   {%- endif %}
 {%- endmacro %}
 
+{% block extrahead %}
+{{ super() }}
+<script type="text/javascript" src="{{ pathto('templatebuiltins.js', 1) }}"></script>
+<script type="text/javascript">
+(function($) {
+    if (!django_template_builtins) {
+       // templatebuiltins.js missing, do nothing.
+       return;
+    }
+    $(document).ready(function() {
+        // Hyperlink Django template tags and filters
+        var base = "{{ pathto('ref/templates/builtins') }}";
+        if (base == "#") {
+            // Special case for builtins.html itself
+            base = "";
+        }
+        // Tags are keywords, class '.k'
+        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
+             var tagname = $(elem).text();
+             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
+                 var fragment = tagname.replace(/_/, '-');
+                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
+             }
+        });
+        // Filters are functions, class '.nf'
+        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
+             var filtername = $(elem).text();
+             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
+                 var fragment = filtername.replace(/_/, '-');
+                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
+             }
+        });
+    });
+})(jQuery);
+</script>
+{% endblock %}
+
 {% block document %}
   <div id="custom-doc" class="{% block bodyclass %}{{ 'yui-t6' if pagename != 'index' else '' }}{% endblock %}">
     <div id="hd">

+ 3 - 3
docs/topics/auth.txt

@@ -1253,7 +1253,7 @@ currently logged-in user, either a  :class:`~django.contrib.auth.models.User`
 instance or an :class:`~django.contrib.auth.models.AnonymousUser` instance, is
 stored in the template variable ``{{ user }}``:
 
-.. code-block:: html
+.. code-block:: html+django
 
     {% if user.is_authenticated %}
         <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
@@ -1288,7 +1288,7 @@ would display ``True`` if the logged-in user had the permission
 
 Thus, you can check permissions in template ``{% if %}`` statements:
 
-.. code-block:: html
+.. code-block:: html+django
 
     {% if perms.foo %}
         <p>You have permission to do something in the foo app.</p>
@@ -1361,7 +1361,7 @@ logged-in user and his/her messages are made available in the
 :ref:`template context <ref-templates-api>` as the template variable
 ``{{ messages }}``. Here's an example of template code that displays messages:
 
-.. code-block:: html
+.. code-block:: html+django
 
     {% if messages %}
     <ul>