Half-way commit to getting hardcoded paths out of templates.

This commit is contained in:
Brit Butler 2014-08-22 17:29:47 -04:00
parent 04c1ed9aee
commit ae96c069c4
11 changed files with 47 additions and 31 deletions

View file

@ -224,11 +224,17 @@ PAGE, a content type for static page support, is available as a plugin.
Right now, the templates break if you use a custom routing scheme Right now, the templates break if you use a custom routing scheme
in your config. This is flatly ridiculous. The templates should be in your config. This is flatly ridiculous. The templates should be
updated to use a url field stored on each object which will store updated to use a url field stored on each object which will store
the unified domain/path of the object. This can be done transparently the path of the object. This can be done transparently to users,
to users, though must be handled with care and may involve refactoring though must be handled with care and may involve refactoring
in the document protocol. Test carefully. If we cheat by hardcoding in the document protocol. Test carefully. If we cheat by hardcoding
the sitemap and/or feeds, that's probably okay for the moment. the sitemap and/or feeds, that's probably okay for the moment.
Turns out this is even messier than I thought. Links are built from
scratch in the templates *all over the place*. Tags in posts,
taglinks and monthlinks in indexes, and prev/next links in numeric
indexes. I'm also doing two `find-all` calls in the base `render`
method for index. So I should profile and/or memoize that if needed.
### Clean up Slugs vs Paths ### Clean up Slugs vs Paths
Currently, we track uniqueness in the site by using a hashtable Currently, we track uniqueness in the site by using a hashtable

View file

@ -33,8 +33,9 @@
(defclass content () (defclass content ()
((file :initarg :file :reader content-file) ((file :initarg :file :reader content-file)
(date :initarg :date :reader content-date) (date :initarg :date :reader content-date)
(path :initarg :path :accessor path-of)
(slug :initarg :slug :accessor slug-of)
(tags :initarg :tags :accessor content-tags) (tags :initarg :tags :accessor content-tags)
(slug :initarg :slug :accessor content-slug)
(text :initarg :text :accessor content-text)) (text :initarg :text :accessor content-text))
(:default-initargs :tags nil :date nil :slug nil)) (:default-initargs :tags nil :date nil :slug nil))

View file

