Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added hyperlinks for builtin template tags and filters to code sample…

…s 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
  • Loading branch information...
commit b09581394e7dd7629e71c775d1cc7160b0c26184 1 parent cfc05d8
Luke Plant authored May 08, 2010
2  docs/Makefile
@@ -31,7 +31,7 @@ clean:
31 31
 	-rm -rf $(BUILDDIR)/*
32 32
 
33 33
 html:
34  
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
  34
+	$(SPHINXBUILD) -b djangohtml $(ALLSPHINXOPTS) $(BUILDDIR)/html
35 35
 	@echo
36 36
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
37 37
 
43  docs/_ext/djangodocs.py
@@ -4,12 +4,28 @@
4 4
 
5 5
 import docutils.nodes
6 6
 import docutils.transforms
  7
+try:
  8
+    import json
  9
+except ImportError:
  10
+    try:
  11
+        import simplejson as json
  12
+    except ImportError:
  13
+        try:
  14
+            from django.utils import simplejson as json
  15
+        except ImportError:
  16
+            json = None
  17
+import os
7 18
 import sphinx
8 19
 import sphinx.addnodes
9 20
 try:
10 21
     from sphinx import builders
11 22
 except ImportError:
12 23
     import sphinx.builder as builders
  24
+try:
  25
+    import sphinx.builders.html as builders_html
  26
+except ImportError:
  27
+    builders_html = builders
  28
+from sphinx.util.console import bold
13 29
 import sphinx.directives
14 30
 import sphinx.environment
15 31
 try:
@@ -56,7 +72,8 @@ def setup(app):
56 72
     app.add_directive('versionadded', parse_version_directive, 1, (1, 1, 1))
57 73
     app.add_directive('versionchanged', parse_version_directive, 1, (1, 1, 1))
58 74
     app.add_transform(SuppressBlockquotes)
59  
-    
  75
+    app.add_builder(DjangoStandaloneHTMLBuilder)
  76
+
60 77
     # Monkeypatch PickleHTMLBuilder so that it doesn't die in Sphinx 0.4.2
61 78
     if sphinx.__version__ == '0.4.2':
62 79
         monkeypatch_pickle_builder()
@@ -218,7 +235,6 @@ def monkeypatch_pickle_builder():
218 235
         import cPickle as pickle
219 236
     except ImportError:
220 237
         import pickle
221  
-    from sphinx.util.console import bold
222 238
     
223 239
     def handle_finish(self):
224 240
         # dump the global context
@@ -248,3 +264,26 @@ def handle_finish(self):
248 264
 
249 265
     builders.PickleHTMLBuilder.handle_finish = handle_finish
250 266
 
  267
+
  268
+class DjangoStandaloneHTMLBuilder(builders_html.StandaloneHTMLBuilder):
  269
+    """
  270
+    Subclass to add some extra things we need.
  271
+    """
  272
+
  273
+    name = 'djangohtml'
  274
+
  275
+    def finish(self):
  276
+        super(DjangoStandaloneHTMLBuilder, self).finish()
  277
+        if json is None:
  278
+            self.warn("cannot create templatebuiltins.js due to missing simplejson dependency")
  279
+            return
  280
+        self.info(bold("writing templatebuiltins.js..."))
  281
+        xrefs = self.env.reftargets.keys()
  282
+        templatebuiltins = dict([('ttags', [n for (t,n) in xrefs if t == 'ttag']),
  283
+                                 ('tfilters', [n for (t,n) in xrefs if t == 'tfilter'])])
  284
+        outfilename = os.path.join(self.outdir, "templatebuiltins.js")
  285
+        f = open(outfilename, 'wb')
  286
+        f.write('var django_template_builtins = ')
  287
+        json.dump(templatebuiltins, f)
  288
+        f.write(';\n')
  289
+        f.close();
7  docs/_static/djangodocs.css
@@ -98,7 +98,12 @@ pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-widt
98 98
 dt .literal, table .literal { background:none; }
99 99
 #bd a.reference { text-decoration: none; }
100 100
 #bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; }
101  
- 
  101
+
  102
+/* Restore colors of pygments hyperlinked code */
  103
+#bd .highlight .k a:link, #bd .highlight .k a:visited { color: #000000; text-decoration: none; border-bottom: 1px dotted #000000; }
  104
+#bd .highlight .nf a:link, #bd .highlight .nf a:visited { color: #990000; text-decoration: none; border-bottom: 1px dotted #990000; }
  105
+
  106
+
102 107
 /*** notes & admonitions ***/
103 108
 .note, .admonition { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; }
104 109
 .admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;}
37  docs/_templates/layout.html
@@ -16,6 +16,43 @@
16 16
   {%- endif %}
17 17
 {%- endmacro %}
18 18
 
  19
+{% block extrahead %}
  20
+{{ super() }}
  21
+<script type="text/javascript" src="{{ pathto('templatebuiltins.js', 1) }}"></script>
  22
+<script type="text/javascript">
  23
+(function($) {
  24
+    if (!django_template_builtins) {
  25
+       // templatebuiltins.js missing, do nothing.
  26
+       return;
  27
+    }
  28
+    $(document).ready(function() {
  29
+        // Hyperlink Django template tags and filters
  30
+        var base = "{{ pathto('ref/templates/builtins') }}";
  31
+        if (base == "#") {
  32
+            // Special case for builtins.html itself
  33
+            base = "";
  34
+        }
  35
+        // Tags are keywords, class '.k'
  36
+        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
  37
+             var tagname = $(elem).text();
  38
+             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
  39
+                 var fragment = tagname.replace(/_/, '-');
  40
+                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
  41
+             }
  42
+        });
  43
+        // Filters are functions, class '.nf'
  44
+        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
  45
+             var filtername = $(elem).text();
  46
+             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
  47
+                 var fragment = filtername.replace(/_/, '-');
  48
+                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
  49
+             }
  50
+        });
  51
+    });
  52
+})(jQuery);
  53
+</script>
  54
+{% endblock %}
  55
+
19 56
 {% block document %}
20 57
   <div id="custom-doc" class="{% block bodyclass %}{{ 'yui-t6' if pagename != 'index' else '' }}{% endblock %}">
21 58
     <div id="hd">
6  docs/topics/auth.txt
@@ -1253,7 +1253,7 @@ currently logged-in user, either a  :class:`~django.contrib.auth.models.User`
1253 1253
 instance or an :class:`~django.contrib.auth.models.AnonymousUser` instance, is
1254 1254
 stored in the template variable ``{{ user }}``:
1255 1255
 
1256  
-.. code-block:: html
  1256
+.. code-block:: html+django
1257 1257
 
1258 1258
     {% if user.is_authenticated %}
1259 1259
         <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
@@ -1288,7 +1288,7 @@ would display ``True`` if the logged-in user had the permission
1288 1288
 
1289 1289
 Thus, you can check permissions in template ``{% if %}`` statements:
1290 1290
 
1291  
-.. code-block:: html
  1291
+.. code-block:: html+django
1292 1292
 
1293 1293
     {% if perms.foo %}
1294 1294
         <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
1361 1361
 :ref:`template context <ref-templates-api>` as the template variable
1362 1362
 ``{{ messages }}``. Here's an example of template code that displays messages:
1363 1363
 
1364  
-.. code-block:: html
  1364
+.. code-block:: html+django
1365 1365
 
1366 1366
     {% if messages %}
1367 1367
     <ul>

0 notes on commit b095813

Please sign in to comment.
Something went wrong with that request. Please try again.