- Version: 0.1.0
- Description: Flexible and customizable static site generator with a lot of plugins!
- Licence: Unlicense
- Author: Alexander Artemenko [email protected]
- Homepage: https://40ants.com/staticl/
- Bug tracker: https://github.com/40ants/staticl/issues
- Source control: GIT
- Depends on: 3bmd, 3bmd-ext-code-blocks, alexandria, cl-fad, cl-ppcre, cl-sitemaps, closer-mop, closure-template, feeder, fuzzy-dates, local-time, log4cl, quri, serapeum, str, utilities.print-items
You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:
(ql-dist:install-dist "http://dist.ultralisp.org/"
:prompt nil)
(ql:quickload :staticl)
StatiCL
is a static site generator. StatiCL
as a modular architecture and is suitable for any kind of a site
be it a blog or a site with pages not included in the feeds. This project was created to overcome limitations of the Coleslaw.
First of all, a STATICL:SITE
object is created and filled with options from .staticlrc
file.
Then staticl:stage
function calls STATICL/CONTENT:READ-CONTENT
generic-function which returns a list
of staticl/content:content
objects. On the next stage, initial list of content objects are passed to a
generic-function staticl/content:preprocess
called with a preprocessor returned by a
generic-function STATICL/PLUGINS:SITE-PLUGINS
as a first argument. Each preprocessor may
return additional staticl/content:content
objects such as index pages, RSS
or ATOM
feeds, sitemaps etc.
When all content was preprocessed, a generic-function staticl/content:write-content
is called
on each staticl/content:content
object and a SITE
object. Content objects are having a format slot,
so internally staticl/content:write-content
generic-function creates an object of corresponding format class
or takes it from the cache and then calls staticl/content:write-content-to-stream
using this format object.
package staticl
function staticl:stage
&KEY (ROOT-DIR *DEFAULT-PATHNAME-DEFAULTS*) (STAGE-DIR (MERGE-PATHNAMES (MAKE-PATHNAME :DIRECTORY '(:RELATIVE "stage"))
(UIOP/PATHNAME:ENSURE-DIRECTORY-PATHNAME ROOT-DIR)))
package staticl/clean-urls
generic-function staticl/clean-urls:transform-filename
site filename
Converts the pathname to the form that should be used to write content to the disk.
If the site has the clean-urls setting enabled, then the filename like some/page.html will be converted to some/page/index.html. If clean-urls is not enabled, the pathname will remain unchanged.
generic-function staticl/clean-urls:transform-url
site url
Converts the URL
to the form that should be used on the site.
If the site has the clean-urls setting enabled, then the URL
like /some/page.html will be converted
to /some/page/. If clean-urls is not enabled, the URL
will remain unchanged.
package staticl/content
class staticl/content:content-from-file
(content-with-title-mixin content-with-tags-mixin content)
Readers
reader staticl/content:content-created-at
(content-from-file) (:created-at)
reader staticl/content:content-excerpt-separator
(content-from-file) (:excerpt)
reader staticl/content:content-file
(content-from-file) (:file)
Absolute pathname to the file read from disk or NIL
for content objects which have no source file, like RSS
feeds.
reader staticl/content:content-format
(content-from-file) (:format)
reader staticl/content:content-template
(content-from-file) (:template)
reader staticl/content:content-text
(content-from-file) (:text)
class staticl/content:content-type
()
Readers
reader staticl/content:content-class
(content-type) (:content-class)
reader staticl/content:content-file-type
(content-type) (:type)
class staticl/content:content-with-tags-mixin
()
Readers
reader staticl/content:content-tags
(content-with-tags-mixin) (:tags)
class staticl/content:content-with-title-mixin
()
Readers
reader staticl/content:content-title
(content-with-title-mixin) (:title)
class staticl/content:content
(print-items-mixin)
Readers
reader staticl/content:content-metadata
(content) (= (make-hash-table :test 'equal))
A hash with additional fields specified in the file's header.
generic-function staticl/content:get-target-filename
site content stage-dir
Should return an absolute pathname to a file where this content item should be rendered.
generic-function staticl/content:preprocess
site plugin content-objects
Returns an additional list content objects such as RSS
feeds or sitemaps.
generic-function staticl/content:read-content-from-disk
site content-type &key exclude
Returns a list of content
objects corresponding to a given content type.
EXCLUDE
argument is a list of pathname prefixes to ignore. Pathnames should be given relative to the root dir of the site.
generic-function staticl/content:read-contents
site &key exclude
Returns a list of content
objects loaded from files.
EXCLUDE
argument is a list of pathname prefixes to ignore. Pathnames should be given relative to the root dir of the site.
generic-function staticl/content:supported-content-types
site
Returns a list of content-type
objects.
generic-function staticl/content:write-content
site content stage-dir
Writes CONTENT
object to the STAGE-DIR
.
generic-function staticl/content:write-content-to-stream
site content stream
Writes CONTENT
object to the STREAM
using given FORMAT
.
function staticl/content:set-metadata
content key value &key override-slot
Changes metadata dictionary by adding a new item with key KEY
.
Key should be a string and it is automatically downcased.
Note, this way, you can override content's object slots.
To prevent accidential override, function will raise an error
in case if a slot named KEY
exists in the object CONTENT
.
To force override provide OVERRIDE-SLOT
argument.
package staticl/content-pipeline
class staticl/content-pipeline:load-content
()
Readers
reader staticl/content-pipeline:exclude-patterns
(load-content) (:exclude)
function staticl/content-pipeline:load-content
&KEY (EXCLUDE (LIST ".qlot"))
package staticl/content/html-content
generic-function staticl/content/html-content:content-html
content
Returns a content as HTML
string.
generic-function staticl/content/html-content:content-html-excerpt
content
Returns an excerpt of full content as HTML
string.
generic-function staticl/content/html-content:has-more-content-p
content
Returns T if there is more content than was returned by content-html-excerpt
generic-function.
package staticl/content/page
class staticl/content/page:page-type
(content-type)
class staticl/content/page:page
(content-from-file)
package staticl/content/post
class staticl/content/post:post-type
(content-type)
class staticl/content/post:post
(content-from-file)
This is the class for a page which will not be included into the feed and indices.
function staticl/content/post:postp
content-item
Returns T if given object is a content of post
class.
package staticl/content/reader
function staticl/content/reader:read-content-file
file &key (separator *default-metadata-separator*)
Returns a plist of metadata from FILE
with :TEXT
holding the content going after the SEPARATOR
.
package staticl/current-root
function staticl/current-root:current-root
macro staticl/current-root:with-current-root
(root) &body body
package staticl/feeds/atom
class staticl/feeds/atom:atom
(feed)
function staticl/feeds/atom:atom
&KEY (TARGET-PATH #P"atom.xml")
package staticl/feeds/rss
class staticl/feeds/rss:rss
(feed)
function staticl/feeds/rss:rss
&KEY (TARGET-PATH #P"rss.xml")
package staticl/filter
class staticl/filter:filter
()
Readers
reader staticl/filter:filter-fn
(filter) (:filter-fn)
reader staticl/filter:pipeline-items
(filter) (:pipeline)
macro staticl/filter:filter
(&key path invert) &rest pipeline
Filters input content objects and processes them using steps given as a body.
Arguments:
PATH
: if given result will contain only items read from the given path.INVERT
: inverts effect of the filter.
package staticl/format
generic-function staticl/format:to-html
text format
package staticl/index/base
class staticl/index/base:base-index
()
Readers
reader staticl/content:content-template
(base-index) (:template)
reader staticl/index/base:index-target-path
(base-index) (:target-path)
Relative pathname to a directory where all pages will be generated.
reader staticl/index/base:page-size
(base-index) (:page-size)
class staticl/index/base:index-page
(content)
Readers
reader staticl/content:content-template
(index-page) (:template)
reader staticl/index/base:next-page
(index-page) (:next-page)
reader staticl/index/base:page-items
(index-page) (:items)
reader staticl/index/base:page-target-path
(index-page) (:target-path)
Relative pathname to a file with page content.
reader staticl/index/base:page-title
(index-page) (:title)
A title of the page.
reader staticl/index/base:prev-page
(index-page) (:prev-page)
Accessors
accessor staticl/index/base:next-page
(index-page) (:next-page)
accessor staticl/index/base:prev-page
(index-page) (:prev-page)
package staticl/index/paginated
class staticl/index/paginated:paginated-index
(base-index)
Readers
reader staticl/index/paginated:page-filename-fn
(paginated-index) (:page-filename-fn)
A callback to change page titles.
Accepts single argument - a page number and should return a pathname relative to the site's root. By default, it returns index.html for the first page and page-2.html, page-3.html for others.
If site has "clean urls" setting enabled, then additional transformation to the pathname will be applied automatically.
reader staticl/index/paginated:page-title-fn
(paginated-index) (:page-title-fn)
A callback to change page titles.
Accepts single argument - a page number and should return a string.
For example, here is how you can translate page title into a russian:
(paginated-index :target-path #P"ru/"
:page-title-fn (lambda (num)
(fmt "Страница ~A" num)))
function staticl/index/paginated:paginated-index
&rest initargs &key target-path page-size template page-title-fn page-filename-fn
package staticl/links/link
class staticl/links/link:link
()
Readers
reader staticl/links/link:link-content
(link) (:content)
function staticl/links/link:link
content
Creates a link to the given content piece.
When such object is passed to the template, it is resolved to a
page URL
and title.
package staticl/links/prev-next
class staticl/links/prev-next:prev-next-links
()
function staticl/links/prev-next:prev-next-links
Creates a links between pages.
package staticl/navigation
class staticl/navigation:item
()
Readers
reader staticl/navigation:menu-item-title
(item) (:title)
reader staticl/navigation:menu-item-url
(item) (:url)
class staticl/navigation:menu
()
Readers
reader staticl/navigation:menu-items
(menu) (:items)
function staticl/navigation:item
title url
function staticl/navigation:menu
&rest items
package staticl/pipeline
generic-function staticl/pipeline:process-items
site pipeline-node content-items
A method for this generic function should process CONTENT-ITEMS
- a list of conten items
produced by a previous pipeline nodes.
During the execution, method can call produce-item
or remove-item
functions to add a new content
or to remove some content item.
function staticl/pipeline:execute-pipeline
site
function staticl/pipeline:produce-item
item
function staticl/pipeline:remove-item
item
package staticl/plugin
class staticl/plugin:plugin
()
function staticl/plugin:make-plugin
name &rest initargs
package staticl/rsync
class staticl/rsync:rsync
()
Readers
reader staticl/rsync:rsync-host
(rsync) (:host)
function staticl/rsync:rsync
host
package staticl/site
class staticl/site:site
()
Readers
reader staticl/site:clean-urls-p
(site) (:clean-urls)
Generate some-page/index.html instead of some-page.html to make URL
s look like https://my-site.com/some-page/ instead of https://my-site.com/some-page.html
reader staticl/site:site-charset
(site) (:charset)
Site's charset. By default it is UTF-8
.
reader staticl/site:site-content-root
(site) (:root)
A directory pathname where .staticlrc file can be found.
reader staticl/site:site-description
(site) (:title)
Site's description.
reader staticl/site:site-navigation
(site) (:navigation)
Site's navigation.
reader staticl/site:site-pipeline
(site) (:pipeline)
A list of pipline nodes
reader staticl/site:site-theme
(site) (:theme)
A theme object for the site.
reader staticl/site:site-title
(site) (:title)
Site's title.
reader staticl/site:site-url
(site) (:url)
Site's URL
.
function staticl/site:make-site
root
function staticl/site:site
title &rest args
package staticl/tag
class staticl/tag:tag
()
Readers
reader staticl/tag:tag-name
(tag) (:name)
package staticl/theme
class staticl/theme:theme
(print-items-mixin)
Readers
reader staticl/theme:theme-path
(theme) (:path)
generic-function staticl/theme:copy-static
theme stage-dir
Copies static files such as CSS
, JS
, images into the STAGE-DIR
.
Usually it is enough to define a method for list-static
generic-function.
generic-function staticl/theme:list-static
theme
Returns a list of static files such as CSS
, JS
, images.
Each list item should be a list of two items where first item is an absolute pathname and second is a pathname relative to the root of the site.
generic-function staticl/theme:render
theme template-name vars stream
Renders fills template named TEMPLATE-NAME
with given VARS
and renders into a given STREAM
.
NAME
argument is a string.VARS
argument is a hash table with string keys.
generic-function staticl/theme:template-vars
site object &key hash
Fills a hash-table given as HASH
argument with variables for filling a template.
If hash is NIL
, then a new hash-table should be allocated with EQUAL
:TEST
argument.
Returned hash-table will be used for rendering a template for an OBJECT
.
package staticl/url
generic-function staticl/url:object-url
site obj &key full &allow-other-keys
Returns a full object URL
.
A method should return an relative URL
, but if case if FULL
argument was given,
the full url with schema and domain will be returned.
Note a call to this method should happen in a context of the with-base-url
macro,
because it is always return a path from the site's root even if FULL
is not given
(in this case return only the path without a domain).
You may wonder: "Why does we bother to return a path without a domain?" It is much easier to service such static site locally for debugging purpose, because you don't have to setup a web server and dns resolver.
Actually you will need to use FULL
argument only in a rare case when you really need
and absolute URL
, for example in an RSS
feed.
macro staticl/url:with-base-url
(url) &body body
package staticl/utils
function staticl/utils:absolute-url-p
url
function staticl/utils:assert-absolute-url
url
function staticl/utils:normalize-plist
plist &rest normalizers-plist &key &allow-other-keys
Returns a new list where each value is replaced with results of call of normalizing functions.
For example:
CL-USER> (normalize-plist '(:foo "Bar" :blah 123)
:foo (lambda (value)
(alexandria:make-keyword (string-upcase value))))
(LIST :FOO :BAR :BLAH 123)
macro staticl/utils:do-files
(filename root-path &key file-type) &body body
For each file under ROOT-PATH
, run BODY
. If FILE-TYPE
is provided, only run
BODY
on files that match the given extension.