Преглед изворни кода

Merge pull request #48 from redline6561/static-pages

Static pages
Brit Butler пре 11 година
родитељ
комит
4e6efa9d9e
7 измењених фајлова са 70 додато и 34 уклоњено
  1. 8 0
      NEWS.md
  2. 0 19
      docs/hacking.md
  3. 32 0
      plugins/static-pages.lisp
  4. 8 4
      src/content.lisp
  5. 1 0
      src/packages.lisp
  6. 9 5
      themes/hyde/post.tmpl
  7. 12 6
      themes/readable/post.tmpl

+ 8 - 0
NEWS.md

@@ -7,6 +7,14 @@
7 7
   the old behavior.
8 8
 * Coleslaw no longer expects a particular repo layout. Use whatever
9 9
   directory hierarchy you like.
10
+* New Content Type Plugin: Static Pages, accepting a title, url, and
11
+  optionally tags and a date. All files with a `.page` extension are
12
+  compiled as static pages and reuse the POST template.
13
+  To enable Static Pages, add `(static-pages)` to the `:plugins`
14
+  section of your config.
15
+* Coleslaw now allows content without a date or tags. Note that POSTs
16
+  without a date will still show up in the reverse chronological
17
+  indexes at the very end.
10 18
 
11 19
 ## Changes for 0.9.3 (2013-04-16):
12 20
 

+ 0 - 19
docs/hacking.md

@@ -168,25 +168,6 @@ freshly built site.
168 168
 
169 169
 ## Areas for Improvement
170 170
 
171
-### Allow Tagless or Dateless Content
172
-
173
-Several users have expected to be able to not supply tags or a date
174
-for their content. This is a reasonable expectation and requires
175
-changes to at least the post templates and the `read-content`
176
-function. There may be other areas where it was assumed tags/dates
177
-will always be present.
178
-
179
-### New Content Type: Pages!
180
-
181
-Many users have requested a content type PAGE, for static pages. It
182
-should be a pretty straightforward subclass of CONTENT with the
183
-necessary methods: `render`, `page-url` and `publish`. It could have a
184
-`url` slot with `page-url` as a reader to allow arbitrary layout on
185
-the site.  For now, we can be sloppy and reuse the post template and
186
-limit static-pages to being written in markdown. If we want to support
187
-other formats, consider moving the format slot from POST to CONTENT.
188
-This has been implemented on the branch `static-pages`.
189
-
190 171
 ### New Content Type: Shouts!
191 172
 
192 173
 I've also toyed with the idea of a content type called a SHOUT, which

+ 32 - 0
plugins/static-pages.lisp

