Pārlūkot izejas kodu

Update hacking docs.

Brit Butler 11 gadi atpakaļ
vecāks
revīzija
eb0f1e23ab
2 mainītis faili ar 106 papildinājumiem un 54 dzēšanām
  1. 98 48
      docs/hacking.md
  2. 8 6
      src/packages.lisp

+ 98 - 48
docs/hacking.md

@@ -20,26 +20,70 @@ will checkout the repo to a **$TMPDIR** and call `(coleslaw:main $TMPDIR)`.
20 20
 
21 21
 It is then coleslaw's job to load all of your content, your config and
22 22
 templates, and render the content to disk. Deployment is done by
23
-updating a symlink and the default install assumes your webserver will
24
-be configured to serve from that symlink. However, there are plugins
25
-for deploying to Heroku, S3, and Github Pages.
23
+moving the files to a location specified in the config and updating a
24
+symlink.  It is assumed a web server is set up to serve from that
25
+symlink. However, there are plugins for deploying to Heroku, S3, and
26
+Github Pages.
26 27
 
27 28
 ### Blogs vs Sites
28 29
 
29 30
 **Coleslaw** is blogware. When I designed it, I only cared that it
30
-could replace my server's wordpress install. As a result, the code is
31
-still structured in terms of POSTs and INDEXes. Roughly speaking, a
32
-POST is a blog entry and an INDEX is a collection of POSTs or other
33
-content. An INDEX really only serves to group a set of content objects
34
-on a page, it isn't content itself.
31
+could replace my server's wordpress install. As a result, the code
32
+until very recently was structured in terms of POSTs and
33
+INDEXes. Roughly speaking, a POST is a blog entry and an INDEX is a
34
+collection of POSTs or other content. An INDEX really only serves to
35
+group a set of content objects on a page, it isn't content itself.
35 36
 
36 37
 This isn't ideal if you're looking for a full-on static site
37 38
 generator.  Content Types were added in 0.8 as a step towards making
38 39
 *coleslaw* suitable for more use cases but still have some
39
-limitations. Chiefly, the association between Content Types, their
40
-template, and their inclusion in an INDEX is presently ad-hoc.
40
+limitations. Any subclass of CONTENT that implements the *document
41
+protocol* counts as a content type. However, only POSTs are currently
42
+included on INDEXes since their isn't yet a formal relationship to
43
+determine what content types should be included on which indexes.
44
+
45
+### The Document Protocol
46
+
47
+The *document protocol* was born during a giant refactoring in 0.9.3.
48
+Any object that will be rendered to HTML should adhere to the protocol.
49
+Subclasses of CONTENT (content types) that implement the protocol will
50
+be seamlessly picked up by *coleslaw* and included on the rendered site.
51
+
52
+All current Content Types and Indexes implement the protocol faithfully.
53
+It consists of 2 "class" methods, 2 instance methods, and an invariant.
54
+
55
+
56
+* Class Methods:
57
+
58
+Since Common Lisp doesn't have explicit support for class methods, we
59
+implement them by eql-specializing on the class, e.g.
60
+```lisp
61
+(defmethod foo ((doc-type (eql (find-class 'bar))))
62
+  ... )
63
+```
64
+
65
+- `discover`: Create instances for documents of the class and put them in
66
+  in-memory database with `add-document`. If your class is a subclass of
67
+  CONTENT, there is a default method for this.
68
+- `publish`: Iterate over all objects of the class
69
+
70
+
71
+* Instance Methods:
72
+
73
+- `page-url`: Generate a unique, relative path for the object on the site
74
+  sans file extension. An :around method adds that later. The `slug` slot
75
+  on the object is generally used to hold a portion of the unique
76
+  identifier. i.e. `(format nil "posts/~a" (content-slug object))`.
77
+- `render`: A method that calls the appropriate template with `theme-fn`,
78
+  passing it any needed arguments and returning rendered HTML.
79
+
80
+
81
+* Invariants:
82
+
83
+- Any Content Types (subclasses of CONTENT) are expected to be stored in
84
+  the site's git repo with the lowercased class-name as a file extension,
85
+  i.e. (".post" for POST files).
41 86
 
