Просмотр исходного кода

Merge pull request #47 from redline6561/user-defined-routing

User defined routing
Brit Butler лет назад: 11
Родитель
Сommit
40d6e5bb2c
8 измененных файлов с 42 добавлено и 40 удалено
  1. 8 2
      NEWS.md
  2. 1 1
      coleslaw.asd
  3. 1 13
      docs/hacking.md
  4. 12 0
      examples/multi-site.coleslawrc
  5. 6 0
      examples/single-site.coleslawrc
  6. 7 1
      src/documents.lisp
  7. 7 20
      src/indexes.lisp
  8. 0 3
      src/posts.lisp

+ 8 - 2
NEWS.md

@@ -1,5 +1,10 @@
1 1
 ## Changes for 0.9.4 (2013-05-05):
2 2
 
3
+* **SITE-BREAKING CHANGE**: Coleslaw now supports user-defined routing.
4
+  Instead of hard-coding the paths various content types are stored at,
5
+  they must be specified in the configuration file (.coleslawrc). Just
6
+  copy the `:routing` key from the [example][single_site.rc] to get
7
+  the old behavior.
3 8
 * Coleslaw no longer expects a particular repo layout. Use whatever
4 9
   directory hierarchy you like.
5 10
 
@@ -69,5 +74,6 @@
69 74
 
70 75
 * Initial release.
71 76
 
72
-[hacking_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md
73
-[theming_guide]: https://github.com/redline6561/coleslaw/blob/master/docs/themes.md
77
+[hacking_guide]:  https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md
78
+[theming_guide]:  https://github.com/redline6561/coleslaw/blob/master/docs/themes.md
79
+[single_site.rc]: https://github.com/redline6561/coleslaw/blob/master/examples/single-site.coleslawrc

+ 1 - 1
coleslaw.asd

@@ -1,7 +1,7 @@
1 1
 (defsystem #:coleslaw
2 2
   :name "coleslaw"
3 3
   :description "Flexible Lisp Blogware"
4
-  :version "0.9.3"
4
+  :version "0.9.4-dev"
5 5
   :license "BSD"
6 6
   :author "Brit Butler <redline6561@gmail.com>"
7 7
   :pathname "src/"

+ 1 - 13
docs/hacking.md

@@ -74,7 +74,7 @@ implement them by eql-specializing on the class, e.g.
74 74
 
75 75
 - `page-url`: Generate a unique, relative path for the object on the site
76 76
   sans file extension. An :around method adds that later. The `slug` slot
77
-  on the object is generally used to hold a portion of the unique
77
+  on the object is conventionally used to hold a portion of the unique
78 78
   identifier. i.e. `(format nil "posts/~a" (content-slug object))`.
79 79
 - `render`: A method that calls the appropriate template with `theme-fn`,
80 80
   passing it any needed arguments and returning rendered HTML.
@@ -176,18 +176,6 @@ changes to at least the post templates and the `read-content`
176 176
 function. There may be other areas where it was assumed tags/dates
177 177
 will always be present.
178 178
 
179
-### User-Defined Routing
180
-
181
-There is no reason *coleslaw* should be in charge of the site layout or
182
-should care. If all objects only used the *slug* slot in their `page-url`
183
-methods, there could be a :routing argument in the config containing
184
-a plist of `(:class "~{format string~}")` pairs. A default method could
185
-check the :class key under `(routing *config*)` if no specialized
186
-`page-url` was defined. This would have the additional benefit of
187
-localizing all the site routing in one place. New Content Types would
188
-probably `pushnew` a plist onto the config key in their `enable` function.
189
-This has been implemented on the branch `user-defined-routing`.
190
-
191 179
 ### New Content Type: Pages!
192 180
 
193 181
 Many users have requested a content type PAGE, for static pages. It

+ 12 - 0
examples/multi-site.coleslawrc

@@ -3,6 +3,12 @@
3 3
                                       :domain "http://blub.co.za"
4 4
                                       :feeds ("lisp")
5 5
                                       :plugins ((mathjax))
6
+                                      :routing ((:post           "posts/~a")
7
+                                                (:tag-index      "tag/~a")
8
+                                                (:month-index    "date/~a")
9
+                                                (:numeric-index  "~d")
10
+                                                (:feed           "~a.xml")
11
+                                                (:tag-feed       "tag/~a.xml"))
6 12
                                       :sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
7 13
                                                 (:url "http://github.com/ralph-moeritz" :name "Code"))
8 14
                                       :staging-dir "/tmp/coleslaw"
@@ -13,6 +19,12 @@
13 19
                                   :domain "http://musings.co.za"
14 20
                                   :feeds ("opinion")
15 21
                                   :plugins ((mathjax))
22
+                                  :routing ((:post           "posts/~a")
23
+                                            (:tag-index      "tag/~a")
24
+                                            (:month-index    "date/~a")
25
+                                            (:numeric-index  "~d")
26
+                                            (:feed           "~a.xml")
27
+                                            (:tag-feed       "tag/~a.xml"))
16 28
                                   :sitenav ((:url "http://twitter.com/ralph_moeritz" :name "Twitter")
17 29
                                             (:url "http://github.com/ralph-moeritz" :name "Code"))
18 30
                                   :staging-dir "/tmp/coleslaw"

+ 6 - 0
examples/single-site.coleslawrc

@@ -7,6 +7,12 @@
7 7
            (disqus :shortname "my-site-name")
8 8
            (analytics :tracking-code "foo"))