@@ -0,0 +1,32 @@
1
+(defpackage :coleslaw-static-pages
2
+  (:use :cl)
3
+  (:export #:enable)
4
+  (:import-from :coleslaw #:*config*
5
+                          #:content
6
+                          #:page-url
7
+                          #:find-all
8
+                          #:render
9
+                          #:publish
10
+                          #:write-document))
11
+
12
+(in-package :coleslaw-static-pages)
13
+
14
+(defclass page (content)
15
+  ((title :initarg :title :reader page-title)
16
+   (url :initarg :url :reader page-url)))
17
+
18
+(defmethod initialize-instance :after ((object page) &key)
19
+  ;; Expect all static-pages to be written in Markdown for now.
20
+  (with-accessors ((text content-text)) object
21
+    (setf text (render-text text :md))))
22
+
23
+(defmethod render ((object page) &key next prev)
24
+  ;; For the time being, we'll re-use the normal post theme.
25
+  (funcall (theme-fn 'post) (list :config *config*
26
+                                  :post object)))
27
+
28
+(defmethod publish ((doc-type (eql (find-class 'page))))
29
+  (dolist (page (find-all 'page))
30
+    (write-document page)))
31
+
32
+(defun enable ())

+ 8 - 4
src/content.lisp

@@ -36,6 +36,11 @@
36 36
    (date :initform nil :initarg :date :accessor content-date)
37 37
    (text :initform nil :initarg :text :accessor content-text)))
38 38
 
39
+(defmethod initialize-instance :after ((object content) &key)
40
+  (with-accessors ((tags content-tags)) object
41
+    (when (stringp tags)
42
+      (setf tags (mapcar #'make-tag (cl-ppcre:split "," tags))))))
43
+
39 44
 (defun read-content (file)
40 45
   "Returns a plist of metadata from FILE with :text holding the content as a string."
41 46
   (flet ((slurp-remainder (stream)
@@ -46,9 +51,7 @@
46 51
          (parse-field (str)
47 52
            (nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+: (.*)" str)))
48 53
          (field-name (line)
49
-           (make-keyword (string-upcase (subseq line 0 (position #\: line)))))
50
-         (read-tags (str)
51
-           (mapcar #'make-tag (cl-ppcre:split "," str))))
54
+           (make-keyword (string-upcase (subseq line 0 (position #\: line))))))
52 55
     (with-open-file (in file :external-format '(:utf-8))
53 56
       (unless (string= (read-line in) (separator *config*))
54 57
         (error "The provided file lacks the expected header."))
@@ -57,9 +60,10 @@
57 60
                      appending (list (field-name line)
58 61
                                      (aref (parse-field line) 0))))
59 62
             (content (slurp-remainder in)))
60
-        (setf (getf meta :tags) (read-tags (getf meta :tags)))
61 63
         (append meta (list :text content))))))
62 64
 
65
+;; Helper Functions
66
+
63 67
 (defun tag-p (tag obj)
64 68
   "Test if OBJ is tagged with TAG."
65 69
   (let ((tag (if (typep tag 'tag) tag (make-tag tag))))

+ 1 - 0
src/packages.lisp

@@ -15,6 +15,7 @@
15 15
            #:index
16 16
            #:render-text
17 17
            #:add-injection
18
+           #:theme-fn
18 19
            ;; The Document Protocol
19 20
            #:add-document
20 21
            #:find-all

+ 9 - 5
themes/hyde/post.tmpl

@@ -4,13 +4,17 @@
4 4
 <div class="article-meta">{\n}
5 5
   <h1 class="title">{$post.title}</h1>{\n}
6 6
   <div class="tags">{\n}
7
-    Tagged as {foreach $tag in $post.tags}
8
-                <a href="../tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil}
9
-                    {if not isLast($tag)},{sp}{/if}
10
-              {/foreach}
7
+    {if $post.tags}
8
+      Tagged as {foreach $tag in $post.tags}
9
+        <a href="../tag/{$tag.slug}.{$config.pageExt}">{$tag.name}</a>{nil}
10
+          {if not isLast($tag)},{sp}{/if}
11
+      {/foreach}
12
+    {/if}
11 13
   </div>{\n}
12 14
   <div class="date">{\n}
13
-    Written on {$post.date}
15
+    {if $post.date}
16
+      Written on {$post.date}
17
+    {/if}
14 18
   </div>{\n}
15 19
 </div>{\n}
16 20
 <div class="article-content">{\n}

+ 12 - 6
themes/readable/post.tmpl

@@ -3,13 +3,19 @@
3 3
 {template post}
4 4
 <div class="row-fluid">{\n}
5 5
   <h1 class="page-header">{$post.title}</h1>{\n}
6
-  <p>Tagged as 
7
-    {foreach $tag in $post.tags}
8
-      <a href="../tag/{$tag.slug}{$config.pageExt}">{$tag.name}</a>{nil}
9
-      {if not isLast($tag)},{sp}{/if}
10
-    {/foreach}
6
+  <p>
7
+    {if $post.tags}
8
+      Tagged as {foreach $tag in $post.tags}
9
+        <a href="../tag/{$tag.slug}{$config.pageExt}">{$tag.name}</a>{nil}
10
+          {if not isLast($tag)},{sp}{/if}
11
+      {/foreach}
12
+    {/if}
13
+  </p>
14
+  <p class="date-posted">
15
+    {if $post.date}
16
+      Written on {$post.date}
17
+    {/if}
11 18
   </p>
12
-  <p class="date-posted">Written on {$post.date}</p>
13 19
 
14 20
   {$post.text |noAutoescape}
15 21