42
-// TODO: Write something about the new Document Protocol!
43 87
 ### Current Content Types & Indexes
44 88
 
45 89
 There are 5 INDEX subclasses at present: TAG-INDEX, MONTH-INDEX,
@@ -50,8 +94,10 @@ Currently, there is only 1 content type: POST, for blog entries.
50 94
 
51 95
 I'm planning to add a content type PAGE, for static pages. It should
52 96
 be a pretty straightforward subclass of CONTENT with the necessary
53
-methods: `render`, `page-url` and `publish`, but will require a small
54
-tweak to prevent showing up in any INDEX.
97
+methods: `render`, `page-url` and `publish`. It could have a `url`
98
+slot with `page-url` as a reader to allow arbitrary layout on the site.
99
+The big question is how to handle templating and how indexes or other
100
+content should link to it.
55 101
 
56 102
 ### Templates and Theming
57 103
 
@@ -69,33 +115,32 @@ template file should contain a namespace like
69 115
 Each template creates a lisp function in the theme's package when
70 116
 loaded. These functions take a property list (or plist) as an argument
71 117
 and return rendered HTML.  **Coleslaw** defines a helper called
72
-`theme-fn` for easy access to the template functions.
118
+`theme-fn` for easy access to the template functions. Additionally,
119
+there are RSS, ATOM, and sitemap templates *coleslaw* uses automatically.
120
+No need for individual themes to reimplement a standard, after all!
73 121
 
74 122
 // TODO: Update for changes to compile-blog, indexes refactor, etc.
75 123
 ### The Lifecycle of a Page
76 124
 
77 125
 - `(load-content)`
78 126
 
79
-A page starts, obviously, with a file. When
80
-*coleslaw* loads your content, it iterates over a list of content
81
-types (i.e. subclasses of CONTENT).  For each content type, it
82
-iterates over all files in the repo with a matching extension,
83
-e.g. ".post" for POSTs. Objects of the appropriate class are created
84
-from each matching file and inserted into the `*content*` hash-table.
127
+A page starts, obviously, with a file. When *coleslaw* loads your
128
+content, it iterates over a list of content types (i.e. subclasses of
129
+CONTENT).  For each content type, it iterates over all files in the
130
+repo with a matching extension, e.g. ".post" for POSTs. Objects of the
131
+appropriate class are created from each matching file and inserted
132
+into the an in-memory data store. Then the INDEXes are created by
133
+iterating over the POSTs and inserted into the data store.
85 134
 
86 135
 - `(compile-blog dir)`
87 136
 
88
-
89 137
 Compilation starts by ensuring the staging directory (`/tmp/coleslaw/`
90 138
 by default) exists, cd'ing there, and copying over any necessary theme
91
-assets. Then *coleslaw* iterates over the content types, calling the
92
-`publish` method on each one. Publish creates any non-INDEX pages for
93
-the objects of that content type by iterating over the objects in an
94
-appropriate fashion, rendering them, and passing the result to
95
-`write-page` (which should probably just be renamed to `write-file`).
96
-
97
-After this, `render-indexes` is called, and an 'index.html' symlink
98
-is created to point to the first reverse chronological index.
139
+assets. Then *coleslaw* iterates over the content types and index classes,
140
+calling the `publish` method on each one. Publish iterates over the
141
+class instances, rendering each one and writing the result out to disk
142
+with `write-page` (which should probably just be renamed to `write-file`).
143
+After this, an 'index.html' symlink is created to point to the first index.
99 144
 
100 145
 - `(deploy dir)`
101 146
 
@@ -106,17 +151,29 @@ freshly built site.
106 151
 
