ソースを参照

Go through HACKING docs with a fine tooth comb.

Brit Butler 11 年 前
コミット
96d85c8e69
共有2 個のファイルを変更した112 個の追加130 個の削除を含む
  1. 112 74
      docs/hacking.md
  2. 0 56
      docs/overview.md

+ 112 - 74
docs/hacking.md

@@ -7,6 +7,22 @@ the idea to each complete their half-dreamed wordpress replacement in
7 7
 a week. Though it has evolved considerably since it's inception, like
8 8
 any software some mess remains.
9 9
 
10
+## Overall Structure
11
+
12
+Conceptually, coleslaw processes a blog as follows:
13
+
14
+1.  Coleslaw loads the user's config, then reads the blog repo loading
15
+    any `.post` files or other content. CONTENT and INDEX objects are
16
+    created from those files.
17
+
18
+2.  The CONTENT and INDEX objects are then fed to the templating engine
19
+    to produce HTML files in a config-specified staging directory,
20
+    usually under `/tmp`.
21
+
22
+3.  A deploy method (possibly customized via plugins) is called with the
23
+    staging directory. It does whatever work is needed to make the
24
+    generated HTML files (and any static content) visible to the web.
25
+
10 26
 ## Core Concepts
11 27
 
12 28
 ### Data and Deployment
@@ -14,8 +30,7 @@ any software some mess remains.
14 30
 **Coleslaw** is pretty fundamentally tied to the idea of git as both a
15 31
 backing data store and a deployment method (via `git push`). The
16 32
 consequence is that you need a bare repo somewhere with a post-recieve
