Merge pull request #47 from redline6561/user-defined-routing
User defined routing
This commit is contained in:
commit
40d6e5bb2c
8 changed files with 42 additions and 40 deletions
10
NEWS.md
10
NEWS.md
|
@ -1,5 +1,10 @@
|
||||||
## Changes for 0.9.4 (2013-05-05):
|
## Changes for 0.9.4 (2013-05-05):
|
||||||
|
|
||||||
|
* **SITE-BREAKING CHANGE**: Coleslaw now supports user-defined routing.
|
||||||
|
Instead of hard-coding the paths various content types are stored at,
|
||||||
|
they must be specified in the configuration file (.coleslawrc). Just
|
||||||
|
copy the `:routing` key from the [example][single_site.rc] to get
|
||||||
|
the old behavior.
|
||||||
* Coleslaw no longer expects a particular repo layout. Use whatever
|
* Coleslaw no longer expects a particular repo layout. Use whatever
|
||||||
directory hierarchy you like.
|
directory hierarchy you like.
|
||||||
|
|
||||||
|
@ -69,5 +74,6 @@
|
||||||
|
|
||||||
* Initial release.
|
* Initial release.
|
||||||
|
|
||||||
[hacking_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md
|
[hacking_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md
|
||||||
[theming_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/themes.md
|
[theming_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/themes.md
|
||||||
|
[single_site.rc]: https://github.com/redline6561/coleslaw/blob/master/examples/single-site.coleslawrc
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
(defsystem #:coleslaw
|
(defsystem #:coleslaw
|
||||||
:name "coleslaw"
|
:name "coleslaw"
|
||||||
:description "Flexible Lisp Blogware"
|
:description "Flexible Lisp Blogware"
|
||||||
:version "0.9.3"
|
:version "0.9.4-dev"
|
||||||
:license "BSD"
|
:license "BSD"
|
||||||
:author "Brit Butler <redline6561@gmail.com>"
|
:author "Brit Butler <redline6561@gmail.com>"
|
||||||
:pathname "src/"
|
:pathname "src/"
|
||||||
|
|
|
@ -74,7 +74,7 @@ implement them by eql-specializing on the class, e.g.
|
||||||
|
|
||||||
- `page-url`: Generate a unique, relative path for the object on the site
|
- `page-url`: Generate a unique, relative path for the object on the site
|
||||||
sans file extension. An :around method adds that later. The `slug` slot
|
sans file extension. An :around method adds that later. The `slug` slot
|
||||||
on the object is generally used to hold a portion of the unique
|
on the object is conventionally used to hold a portion of the unique
|
||||||
identifier. i.e. `(format nil "posts/~a" (content-slug object))`.
|
identifier. i.e. `(format nil "posts/~a" (content-slug object))`.
|
||||||
- `render`: A method that calls the appropriate template with `theme-fn`,
|
- `render`: A method that calls the appropriate template with `theme-fn`,
|
||||||
passing it any needed arguments and returning rendered HTML.
|
passing it any needed arguments and returning rendered HTML.
|
||||||
|
@ -176,18 +176,6 @@ changes to at least the post templates and the `read-content`
|
||||||
function. There may be other areas where it was assumed tags/dates
|
function. There may be other areas where it was assumed tags/dates
|
||||||
will always be present.
|
will always be present.
|
||||||
|
|
||||||
### User-Defined Routing
|
|
||||||
|
|
||||||
There is no reason *coleslaw* should be in charge of the site layout or
|
|
||||||
should care. If all objects only used the *slug* slot in their `page-url`
|
|
||||||
methods, there could be a :routing argument in the config containing
|
|
||||||
a plist of `(:class "~{format string~}")` pairs. A default method could
|
|
||||||
check the :class key under `(routing *config*)` if no specialized
|
|
||||||
`page-url` was defined. This would have the additional benefit of
|
|
||||||
localizing all the site routing in one place. New Content Types would
|
|
||||||
probably `pushnew` a plist onto the config key in their `enable` function.
|
|
||||||
This has been implemented on the branch `user-defined-routing`.
|
|
||||||
|
|
||||||
### New Content Type: Pages!
|
### New Content Type: Pages!
|
||||||
|
|
||||||
Many users have requested a content type PAGE, for static pages. It
|
Many users have requested a content type PAGE, for static pages. It
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
:domain "http://blub.co.za"
|
:domain "http://blub.co.za"
|
||||||
:feeds ("lisp")
|
:feeds ("lisp")
|
||||||
:plugins ((mathjax))
|
:plugins ((mathjax))
|
||||||
|
:routing ((:post "posts/~a")
|
||||||
|
(:tag-index "tag/~a")
|
||||||
|
(:month-index "date/~a")
|
||||||
|
(:numeric-index "~d")
|
||||||
|
(:feed "~a.xml")
|
||||||
|
(:tag-feed "tag/~a.xml"))
|
||||||
:sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
|
:sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
|
||||||
(:url "http://github.com/ralph-moeritz" :name "Code"))
|
(:url "http://github.com/ralph-moeritz" :name "Code"))
|
||||||
:staging-dir "/tmp/coleslaw"
|
:staging-dir "/tmp/coleslaw"
|
||||||
|
@ -13,6 +19,12 @@
|
||||||
:domain "http://musings.co.za"
|
:domain "http://musings.co.za"
|
||||||
:feeds ("opinion")
|
:feeds ("opinion")
|
||||||
:plugins ((mathjax))
|
:plugins ((mathjax))
|
||||||
|
:routing ((:post "posts/~a")
|
||||||
|
(:tag-index "tag/~a")
|
||||||
|
(:month-index "date/~a")
|
||||||
|
(:numeric-index "~d")
|
||||||
|
(:feed "~a.xml")
|
||||||
|
(:tag-feed "tag/~a.xml"))
|
||||||
:sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
|
:sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
|
||||||
(:url "http://github.com/ralph-moeritz" :name "Code"))
|
(:url "http://github.com/ralph-moeritz" :name "Code"))
|
||||||
:staging-dir "/tmp/coleslaw"
|
:staging-dir "/tmp/coleslaw"
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
(disqus :shortname "my-site-name")
|
(disqus :shortname "my-site-name")
|
||||||
(analytics :tracking-code "foo"))
|
(analytics :tracking-code "foo"))
|
||||||
:repo "/home/git/tmp/improvedmeans/"
|
:repo "/home/git/tmp/improvedmeans/"
|
||||||
|
:routing ((:post "posts/~a")
|
||||||
|
(:tag-index "tag/~a")
|
||||||
|
(:month-index "date/~a")
|
||||||
|
(:numeric-index "~d")
|
||||||
|
(:feed "~a.xml")
|
||||||
|
(:tag-feed "tag/~a.xml"))
|
||||||
:sitenav ((:url "http://redlinernotes.com/" :name "Home")
|
:sitenav ((:url "http://redlinernotes.com/" :name "Home")
|
||||||
(:url "http://twitter.com/redline6561" :name "Twitter")
|
(:url "http://twitter.com/redline6561" :name "Twitter")
|
||||||
(:url "http://github.com/redline6561" :name "Code")
|
(:url "http://github.com/redline6561" :name "Code")
|
||||||
|
|
|
@ -27,7 +27,13 @@
|
||||||
;; Instance Methods
|
;; Instance Methods
|
||||||
|
|
||||||
(defgeneric page-url (document)
|
(defgeneric page-url (document)
|
||||||
(:documentation "The url to the DOCUMENT without the domain."))
|
(:documentation "The url to the DOCUMENT without the domain.")
|
||||||
|
(:method (document)
|
||||||
|
(let* ((class-name (class-name (class-of document)))
|
||||||
|
(route (assoc class-name (routing *config*))))
|
||||||
|
(if route
|
||||||
|
(format nil (second route) (slot-value document 'slug))
|
||||||
|
(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)))
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
|
|
||||||
(defclass tag-index (index) ())
|
(defclass tag-index (index) ())
|
||||||
|
|
||||||
(defmethod page-url ((object tag-index))
|
|
||||||
(format nil "tag/~a" (index-slug object)))
|
|
||||||
|
|
||||||
(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))
|
||||||
|
@ -39,9 +36,6 @@
|
||||||
|
|
||||||
(defclass month-index (index) ())
|
(defclass month-index (index) ())
|
||||||
|
|
||||||
(defmethod page-url ((object month-index))
|
|
||||||
(format nil "date/~a" (index-slug object)))
|
|
||||||
|
|
||||||
(defmethod discover ((doc-type (eql (find-class 'month-index))))
|
(defmethod discover ((doc-type (eql (find-class 'month-index))))
|
||||||
(let ((content (by-date (find-all 'post))))
|
(let ((content (by-date (find-all 'post))))
|
||||||
(dolist (month (all-months))
|
(dolist (month (all-months))
|
||||||
|
@ -61,9 +55,6 @@
|
||||||
|
|
||||||
(defclass numeric-index (index) ())
|
(defclass numeric-index (index) ())
|
||||||
|
|
||||||
(defmethod page-url ((object numeric-index))
|
|
||||||
(format nil "~d" (index-slug object)))
|
|
||||||
|
|
||||||
(defmethod discover ((doc-type (eql (find-class 'numeric-index))))
|
(defmethod discover ((doc-type (eql (find-class 'numeric-index))))
|
||||||
(let ((content (by-date (find-all 'post))))
|
(let ((content (by-date (find-all 'post))))
|
||||||
(dotimes (i (ceiling (length content) 10))
|
(dotimes (i (ceiling (length content) 10))
|
||||||
|
@ -90,13 +81,12 @@
|
||||||
(defclass feed (index)
|
(defclass feed (index)
|
||||||
((format :initform nil :initarg :format :accessor feed-format)))
|
((format :initform nil :initarg :format :accessor feed-format)))
|
||||||
|
|
||||||
(defmethod page-url ((object feed))
|
|
||||||
(format nil "~(~a~).xml" (feed-format object)))
|
|
||||||
|
|
||||||
(defmethod discover ((doc-type (eql (find-class 'feed))))
|
(defmethod discover ((doc-type (eql (find-class 'feed))))
|
||||||
(let ((content (take-up-to 10 (by-date (find-all 'post)))))
|
(let ((content (by-date (find-all 'post))))
|
||||||
(dolist (format '(rss atom))
|
(dolist (format '(rss atom))
|
||||||
(let ((feed (make-instance 'feed :content content :format format)))
|
(let ((feed (make-instance 'feed :format format
|
||||||
|
:content (take-up-to 10 content)
|
||||||
|
:slug (format nil "~(~a~)" format))))
|
||||||
(add-document feed)))))
|
(add-document feed)))))
|
||||||
|
|
||||||
(defmethod publish ((doc-type (eql (find-class 'feed))))
|
(defmethod publish ((doc-type (eql (find-class 'feed))))
|
||||||
|
@ -107,17 +97,14 @@
|
||||||
|
|
||||||
(defclass tag-feed (feed) ())
|
(defclass tag-feed (feed) ())
|
||||||
|
|
||||||
(defmethod page-url ((object tag-feed))
|
|
||||||
(format nil "tag/~a~(~a~).xml" (index-slug object) (feed-format object)))
|
|
||||||
|
|
||||||
(defmethod discover ((doc-type (eql (find-class 'tag-feed))))
|
(defmethod discover ((doc-type (eql (find-class 'tag-feed))))
|
||||||
(let ((content (by-date (find-all 'post))))
|
(let ((content (by-date (find-all 'post))))
|
||||||
(dolist (tag (feeds *config*))
|
(dolist (tag (feeds *config*))
|
||||||
(let ((tagged (remove-if-not (lambda (x) (tag-p tag x)) content)))
|
(let ((tagged (remove-if-not (lambda (x) (tag-p tag x)) content)))
|
||||||
(dolist (format '(rss atom))
|
(dolist (format '(rss atom))
|
||||||
(let ((feed (make-instance 'tag-feed :content (take-up-to 10 tagged)
|
(let ((feed (make-instance 'tag-feed :format format
|
||||||
:format format
|
:content (take-up-to 10 tagged)
|
||||||
:slug tag)))
|
:slug (format nil "~a-~(~a~)" tag format))))
|
||||||
(add-document feed)))))))
|
(add-document feed)))))))
|
||||||
|
|
||||||
(defmethod publish ((doc-type (eql (find-class 'tag-feed))))
|
(defmethod publish ((doc-type (eql (find-class 'tag-feed))))
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
:prev prev
|
:prev prev
|
||||||
:next next)))
|
:next next)))
|
||||||
|
|
||||||
(defmethod page-url ((object post))
|
|
||||||
(format nil "posts/~a" (content-slug object)))
|
|
||||||
|
|
||||||
(defmethod publish ((doc-type (eql (find-class 'post))))
|
(defmethod publish ((doc-type (eql (find-class 'post))))
|
||||||
(loop for (next post prev) on (append '(nil) (by-date (find-all 'post)))
|
(loop for (next post prev) on (append '(nil) (by-date (find-all 'post)))
|
||||||
while post do (write-document post nil :prev prev :next next)))
|
while post do (write-document post nil :prev prev :next next)))
|
||||||
|
|
Loading…
Add table
Reference in a new issue