107 152
 ## Areas for Improvement
108 153
 
109
-### render-foo* functions could be abstracted out
110
-// TODO
154
+### Render Function Cleanup
111 155
 
112
-### user-defined routing
113
-// TODO
156
+There are currently 3 render-foo* functions and 3 implementations of the
157
+render method. Only the render-foo* functions call `write-page` so there
158
+should be some room for cleanup here. The render method implementations
159
+are probably necessary unless we want to start storing their arguments
160
+on the models. There may be a different way to abstract the data flow.
161
+
162
+### User-Defined Routing
163
+
164
+There is no reason *coleslaw* should be in charge of the site layout or
165
+should care. If all objects only used the *slug* slot in their `page-url`
166
+methods, there could be a :routing argument in the config containing
167
+a plist of `(:class "~{format string~}")` pairs. A default method could
168
+check the :class key under `(routing *config*)` if no specialized
169
+`page-url` was defined. This would have the additional benefit of
170
+localizing all the site routing in one place. New Content Types would
171
+probably `pushnew` a plist onto the config key in their `enable` function.
114 172
 
115 173
 ### Better Content Types
116
-// TODO: Update to discuss Document Protocol.
117 174
 
118
-Creating a new content type should be both straightforward and doable
119
-as a plugin. All that is really required is a subclass of CONTENT with
175
+Creating a new content type is both straightforward and doable as a
176
+plugin. All that is really required is a subclass of CONTENT with
120 177
 any needed slots, a template, a `render` method to call the template
121 178
 with any needed options, a `page-url` method for layout, and a
122 179
 `publish` method.
@@ -126,10 +183,12 @@ Unfortunately, this does not solve:
126 183
 1. The issue of compiling the template at load-time and making sure it
127 184
    was installed in the theme package. The plugin would need to do
128 185
    this itself or the template would need to be included in 'core'.
186
+   Thankfully, this should be easy with *cl-closure-template*.
129 187
 2. More seriously, there is no formal relationship between content
130
-   types and indexes. Indexes include *ALL* objects in the `*content*`
131
-   hash table. This may be undesirable and doesn't permit indexes
132
-   dedicated to particular content types.
188
+   types and indexes. Consequentially, INDEXes include only POST
189
+   objects at the moment. Whether the INDEX should specify what
190
+   Content Types it includes or the CONTENT which indexes it appears
191
+   on is not yet clear.
133 192
 
134 193
 ### New Content Type: Shouts!
135 194
 
@@ -141,15 +200,6 @@ tabs or stored on twitter's servers. It would be cool to see SHOUTs as
141 200
 a plugin, probably with a dedicated SHOUT-INDEX, and some sort of
142 201
 oEmbed/embed.ly/noembed support.
143 202
 
144
-### Layouts and Paths
145
-
146
-Defining a page-url for every content-object and index seems a bit
147
-silly. It also spreads information about the site layout throughout
148
-the codebase, it might be better to have a slot in the config that
149
-defines this information with a key to go with each format string.
150
-Adding a new content-type as a plugin could then provide a default
151
-by banging on the config or specify the path in its `enable` options.
152
-
153 203
 ### Incremental Compilation
154 204
 
155 205
 Incremental compilation is doable, even straightforward if you ignore

+ 8 - 6
src/packages.lisp

@@ -10,14 +10,16 @@
10 10
   (:export #:main
11 11
            #:preview
12 12
            #:*config*
13
-           #:blog
14 13
            #:content
15 14
            #:post
16 15
            #:index
17
-           #:page-path
16
+           #:render-content
17
+           #:add-injection
18
+           ;; The Document Protocol
19
+           #:add-document
20
+           #:find-all
21
+           #:purge-all
18 22
            #:discover
19 23
            #:publish
20
-           #:render
21
-           #:render-content
22
-           #:read-content
23
-           #:add-injection))
24
+           #:page-url
25
+           #:render))