9 9
  :repo "/home/git/tmp/improvedmeans/"
10
+ :routing ((:post           "posts/~a")
11
+           (:tag-index      "tag/~a")
12
+           (:month-index    "date/~a")
13
+           (:numeric-index  "~d")
14
+           (:feed           "~a.xml")
15
+           (:tag-feed       "tag/~a.xml"))
10 16
  :sitenav ((:url "http://redlinernotes.com/" :name "Home")
11 17
            (:url "http://twitter.com/redline6561" :name "Twitter")
12 18
            (:url "http://github.com/redline6561" :name "Code")

+ 7 - 1
src/documents.lisp

@@ -27,7 +27,13 @@
27 27
 ;; Instance Methods
28 28
 
29 29
 (defgeneric page-url (document)
30
-  (:documentation "The url to the DOCUMENT without the domain."))
30
+  (:documentation "The url to the DOCUMENT without the domain.")
31
+  (:method (document)
32
+    (let* ((class-name (class-name (class-of document)))
33
+           (route (assoc class-name (routing *config*))))
34
+      (if route
35
+          (format nil (second route) (slot-value document 'slug))
36
+          (error "No routing method found for: ~A" class-name)))))
31 37
 
32 38
 (defmethod page-url :around ((document t))
33 39
   (let ((result (call-next-method)))

+ 7 - 20
src/indexes.lisp

@@ -17,9 +17,6 @@
17 17
 
18 18
 (defclass tag-index (index) ())
19 19
 
20
-(defmethod page-url ((object tag-index))
21
-  (format nil "tag/~a" (index-slug object)))
22
-
23 20
 (defmethod discover ((doc-type (eql (find-class 'tag-index))))
24 21
   (let ((content (by-date (find-all 'post))))
25 22
     (dolist (tag (all-tags))
@@ -39,9 +36,6 @@
39 36
 
40 37
 (defclass month-index (index) ())
41 38
 
42
-(defmethod page-url ((object month-index))
43
-  (format nil "date/~a" (index-slug object)))
44
-
45 39
 (defmethod discover ((doc-type (eql (find-class 'month-index))))
46 40
   (let ((content (by-date (find-all 'post))))
47 41
     (dolist (month (all-months))
@@ -61,9 +55,6 @@
61 55
 
62 56
 (defclass numeric-index (index) ())
63 57
 
64
-(defmethod page-url ((object numeric-index))
65
-  (format nil "~d" (index-slug object)))
66
-
67 58
 (defmethod discover ((doc-type (eql (find-class 'numeric-index))))
68 59
   (let ((content (by-date (find-all 'post))))
69 60
     (dotimes (i (ceiling (length content) 10))
@@ -90,13 +81,12 @@
90 81
 (defclass feed (index)
91 82
   ((format :initform nil :initarg :format :accessor feed-format)))
92 83
 
93
-(defmethod page-url ((object feed))
94
-  (format nil "~(~a~).xml" (feed-format object)))
95
-
96 84
 (defmethod discover ((doc-type (eql (find-class 'feed))))
97
-  (let ((content (take-up-to 10 (by-date (find-all 'post)))))
85
+  (let ((content (by-date (find-all 'post))))
98 86
     (dolist (format '(rss atom))
99
-      (let ((feed (make-instance 'feed :content content :format format)))
87
+      (let ((feed (make-instance 'feed :format format
88
+                                 :content (take-up-to 10 content)
89
+                                 :slug (format nil "~(~a~)" format))))
100 90
         (add-document feed)))))
101 91
 
102 92
 (defmethod publish ((doc-type (eql (find-class 'feed))))
@@ -107,17 +97,14 @@
107 97
 
108 98
 (defclass tag-feed (feed) ())
109 99
 
110
-(defmethod page-url ((object tag-feed))
111
-  (format nil "tag/~a~(~a~).xml" (index-slug object) (feed-format object)))
112
-
113 100
 (defmethod discover ((doc-type (eql (find-class 'tag-feed))))
114 101
   (let ((content (by-date (find-all 'post))))
115 102
     (dolist (tag (feeds *config*))
116 103
       (let ((tagged (remove-if-not (lambda (x) (tag-p tag x)) content)))
117 104
         (dolist (format '(rss atom))
118
-          (let ((feed (make-instance 'tag-feed :content (take-up-to 10 tagged)
119
-                                     :format format
120
-                                     :slug tag)))
105
+          (let ((feed (make-instance 'tag-feed :format format
106
+                                     :content (take-up-to 10 tagged)
107
+                                     :slug (format nil "~a-~(~a~)" tag format))))
121 108
             (add-document feed)))))))
122 109
 
123 110
 (defmethod publish ((doc-type (eql (find-class 'tag-feed))))

+ 0 - 3
src/posts.lisp

@@ -21,9 +21,6 @@
21 21
                                   :prev prev
22 22
                                   :next next)))
23 23
 
24
-(defmethod page-url ((object post))
25
-  (format nil "posts/~a" (content-slug object)))
26
-
27 24
 (defmethod publish ((doc-type (eql (find-class 'post))))
28 25
   (loop for (next post prev) on (append '(nil) (by-date (find-all 'post)))
29 26
      while post do (write-document post nil :prev prev :next next)))