source: project/wiki/eggref/5/hyde @ 37543

Last change on this file since 37543 was 37543, checked in by Moritz Heidkamp, 19 months ago

hyde: Add version 3 release notes

File size: 20.6 KB
Line 
1[[tags: egg]]
2
3== Hyde
4
5[[toc:]]
6
7=== Description
8
9A static website compiler
10
11=== Author
12
13[[/users/moritz-heidkamp|Moritz Heidkamp]]
14
15=== Requirements
16
17Although there is a native
18[[http://daringfireball.net/projects/markdown/|Markdown]] parser for
19Chicken these days (called [[/egg/lowdown|Lowdown]]) due to historical
20reasons you'll have to have a {{markdown}} program available in your
21{{PATH}} to use Markdown in your Hyde pages for the time
22being. Alternatively you can define a custom page translator using
23Lowdown (see [[#translators|translators]]).
24
25=== Documentation
26
27Hyde is a program for compiling static websites from a variety of
28input files. It is basically a Schemey clone of programs such as
29[[http://webby.rubyforge.org/|Webby]] and, particularly name-wise,
30[[http://jekyllrb.com/|Jekyll]]. Note that there is
31[[http://ringce.com/hyde|another project named Hyde]] which is similar
32in purpose but written in Python.
33
34Hyde can be run through the {{hyde}} executable contained in this egg.
35
36A website is, in Hyde's sense, a directory containing at least a
37{{hyde.scm}} file. This file is evaluated before any command and can
38be used to set parameters or define helper functions. It should also
39contain a directory of source files (unless the {{(source-dir)}}
40parameter points somewhere outside the current directory). Invoking
41the compilation process will recursively traverse {{(source-dir)}} and
42do one of the following things for each file it finds:
43
44* If the file's extension is unknown to Hyde, copy the file to the
45same relative path within {{(output-dir)}} unchanged.
46
47* If the file's extension is known to Hyde, translate its contents,
48possibly wrap the result in one or more layouts and write it to the
49same relative path within {{(output-dir)}}, possibly changing its
50extension.
51
52
53In the latter case, the translator used is determined by the source
54file's extension (see [[#translators|translators]] for a list of
55available translators). Before translation, the file is {{(read)}},
56i.e. the first s-expression in the file is read from it. This
57s-expression must be an alist (or a null list) holding arbitrary
58page-vars which are made available within the page's as well as the
59layouts' evaluation environment. This can be used to set a page title,
60for example. The rest of the file is considered the page's body and is
61left to be translated by the translator.
62
63Applying css to a website is done by using scss or regular css. Documentation for the syntax used in scss can be found in [[scss]].
64
65=== Example
66
67Hyde's functionality is probably best understood by an example
68session. Let's start by initializing a site:
69
70    $ mkdir cool-site
71    $ cd cool-site
72    $ hyde init
73    creating layouts
74    creating src
75    creating out
76    creating hyde.scm
77    creating layouts/default.sxml
78   
79We now have a basic site structure. The next step would probably be to
80add some pages, so let's start by creating an index page in wiki
81(i.e. svnwiki) format:
82
83    $ hyde new wiki index
84    src/index.wiki
85    $ cat src/index.wiki
86    ((title . "index"))
87   
88As you can see, Hyde created the source file and inserted the file
89name as a page-var called {{title}}, too (actually it's the other way
90around: the argument for {{hyde new}} is the title and Hyde transforms
91this into a suitable file name, i.e. it removes special chars and
92substitutes spaces with dashes). This is handy as the default layout
93uses this to fill the {{<title>}} tag in the resulting HTML document:
94
95    $ cat layouts/default.sxml
96    ()
97    `((xhtml-1.0-strict)
98      (html
99       (head
100        (title ,($ 'title)))
101       (body
102        (h1 ,($ 'title))
103        (inject ,contents))))
104
105As we learn from that example, page-vars can be referred to through
106the {{$}} function which is made available by Hyde in the environment
107which SXML (as well as SCSS and Atom) pages are evaluated in. Also
108note the {{inject}} transformation rule which allows injection of
109unescaped HTML into the document. Finally, the variable {{contents}}
110contains the translated page contents (see
111[[#available-bindings-during-page-evaluation|Available Bindings During
112Page Evaluation]]).
113
114Let's add a little content to our page and compile the site:
115
116    $ echo 'Hey, welcome to my cool site!' >> src/index.wiki
117    $ hyde
118    cleaning output directory
119    preparing compilation
120    compiling pages
121    * index.wiki -> index.html
122
123    $ cat out/index.html
124    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
125    <html>
126    <head>
127    <title>index</title></head>
128    <body>
129    <h1>index</h1>
130    <p>Hey, welcome to my cool site!</p>
131    </body></html>
132
133As you can see, Hyde renamed {{index.wiki}} to {{index.html}}. This
134can be changed through the {{default-extension}} parameter or by
135adding a page-var {{ext}} to the page:
136
137    $ cat src/index.wiki
138    ((title . "index")
139     (ext   . "xml"))
140    Hey, welcome to my cool site!
141
142    $ hyde           
143    cleaning output directory
144    preparing compilation
145    compiling pages
146    * index.wiki -> index.xml
147
148=== Available Options
149
150The {{hyde}} executable understands the following options:
151
152; {{-e HYDE_ENV_NAME}} : Sets the hyde environment to execute the command in (see [[#available-commands|Available Commands]] for which commands respect this option and [[#define-hyde-environment|define-hyde-environment]] on how to define environments).
153
154
155=== Available Commands
156
157The {{hyde}} executable understands the following commands:
158
159; {{hyde init}} : Initializes a site in the current directory.
160; {{hyde new <page-type> [<title> ...]}} : Creates a new page with the given page type and title. The page's filename will be inferred from the given title by downcasing it and replacing spaces with dashes.
161; {{hyde serve}} : Serves the current site with [[spiffy]], (re-)compiling the requested page on each request (useful for development). This command respects the {{-e}} option.
162; {{hyde build [<prefix> ...]}} : Builds the current site. If prefixes are given then only paths having those prefixes will be built. This command respects the {{-e}} option.
163; {{hyde}} : Compiles the current site. This command respects the {{-e}} option.
164
165=== Configuration Parameters
166
167The following parameters are available to configure Hyde's
168behavior. They are usually set in a site's {{hyde.scm}}.
169
170
171<parameter>(source-dir [dir])</parameter>
172
173The directory in which source pages are kept. Default: {{"src"}}
174
175
176<parameter>(layouts-dir [dir])</parameter>
177
178The directory in which layouts are kept. Default: {{"layouts"}}
179
180
181<parameter>(output-dir [dir])</parameter>
182
183The directory compilation results will be written to. Default:
184{{"out"}}
185
186
187<parameter>(default-layouts [layouts])</parameter>
188
189A list of default layouts which are applied when no other is
190specified. Default: {{'("default.sxml")}}
191
192
193<parameter>(clean-before-build [bool])</parameter>
194
195Indicates whether to purge the {{output-dir}} before compilation or
196not. Default: {{#t}}
197
198
199<parameter>(excluded-paths [regexes])</parameter>
200
201A list of regular expressions matching paths which are to be ignored
202when compiling. Default: {{`(,(irregex (seq "~" eos)))}}
203
204
205<parameter>(default-extension [extension])</parameter>
206
207The file extension to use for compiled pages which don't explicitly
208specify an extension. Default: {{"html"}}
209
210
211<parameter>(default-page-vars [page-vars])</parameter>
212
213An alist which maps either (ir)regexps or procedures to
214page-vars. Each page has its {{page-source-path}} matched against the
215(ir)regexps or is passed to the procedure. If it matches or returns
216non-{{#f}}, the respective page-vars are appended to the page's local
217page-vars, i.e. local page-vars have precedence over them.  Default: {{'()}}
218
219Example:
220
221The following {{default-page-vars}} would set the {{layouts}} page-var
222to {{("page.sxml" "default.sxml")}} for all {{.sxml}} pages with the
223relative path prefix {{pages/}} and the page-vars {{tags}} to
224{{(awful)}} for all pages containing the word "cool":
225
226<enscript language="scheme">
227(default-page-vars `(((seq bos "pages/" (+ any) ".sxml" eos)
228                      (layouts "page.sxml" "default.sxml"))
229
230                     (,(lambda (page)
231                        (irregex-search "cool" (read-page page)))
232                      (tags awful))))
233</enscript>
234
235
236<parameter>(page-eval-env [env])</parameter>
237
238The environment for evaluating SXML and SCSS pages. It needs to be an
239environment created via the {{hyde-page-eval-env}} module which is a
240(mostly) drop-in replacement for the deprecated
241[[/egg/environments|environments egg]]. Note that the top-level
242environment is always used as a fallback for lookup.
243
244
245<parameter>(uri-path-prefix [path])</parameter>
246
247A string that is prepended to all pages' {{page-path}}. Default: {{""}}.
248
249
250<parameter>(shortcut-links [shortcuts])</parameter>
251
252An alist of shortcut names (symbols) mapping to URI templates
253containing {{format}} placeholders. These shortcuts can be used with the
254following page translators:
255
256; svnwiki : The {{[[link]]}} syntax is extended to allow shortcuts to be used by prefixing the path with the shortcut name and a colon, for example: {{[[foo:something]]}} will use the {{foo}} shortcut and substitute the first placeholder with {{"something"}}.
257; sxml : The transformation rule {{shortcut}} can be used to expand a shortcut name into a URI, for example: {{(a (@ (href (shortcut foo "something"))))}}.
258
259This feature has been added in version 0.12.
260
261
262<parameter>(ignore-page? [predicate])</parameter>
263
264{{predicate}} is a procedure accepting a page; when it returns {{#t}}
265that page will not be compiled to an output file (it can still be
266accessed through {{pages}} though).
267
268This parameter has been added in version 0.16.
269
270
271<parameter>(ignore-page? [predicate])</parameter>
272
273
274=== Page accessors
275
276<parameter>pages</parameter>
277
278An alist of all available pages indexed by their source file names
279relative to {{(source-dir)}}. The values are {{page}} records. Note
280that it is only bound during site compilation, i.e. not yet when
281{{hyde.scm}} is loaded.
282
283This used to be a constant up until version 0.13 and was only
284available in the {{page-eval-env}} up until 0.20.0.
285
286<procedure>(page-by-path path)</procedure>
287
288Looks up a page by its target {{path}} (i.e. {{page-path}}), which can
289be given as a string or a list of strings representing the path
290components.
291
292<procedure>(current-page)</procedure>
293
294Returns the current page's record. Only bound during compilation.
295
296
297<procedure>(page-path page)</procedure>
298
299Returns the given {{page}}'s absolute URI path.
300
301
302<procedure>(page-source-path page)</procedure>
303
304Returns the given {{page}}'s source path relative to {{(source-dir)}}.
305
306
307<procedure>(page-vars page)</procedure>
308
309Returns the given {{page}}'s page-vars as an alist.
310
311
312<procedure>(page-type page)</procedure>
313
314Returns the given {{page}}'s type which is one of the following symbols:
315
316; dynamic : a page which is handled by one of Hyde's page translators
317; static : a page which is just copied to {{(output-dir)}}
318; directory : a directory
319
320
321<procedure>(read-page page #!rest layouts)</procedure>
322
323Returns the given {{page}}'s contents, possibly wrapped in the given
324{{layouts}}. {{page}} may be either a {{page}} record or a path
325relative to {{(source-dir)}}. This procedure is useful to create
326aggregate pages. Note that it will translate the contents of dynamic
327{{page}}s even if they have not been compiled, yet. In this case, they
328will neither be wrapped in page-specific nor the default layouts, only
329the ones given in {{layouts}}.
330
331
332=== Translators
333
334A ''translator'' is a zero-argument procedure which is expected to
335read the contents of a Hyde page from {{(current-input-port)}} and
336write its translation to {{(current-output-port)}}. For example, the
337SXML translator shipped with Hyde reads s-expressions from
338{{(current-input-port)}}, evaluates them in {{(page-eval-env)}},
339applies {{sxml-conversion-rules}} and finally writes the result
340rendered as HTML to {{(current-output-port)}}. Note The page-vars
341preamble has already been read and interpreted at the point a
342translator is called. The page being translated is available via
343{{(current-page)}}.
344
345<procedure>(translate-sxml)</procedure>
346<procedure>(translate-scss)</procedure>
347<procedure>(translate-markdown)</procedure>
348<procedure>(translate-svnwiki)</procedure>
349
350Translators for SXML, SCSS, Markdown and svnwiki formatted pages. See
351{{translators}} parameter for which files extensions they are mapped
352to.
353
354
355<parameter>(translators [translators-alist])</parameter>
356
357An alist of source language translators indexed by file extensions. Default:
358
359<enscript language="scheme">
360    `(("sxml" ,translate-sxml)
361      ("scss" ,translate-scss (ext . css) (layouts))
362      ("md"   ,translate-markdown)
363      ("wiki" ,translate-svnwiki)
364      ("sw"   ,translate-svnwiki))
365</enscript>
366
367Additionally, {{`("atom" ,translate-atom (ext . atom) (layouts))}} can
368be made available by loading the {{hyde-atom}} extension from your
369site's {{hyde.scm}}.
370
371To use [[/egg/lowdown|Lowdown]] for
372[[http://daringfireball.net/projects/markdown/|Markdown]] pages you
373need to define a custom page translator in your site's {{hyde.scm}}
374like this:
375
376<enscript language="scheme">
377(use lowdown)
378(translators (cons (list "md" markdown->html) (translators)))
379</enscript>
380
381
382<procedure>(make-external-translator program-name [args])</procedure>
383
384Creates a procedure that reads from {{(current-input-port)}} and
385writes to the standard input of the external program {{program-name}}
386(either a string or a thunk returning a string). Optionally a thunk
387can be passed for {{args}} which needs to return a list of arguments
388for the program. The program's standard output is read back and
389written to {{(current-output-port)}}. It can be used to create page
390translators for external programs, e.g. the markdown translator
391included in Hyde is defined like this:
392
393<enscript language="scheme">
394(define translate-markdown (make-external-translator markdown-program))
395(translators (cons (list "md" translate-markdown) (translators)))
396</enscript>
397
398
399=== Helpers
400
401These procedures and macros are mainly intended for use in the
402{{hyde.scm}} or in extension modules.
403
404
405<syntax>(define-hyde-environment name body ...)</syntax>
406
407Defines an environment {{name}}. The {{body}} expressions are only
408evaluated when {{hyde}} is executed with {{-e [name]}}. This is useful
409to set different parameters for different scenarios or deployment
410locations. If no {{-e}} option is set, the {{default}} environment is
411used. Just {{(define-hyde-environment default ...)}} to override
412it. See [[#available-commands|Available Commands]] for which commands
413respect environments.
414
415<procedure>(pathify string)</procedure>
416
417Turn {{string}} into a URL friendly path name.
418
419Example:
420
421<enscript language="scheme">
422(pathify "This is \"something\" nice.") ; => "this-is-something-nice"
423</enscript>
424
425Exported since version 0.16.
426
427
428<constant>sxml-conversion-rules</constant>
429
430The set of SXML conversion rules used for translating {{sxml}} pages.
431
432Exported since version 0.15.
433
434
435<procedure>(serve-page page path continue)</procedure>
436
437Default handler for the {{hyde serve}} command which translates
438dynamic pages when requested by their target path and tries to serve
439index files for directories as defined via [[/egg/spiffy|Spiffy]]'s
440{{index-files}} parameter. Static files are handled by Spiffy's
441default handler.
442
443See also {{page-serve-handler}}.
444
445
446=== Available Bindings During Page Evaluation
447
448In pages which are evaluated as Scheme (currently SXML, SCSS and Atom
449pages), the following bindings are available:
450
451
452<procedure>($ page-var #!optional page)</procedure>
453
454Returns the value of {{page-var}} (a symbol identifiying the page-var)
455or {{#f}} if no {{page-var}} of that name exists. By giving the
456optional {{page}} argument, refer to that page's page-vars instead of
457the current page's.
458
459
460
461<constant>contents</constant>
462
463The translated contents of the current page. Only available in layouts.
464
465
466=== Hooks
467
468<parameter>around-page-translate</parameter>
469
470A procedure that is called for every page translation. It needs to
471accept the following arguments:
472
473; {{page}} : The page being translated
474; {{translate}} : A thunk which returns the translation result
475
476The procedure needs to return the translation result. Default:
477
478<enscript language="scheme">
479(lambda (page translate) (translate))
480</enscript>
481
482Available since version 0.21.0.
483
484<parameter>page-serve-handler</parameter>
485
486A procedure that is called for every request handled by {{hyde
487serve}}. It needs to accept the following arguments:
488
489; {{page}} : The requested page or {{#f}} if none was found for the requested path
490; {{path}} : The requested path represented as a list of strings
491; {{continue}} : A thunk to be called in case no response was sent
492
493The procedure should either send a response (e.g. via
494[[/egg/spiffy|Spiffy]]'s {{send-response}} procedure) or call the
495{{continue}} thunk. The default is {{serve-page}}.
496
497Available since version 0.21.0.
498
499=== Version History
500
501==== Version 3
502
503* Fix external translator support for CHICKEN 5 (thanks Vasilij Schneidermann for the patch)
504
505==== Version 2
506
507* First version to support CHICKEN 5
508
509==== Version 0.21.0
510
511* Add {{around-page-translate}} and {{page-serve-handler}} hooks.
512* Export all page accessors and translators.
513* As a result of this, remove many bindings from the default {{page-eval-env}} (most notably {{pages}}).
514* Make {{make-external-translator}} use {{copy-port}} instead of line-wise reading/writing and turn it into a procedure.
515* Also handle dotfiles (e.g. for .htaccess files, thanks Peter Bex for the suggestion).
516
517
518==== Version 0.20.0
519
520* Replace deprecated  [[/egg/environments|environments egg]] with mostly drop-in {{hyde-page-eval-env}} module.
521
522==== Version 0.16
523
524* Add {{hyde build}} command.
525* Allow link-shortcuts to be procedures.
526* Extract {{pathify}}.
527* Use {{big-chicken}} module environment when possible.
528* Fix issue in {{hyde serve}} with trailing slashes on paths (thanks John J Foerch for the patch).
529* Add {{ignore-page?}}. Fix escaping issue in colorize-code (thanks Peter Bex for the patch).
530* Add a link with relation {{alternate}} to the atom feed emitted by {{hyde-atom}}.
531
532==== Version 0.15
533
534* Add {{hyde-atom}} module for convenient generation of atom feeds from pages.
535* Export {{sxml-conversion-rules}}
536
537
538==== Version 0.14
539
540* Some compatibility changes. Depend on Spiffy >= 4.9.
541
542
543==== Version 0.13
544
545* Update to scss 0.3.
546* Make {{pages}} a parameter in {{page-eval-env}}.
547
548==== Version 0.12
549
550* Add {{link-shortcuts}}.
551
552==== Version 0.11
553
554* Change {{default-page-vars}} irregex keys to match against {{page-source-path}} instead of {{page-path}}.
555* Add environments.
556* Add {{uri-path-prefix}}.
557
558
559==== Version 0.10
560
561* Add colorize support to svnwiki pages.
562* Implement more powerful {{default-page-vars}}.
563* Add {{make-external-translator}} (thanks to Christian Kellermann for the patch).
564* Only recompile requested pages instead of the whole site with {{hyde serve}}.
565
566
567==== Version 0.9
568
569* Print usage for unknown commands (thanks to Christian Kellermann).
570* Add current-page binding and make it the default argument for all page record field accessors.
571
572==== Version 0.8
573
574* Add svnwiki and atom page translators.
575* Make pages a proper type.
576* Allow creation of aggregate pages through {{read-page}}.
577* Drop {{sxml-shortcuts}} from {{sxml-conversion-rules}}.
578
579
580=== To Do
581
582* document layout nesting
583* change default extension to be an alist mapping source extensions to
584  target extensions
585
586=== License
587
588  Copyright (c) 2010-2019, Moritz Heidkamp
589  All rights reserved.
590 
591  Redistribution and use in source and binary forms, with or without
592  modification, are permitted provided that the following conditions are
593  met:
594 
595  Redistributions of source code must retain the above copyright
596  notice, this list of conditions and the following disclaimer.
597 
598  Redistributions in binary form must reproduce the above copyright
599  notice, this list of conditions and the following disclaimer in the
600  documentation and/or other materials provided with the distribution.
601 
602  Neither the name of the author nor the names of its contributors may
603  be used to endorse or promote products derived from this software
604  without specific prior written permission.
605 
606  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
607  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
608  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
609  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
610  COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
611  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
612  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
613  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
614  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
615  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
616  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
617  OF THE POSSIBILITY OF SUCH DAMAGE.
Note: See TracBrowser for help on using the repository browser.