17
-hook. That post-recieve hook
18
-([example](https://github.com/redline6561/coleslaw/blob/master/examples/example.post-receive))
33
+hook. That post-recieve hook ([example][post_receive_hook])
19 34
 will checkout the repo to a **$TMPDIR** and call `(coleslaw:main $TMPDIR)`.
20 35
 
21 36
 It is then coleslaw's job to load all of your content, your config and
@@ -25,6 +40,60 @@ symlink.  It is assumed a web server is set up to serve from that
25 40
 symlink. However, there are plugins for deploying to Heroku, S3, and
26 41
 Github Pages.
27 42
 
43
+### Plugins
44
+
45
+**Coleslaw** strongly encourages extending functionality via plugins.
46
+The Plugin API is well-documented and flexible enough for many use
47
+cases. Do check the [API docs][api_docs] when contemplating a new
48
+feature and see if a plugin would be appropriate.
49
+
50
+### Templates and Theming
51
+
52
+User configs are allowed to specify a theme. A theme consists of a
53
+directory under "themes/" containing css, images, and at least
54
+3 templates: Base, Index, and Post.
55
+
56
+**Coleslaw** uses [cl-closure-template][closure_template]
57
+exclusively for templating. **cl-closure-template** is a well
58
+documented CL implementation of Google's Closure Templates. Each
59
+template file should contain a namespace like
60
+`coleslaw.theme.theme-name`.
61
+
62
+Each template creates a lisp function in the theme's package when
63
+loaded. These functions take a property list (or plist) as an argument
64
+and return rendered HTML.  **Coleslaw** defines a helper called
65
+`theme-fn` for easy access to the template functions. Additionally,
66
+there are RSS, ATOM, and sitemap templates *coleslaw* uses automatically.
67
+No need for individual themes to reimplement a standard, after all!
68
+
69
+### The Lifecycle of a Page
70
+
71
+- `(load-content)`
72
+
73
+A page starts, obviously, with a file. When *coleslaw* loads your
74
+content, it iterates over a list of content types (i.e. subclasses of
75
+CONTENT).  For each content type, it iterates over all files in the
76
+repo with a matching extension, e.g. ".post" for POSTs. Objects of the
77
+appropriate class are created from each matching file and inserted
78
+into the an in-memory data store. Then the INDEXes are created from
79
+the loaded content and added to the data store.
80
+
81
+- `(compile-blog dir)`
82
+
83
+Compilation starts by ensuring the staging directory (`/tmp/coleslaw/`
84
+by default) exists, cd'ing there, and copying over any necessary theme
85
+assets. Then *coleslaw* iterates over all the content types and index
86
+classes, rendering all of their instances and writing the HTML to disk.
87
+After this, an 'index.html' symlink is created pointing to the first
88
+reverse-chronological index.
89
+
90
+- `(deploy dir)`
91
+
92
+Finally, we move the staging directory to a timestamped path under the
93
+the config's `:deploy-dir`, delete the directory pointed to by the old
94
+'.prev' symlink, point '.curr' at '.prev', and point '.curr' at our
95
+freshly built site.
96
+
28 97
 ### Blogs vs Sites
29 98
 
30 99
 **Coleslaw** is blogware. When I designed it, I only cared that it
@@ -35,12 +104,13 @@ collection of POSTs or other content. An INDEX really only serves to
35 104
 group a set of content objects on a page, it isn't content itself.
36 105
 
37 106
 This isn't ideal if you're looking for a full-on static site
38
-generator.  Content Types were added in 0.8 as a step towards making
39
-*coleslaw* suitable for more use cases but still have some
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.
107
+generator.  Thankfully, Content Types were added in 0.8 as a step
108
+towards making *coleslaw* suitable for more use cases. Any subclass of
109
+CONTENT that implements the *document protocol* counts as a content
110
+type. However, only POSTs are currently included in the basic INDEXes
111
+since there isn't yet a formal relationship to determine which content
112
+types should be included on which indexes.  Users may easily implement
113
+their own dedicated INDEX for new Content Types.
44 114
 
45 115
 ### The Document Protocol
46 116
 
@@ -55,27 +125,43 @@ It consists of 2 "class" methods, 2 instance methods, and an invariant.
55 125
 There are also 4 helper functions provided that should prove useful in
56 126
 implementing new content types.
57 127
 
128
+
58 129
 **Class Methods**:
59 130
 
60
-Since Common Lisp doesn't have explicit support for class methods, we
61
-implement them by eql-specializing on the class, e.g.
131
+Class Methods don't *really* exist in Common Lisp, as methods are
132
+defined on generic functions and not on the class itself. But since
133
+it's useful to think about a Class as being responsible for its
134
+instances in the case of a blog, we implement class methods by
135
+eql-specializing on the class, e.g.
136
+
62 137
 ```lisp
63 138
 (defmethod foo ((doc-type (eql (find-class 'bar))))
64 139
   ... )
65 140
 ```
66 141
 
67
-- `discover`: Create instances for documents of the class and put them in
68
-  in-memory database with `add-document`. If your class is a subclass of
69
-  CONTENT, there is a default method for this.
70
-- `publish`: Iterate over all objects of the class
142
+- `discover`: Create instances for documents of the class and put them
143
+  in the in-memory database with `add-document`.
144
+
145
+  For CONTENT, this means checking the blog repo for any files with a
146
+  matching extension and loading them from disk. If your class is a
147
+  subclass of CONTENT, it inherits a pleasant default method for this.
148
+
149
+  For INDEXes, this means iterating over any relevant CONTENT in the
150
+  database, and creating INDEXes in the database that include that
151
+  content.
152
+
153
+- `publish`: Iterate over all instances of the class, rendering each
154
+  one to HTML and writing it out to the staging directory on disk.
71 155
 
72 156
 
73 157
 **Instance Methods**:
74 158
 
75
-- `page-url`: Generate a unique, relative path for the object on the site
76
-  sans file extension. An :around method adds that later. The `slug` slot
77
-  on the object is conventionally used to hold a portion of the unique
78
-  identifier. i.e. `(format nil "posts/~a" (content-slug object))`.
159
+- `page-url`: Generate a relative path for the object on the site,
160
+  usually sans file extension. If there is no extension, an :around
161
+  method adds "html" later. The `slug` slot on the instance is
162
+  conventionally used to hold a portion of the path that corresponds
163
+  to a unique Primary Key or Object ID.
164
+
79 165
 - `render`: A method that calls the appropriate template with `theme-fn`,
80 166
   passing it any needed arguments and returning rendered HTML.
81 167
 
@@ -92,12 +178,15 @@ implement them by eql-specializing on the class, e.g.
92 178
   database. It will error if the `page-url` of the document is not
93 179
   unique. Such a hash collision represents content on the site being
94 180
   shadowed/overwritten. This should be used in your `discover` method.
181
+
95 182
 - `write-document`: Write the document out to disk as HTML. It takes
96 183
   an optional template name and render-args to pass to the template.
97 184
   This should be used in your `publish` method.
185
+
98 186
 - `find-all`: Return a list of all documents of the requested class.
99 187
   This is often used in the `publish` method to iterate over documents
100 188
   of a given type.
189
+
101 190
 - `purge-all`: Remove all instances of the requested class from the DB.
102 191
   This is primarily used at the REPL or for debugging but it is also
103 192
   used in a `:before` method on `discover` to keep it idempotent.
@@ -109,62 +198,7 @@ NUMERIC-INDEX, FEED, and TAG-FEED. Respectively, they support
109 198
 grouping content by tags, publishing date, and reverse chronological
110 199
 order. Feeds exist to special case RSS and ATOM generation.
111 200
 Currently, there is only 1 content type: POST, for blog entries.
112
-
113
-### Templates and Theming
114
-
115
-User configs are allowed to specify a theme, otherwise the default is
116
-used. A theme consists of a directory under "themes/" containing css,
117
-images, and at least 3 templates: Base, Index, and Post.
118
-
119
-**Coleslaw** uses
120
-[cl-closure-template](https://github.com/archimag/cl-closure-template)
121
-exclusively for templating. **cl-closure-template** is a well
122
-documented CL implementation of Google's Closure Templates. Each
123
-template file should contain a namespace like
124
-`coleslaw.theme.theme-name`.
125
-
126
-Each template creates a lisp function in the theme's package when
127
-loaded. These functions take a property list (or plist) as an argument
128
-and return rendered HTML.  **Coleslaw** defines a helper called
129
-`theme-fn` for easy access to the template functions. Additionally,
130
-there are RSS, ATOM, and sitemap templates *coleslaw* uses automatically.
131
-No need for individual themes to reimplement a standard, after all!
132
-
133
-### Plugins
134
-
135
-**Coleslaw** also encourages extending functionality via plugins. The Plugin
136
-API is well-documented and flexible enough for many use cases. Do check the
137
-[API docs](https://github.com/redline6561/coleslaw/blob/master/docs/plugin-api.md)
138
-when contemplating a new feature and see if a plugin would be appropriate.
139
-
140
-### The Lifecycle of a Page
141
-
142
-- `(load-content)`
143
-
144
-A page starts, obviously, with a file. When *coleslaw* loads your
145
-content, it iterates over a list of content types (i.e. subclasses of
146
-CONTENT).  For each content type, it iterates over all files in the
147
-repo with a matching extension, e.g. ".post" for POSTs. Objects of the
148
-appropriate class are created from each matching file and inserted
149
-into the an in-memory data store. Then the INDEXes are created by
150
-iterating over the POSTs and inserted into the data store.
151
-
152
-- `(compile-blog dir)`
153
-
154
-Compilation starts by ensuring the staging directory (`/tmp/coleslaw/`
155
-by default) exists, cd'ing there, and copying over any necessary theme
156
-assets. Then *coleslaw* iterates over the content types and index
157
-classes, calling the `publish` method on each one. Publish iterates
158
-over the class instances, rendering each one and writing the result
159
-out to disk with `write-file`. After this, an 'index.html' symlink is
160
-created to point to the first index.
161
-
162
-- `(deploy dir)`
163
-
164
-Finally, we move the staging directory to a timestamped path under the
165
-the config's `:deploy-dir`, delete the directory pointed to by the old
166
-'.prev' symlink, point '.curr' at '.prev', and point '.curr' at our
167
-freshly built site.
201
+PAGE, a content type for static page support, is available as a plugin.
168 202
 
169 203
 ## Areas for Improvement
170 204
 
@@ -220,3 +254,7 @@ reasonable concern. Also, every numbered INDEX would have to be
220 254
 regenerated along with any tag or month indexes matching the
221 255
 modified files. If incremental compilation is a goal, simply
222 256
 disabling the indexes may be appropriate for certain users.
257
+
258
+[post_receive_hook]: https://github.com/redline6561/coleslaw/blob/master/examples/example.post-receive
259
+[closure_template]: https://github.com/archimag/cl-closure-template
260
+[api_docs]: https://github.com/redline6561/coleslaw/blob/master/docs/plugin-api.md

+ 0 - 56
docs/overview.md

@@ -1,56 +0,0 @@
1
-## Overall Structure
2
-
3
-Conceptually, coleslaw processes a blog as follows:
4
-
5
-1.  Coleslaw loads the user's config, then reads a directory containing
6
-    `.post` files and processes them into POST and INDEX objects.
7
-
8
-2.  The POST and INDEX objects are then fed to the templating engine
9
-    to produce HTML files.
10
-
11
-3.  A deploy method is called (possibly customized with plugins) to make
12
-    the resulting HTML files (and any static content) visible to the web.
13
-
14
-## What files are generated anyway?
15
-
16
-Before we dive into other details, it is useful to know the directory
17
-structure of the generated content, so you know how the relative path
18
-different content resides at.
19
-
20
-The blog's toplevel looks like this:
21
-```
22
-index.html
23
-posts/
24
-date/
25
-tag/
26
-css/
27
-static/ (optional)
28
-```
29
-
30
-### index.html
31
-
32
-This file is the blog homepage, as you'd expect.  It contains a list of
33
-the most recent posts and has links to the different archives.
34
-
35
-### posts directory
36
-
37
-This directory contains an `.html` file per post.  The name of the file
38
-is the post's `slug`.
39
-
40
-### date directory
41
-
42
-This directory contains an `.html` file per month, for each month with
43
-published content. The name of the file is of the form `yyyy-mm.html`.
44
-
45
-### tag directory
46
-
47
-This directory contains an `.html` file per tag, each containing all
48
-posts with that tag. The name of the file is the tag's `slug`.
49
-
50
-### css directory
51
-
52
-This directory is a copy of the `css/` folder of the theme.
53
-
54
-### static directory (optional)
55
-
56
-This directory is a copy of the `static/` directory of the blog's git repo.