@ -29,14 +29,14 @@
(:documentation "The url to the DOCUMENT without the domain.") (:documentation "The url to the DOCUMENT without the domain.")
(:method (document) (:method (document)
(let* ((class-name (class-name (class-of document))) (let* ((class-name (class-name (class-of document)))
(route (assoc (make-keyword class-name) (routing *config*)))) (route (get-route class-name)))
(if route (if route
(format nil (second route) (slot-value document 'slug)) (format nil route (slug-of document))
(error "No routing method found for: ~A" class-name))))) (error "No routing method found for: ~A" class-name)))))
(defmethod page-url :around ((document t)) (defmethod page-url :around ((document t))
(let* ((result (call-next-method)) (let* ((result (call-next-method))
(type (or (pathname-type result) "html"))) (type (or (pathname-type result) (page-ext *config*))))
(make-pathname :type type :defaults result))) (make-pathname :type type :defaults result)))
(defgeneric render (document &key &allow-other-keys) (defgeneric render (document &key &allow-other-keys)
@ -64,6 +64,10 @@ use it as the template passing any RENDER-ARGS."
(url (namestring (page-url document)))) (url (namestring (page-url document))))
(write-file (rel-path (staging-dir *config*) url) html))) (write-file (rel-path (staging-dir *config*) url) html)))
(defun get-route (doc-type)
"Return the route format string for DOC-TYPE."
(second (assoc (make-keyword doc-type) (routing *config*))))
(defun find-all (doc-type) (defun find-all (doc-type)
"Return a list of all instances of a given DOC-TYPE." "Return a list of all instances of a given DOC-TYPE."
(loop for val being the hash-values in *site* (loop for val being the hash-values in *site*

View file

@ -6,13 +6,17 @@
"The list of tags which content has been tagged with.") "The list of tags which content has been tagged with.")
(defclass index () (defclass index ()
((slug :initarg :slug :reader index-slug) ((path :initarg :path :accessor path-of)
(slug :initarg :slug :reader slug-of)
(title :initarg :title :reader title-of) (title :initarg :title :reader title-of)
(content :initarg :content :reader index-content))) (content :initarg :content :reader index-content)))
(defmethod initialize-instance :after ((object index) &key)
(setf (path-of object) (page-url object)))
(defmethod render ((object index) &key prev next) (defmethod render ((object index) &key prev next)
(funcall (theme-fn 'index) (list :tags *all-tags* (funcall (theme-fn 'index) (list :tags (find-all 'tag-index)
:months *all-months* :months (find-all 'month-index)
:config *config* :config *config*
:index object :index object
:prev prev :prev prev
@ -24,7 +28,7 @@
(defmethod discover ((doc-type (eql (find-class 'tag-index)))) (defmethod discover ((doc-type (eql (find-class 'tag-index))))
(let ((content (by-date (find-all 'post)))) (let ((content (by-date (find-all 'post))))
(dolist (tag (all-tags)) (dolist (tag *all-tags*)
(add-document (index-by-tag tag content))))) (add-document (index-by-tag tag content)))))
(defun index-by-tag (tag content) (defun index-by-tag (tag content)

View file

@ -11,10 +11,11 @@
(author author-of) (author author-of)
(format post-format) (format post-format)
(text content-text)) object (text content-text)) object
(setf (content-slug object) (slugify title) (setf (slug-of object) (slugify title)
format (make-keyword (string-upcase format)) (path-of object) (page-url object)
text (render-text text format) format (make-keyword (string-upcase format))
author (or author (author *config*))))) text (render-text text format)
author (or author (author *config*)))))
(defmethod render ((object post) &key prev next) (defmethod render ((object post) &key prev next)
(funcall (theme-fn 'post) (list :config *config* (funcall (theme-fn 'post) (list :config *config*

View file

@ -14,7 +14,7 @@
{foreach $post in $content.content} {foreach $post in $content.content}
<entry> <entry>
<link type="text/html" rel="alternate" href="{$config.domain}/posts/{$post.slug}.{$config.pageExt}"/> <link type="text/html" rel="alternate" href="{$config.domain}/{$post.path}"/>
<title>{$post.title}</title> <title>{$post.title}</title>
<published>{$post.date}</published> <published>{$post.date}</published>
<updated>{$post.date}</updated> <updated>{$post.date}</updated>

View file

@ -4,20 +4,20 @@
<h1 class="title">{$index.title}</h1> <h1 class="title">{$index.title}</h1>
{foreach $obj in $index.content} {foreach $obj in $index.content}
<div class="article-meta"> <div class="article-meta">
<a class="article-title" href="{$config.domain}/posts/{$obj.slug}.{$config.pageExt}">{$obj.title}</a> <a class="article-title" href="{$config.domain}/{$obj.path}">{$obj.title}</a>
<div class="date"> posted on {$obj.date}</div> <div class="date"> posted on {$obj.date}</div>
<div class="article">{$obj.text |noAutoescape}</div> <div class="article">{$obj.text |noAutoescape}</div>
</div> </div>
{/foreach} {/foreach}
<div id="relative-nav"> <div id="relative-nav">
{if $prev} <a href="{$prev}.{$config.pageExt}">Previous</a> {/if} {if $prev} <a href="{$config.domain}/{$prev.path}">Previous</a> {/if}
{if $next} <a href="{$next}.{$config.pageExt}">Next</a> {/if} {if $next} <a href="{$config.domain}/{$next.path}">Next</a> {/if}
</div> </div>
{if $tags} {if $tags}
<div id="tagsoup"> <div id="tagsoup">
<p>This blog covers <p>This blog covers
{foreach $tag in $tags} {foreach $tag in $tags}
<a href="{$config.domain}/tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil} <a href="{$config.domain}/${tag.path}">{$tag.name}</a>{nil}
{if not isLast($tag)},{sp}{/if} {if not isLast($tag)},{sp}{/if}
{/foreach} {/foreach}
</div> </div>
@ -26,7 +26,7 @@
<div id="monthsoup"> <div id="monthsoup">
<p>View content from <p>View content from
{foreach $month in $months} {foreach $month in $months}
<a href="{$config.domain}/date/{$month}.{$config.pageExt}">{$month}</a>{nil} <a href="{$config.domain}/{$month.path}">{$month}</a>{nil}
{if not isLast($month)},{sp}{/if} {if not isLast($month)},{sp}{/if}
{/foreach} {/foreach}
</div> </div>

View file

@ -6,7 +6,7 @@
<div class="tags">{\n} <div class="tags">{\n}
{if $post.tags} {if $post.tags}
Tagged as {foreach $tag in $post.tags} Tagged as {foreach $tag in $post.tags}
<a href="{$config.domain}/tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil} <a href="{$config.domain}/{$tag.path}">{$tag.name}</a>{nil}
{if not isLast($tag)},{sp}{/if} {if not isLast($tag)},{sp}{/if}
{/foreach} {/foreach}
{/if} {/if}
@ -21,7 +21,7 @@
{$post.text |noAutoescape} {$post.text |noAutoescape}
</div>{\n} </div>{\n}
<div class="relative-nav">{\n} <div class="relative-nav">{\n}
{if $prev} <a href="{$config.domain}/posts/{$prev.slug}.{$config.pageExt}">Previous</a><br> {/if}{\n} {if $prev} <a href="{$config.domain}/{$prev.path}">Previous</a><br> {/if}{\n}
{if $next} <a href="{$config.domain}/posts/{$next.slug}.{$config.pageExt}">Next</a><br> {/if}{\n} {if $next} <a href="{$config.domain}/{$next.path}">Next</a><br> {/if}{\n}
</div>{\n} </div>{\n}
{/template} {/template}

View file

@ -4,7 +4,7 @@
<h1 class="page-header">{$index.title}</h1> <h1 class="page-header">{$index.title}</h1>
{foreach $obj in $index.content} {foreach $obj in $index.content}
<div class="row-fluid"> <div class="row-fluid">
<h1><a href="{$config.domain}/posts/{$obj.slug}.{$config.pageExt}">{$obj.title}</a></h1> <h1><a href="{$config.domain}/{$obj.path}">{$obj.title}</a></h1>
<p class="date-posted">posted on {$obj.date}</p> <p class="date-posted">posted on {$obj.date}</p>
{$obj.text |noAutoescape} {$obj.text |noAutoescape}
</div> </div>
@ -13,7 +13,7 @@
<div class="row-fluid"> <div class="row-fluid">
<p>This blog covers <p>This blog covers
{foreach $tag in $tags} {foreach $tag in $tags}
<a href="{$config.domain}/tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil} <a href="{$config.domain}/{$tag.path}">{$tag.name}</a>{nil}
{if not isLast($tag)},{sp}{/if} {if not isLast($tag)},{sp}{/if}
{/foreach} {/foreach}
</p> </p>
@ -23,7 +23,7 @@
<div class="row-fluid"> <div class="row-fluid">
<p>View content from <p>View content from
{foreach $month in $months} {foreach $month in $months}
<a href="{$config.domain}/date/{$month}.{$config.pageExt}">{$month}</a>{nil} <a href="{$config.domain}/{$month.path}">{$month}</a>{nil}
{if not isLast($month)},{sp}{/if} {if not isLast($month)},{sp}{/if}
{/foreach} {/foreach}
</p> </p>

View file

@ -6,7 +6,7 @@
<p> <p>
{if $post.tags} {if $post.tags}
Tagged as {foreach $tag in $post.tags} Tagged as {foreach $tag in $post.tags}
<a href="{$config.domain}/tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil} <a href="{$config.domain}/{$tag.path}">{$tag.name}</a>{nil}
{if not isLast($tag)},{sp}{/if} {if not isLast($tag)},{sp}{/if}
{/foreach} {/foreach}
{/if} {/if}
@ -20,8 +20,8 @@
{$post.text |noAutoescape} {$post.text |noAutoescape}
<ul class="pager"> <ul class="pager">
{if $prev}<li class="previous"><a href="{$config.domain}/posts/{$prev.slug}.{$config.pageExt}">&larr; Previous</a></li>{/if}{\n} {if $prev}<li class="previous"><a href="{$config.domain}/{$prev.path}">&larr; Previous</a></li>{/if}{\n}
{if $next}<li class="next"><a href="{$config.domain}/posts/{$next.slug}.{$config.pageExt}">Next &rarr;</a></li>{/if}{\n} {if $next}<li class="next"><a href="{$config.domain}/{$next.path}">Next &rarr;</a></li>{/if}{\n}
</ul> </ul>
</div>{\n} </div>{\n}
{/template} {/template}

View file

@ -13,10 +13,10 @@
{foreach $post in $content.content} {foreach $post in $content.content}
<item> <item>
<title>{$post.title}</title> <title>{$post.title}</title>
<link>{$config.domain}/posts/{$post.slug}.{$config.pageExt}</link> <link>{$config.domain}/{$post.path}</link>
<pubDate>{$post.date}</pubDate> <pubDate>{$post.date}</pubDate>
<author>{$config.author}</author> <author>{$config.author}</author>
<guid isPermaLink="true">{$config.domain}/posts/{$post.slug}.{$config.pageExt}</guid> <guid isPermaLink="true">{$config.domain}/{$post.path}</guid>
{foreach $tag in $post.tags} {foreach $tag in $post.tags}
<category><![CDATA[ {$tag.name |noAutoescape} ]]></category> <category><![CDATA[ {$tag.name |noAutoescape} ]]></category>
{/foreach} {/foreach}