[snowy] Parse and render internal links correctly



commit 24050f4909f3bb2c04bd16be7b32d95b60b41f4d
Author: Brad Taylor <brad getcoded net>
Date:   Wed Jul 22 14:16:26 2009 -0400

    Parse and render internal links correctly

 TODO                      |    3 +--
 data/note2xhtml.xsl       |   26 +++++++++++++++-----------
 notes/views.py            |   39 ++++++++++++++++++++++++++++++++-------
 site_media/css/screen.css |   12 ++++++++++++
 4 files changed, 60 insertions(+), 20 deletions(-)
---
diff --git a/TODO b/TODO
index 45b7b2b..293609b 100644
--- a/TODO
+++ b/TODO
@@ -30,13 +30,12 @@ TODO
    - Documentation via Piston
 
  * Note View
-   - Links need to be replaced with note.pk references on import, and
-     replaced back with <link:*/> on sync.
    - Show which notebooks a note is part of
    - Note searching
    - Better page to show when current user can't view a note
 
  * Note Editing
+   - Renaming (incl. altering internal links)
    - Delete note link
    - History viewer
    - Sharing UI
diff --git a/data/note2xhtml.xsl b/data/note2xhtml.xsl
index 5f6465b..7784816 100644
--- a/data/note2xhtml.xsl
+++ b/data/note2xhtml.xsl
@@ -8,10 +8,7 @@
 <xsl:output method="html" indent="no" />
 <xsl:preserve-space elements="*" />
 
-<xsl:param name="font" />
-<xsl:param name="export-linked" />
-<xsl:param name="export-linked-all" />
-<xsl:param name="root-note" />
+<xsl:param name="base-user-url" />
 
 <xsl:param name="newline" select="'&#xA;'" />
 
@@ -80,23 +77,30 @@
 	<span class="note-size-huge"><xsl:apply-templates select="node()"/></span>
 </xsl:template>
 
-<!-- TODO:
 <xsl:template match="link:broken">
-	<span style="color:#555753;text-decoration:underline">
+	<span class="link-broken">
 		<xsl:value-of select="node()"/>
 	</span>
 </xsl:template>
 
 <xsl:template match="link:internal">
-	<a style="color:#204A87" href="#{node()}">
-		<xsl:value-of select="node()"/>
-	</a>
+	<xsl:choose>
+		<xsl:when test="@id">
+			<a href="{$base-user-url}{ id}" class="link-internal">
+				<xsl:value-of select="node()"/>
+			</a>
+		</xsl:when>
+		<xsl:otherwise>
+			<span class="link-broken">
+				<xsl:value-of select="node()"/>
+			</span>
+		</xsl:otherwise>
+	</xsl:choose>
 </xsl:template>
 
 <xsl:template match="link:url">
-	<a style="color:#3465A4" href="{node()}"><xsl:value-of select="node()"/></a>
+	<a href="{node()}" class="link-url"><xsl:value-of select="node()"/></a>
 </xsl:template>
--->
 
 <xsl:template match="tomboy:list">
 	<ul>
diff --git a/notes/views.py b/notes/views.py
index 13a8013..c2a6e82 100644
--- a/notes/views.py
+++ b/notes/views.py
@@ -15,17 +15,17 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from django.template import RequestContext
-from django.contrib.auth.models import User
-from django.shortcuts import render_to_response, get_object_or_404
 from django.http import HttpResponseRedirect, HttpResponseForbidden, Http404
+from django.shortcuts import render_to_response, get_object_or_404
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from django.template import RequestContext
 
 from snowy.notes.templates import CONTENT_TEMPLATES, DEFAULT_CONTENT_TEMPLATE
 from snowy.notes.models import *
 from snowy import settings
 
-from piston import forms as piston_forms
-
 def note_index(request, username,
                template_name='note/note_index.html'):
     author = get_object_or_404(User, username=username)
@@ -43,6 +43,27 @@ def note_index(request, username,
 
 def note_detail(request, username, note_id, slug='',
                 template_name='notes/note_detail.html'):
+    def clean_content(xml, author):
+        """
+        Adds an id attribute to <link:internal> tags so that URLs can be
+        constructed by the XSLT.
+        """
+        from xml.dom import minidom
+        doc = minidom.parseString(xml)
+
+        for link in doc.getElementsByTagName('link:internal'):
+            if not link.hasChildNodes: continue
+
+            title = link.childNodes[0].nodeValue
+            try:
+                note = Note.objects.get(author=author, title=title)
+            except ObjectDoesNotExist:
+                continue
+
+            link.setAttribute("id", str(note.pk))
+        
+        return doc.toxml()
+
     author = get_object_or_404(User, username=username)
     note = get_object_or_404(Note, pk=note_id, author=author)
 
@@ -63,8 +84,12 @@ def note_detail(request, username, note_id, slug='',
         style = libxslt.parseStylesheetDoc(styledoc)
     
         template = CONTENT_TEMPLATES.get(note.content_version, DEFAULT_CONTENT_TEMPLATE)
-        doc = libxml2.parseDoc(template.replace('%%%CONTENT%%%', note.content.encode('UTF-8')))
-        result = style.applyStylesheet(doc, None)
+        complete_xml = template.replace('%%%CONTENT%%%', note.content.encode('UTF-8'))
+        doc = libxml2.parseDoc(clean_content(complete_xml, author))
+
+        result = style.applyStylesheet(doc,
+            {'base-user-url': "'%s'" % reverse('note_index', kwargs={'username': author.username})}
+        )
 
         # libxml2 doesn't munge encodings, so forcibly decode from UTF-8
         body = unicode(style.saveResultToString(result), 'UTF-8')
diff --git a/site_media/css/screen.css b/site_media/css/screen.css
index d5f025a..8bdeab4 100644
--- a/site_media/css/screen.css
+++ b/site_media/css/screen.css
@@ -280,3 +280,15 @@ table#content-layout {
 .note-size-huge {
     font-size: 2.0em;
 }
+
+a.link-internal {
+    color: #204A87;
+}
+
+a.link-broken {
+    color: #555753;
+}
+
+a.link-url {
+    color: #3465A4;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]