source: project/wiki/eggref/4/hyde @ 31875

Last change on this file since 31875 was 31875, checked in by Moritz Heidkamp, 6 years ago

hyde: Update documentation for version 0.21.0

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