Creating a project homepage with the SCLP
Tagged as tutorial, examples, lisp
Written on 2016-04-22 by Daniel "jackdaniel" Kochmański
Introduction
In this short tutorial I'll describe how to bootstrap easily a project website. In fact that's what I did today with the Embeddable Common-Lisp website in order to provide the RSS feed and make putting there the news easier.
Additionally I'm showing here, how to create a standalone executable
for coleslaw
with clon
after providing quicklisp
independant
bundle of systems.
Quick start
First clone the repository:
$ cd /home/p/ecl
$ git clone https://gitlab.common-lisp.net/dkochmanski/sclp.git website
$ cd website
Now you should adjust the appropriate files. Edit .coleslawrc
(file
is self-explanatory), static pages and posts.
Each file with the extension *.page
is a static
page. pages/main.page
is an example template with a static page –
don't forget to link it in the .coleslawrc
's sitenav
section. Exact URL of the page is declared in the file's header.
Files named *.post
represent blog/news posts which appear in the RSS
feed. They are indexed and accessible from the root URL. Supported
file formats are markdown
, html
and cl-who
(if enabled).
When you're done, you could just load coleslaw with your favorite CL
implementation, using Quicklisp load coleslaw
and call the function
main on the website directory:
(ql:quickload 'coleslaw)
(coleslaw:main "/home/p/ecl/website/")
We will take more ambitious road – we'll create a standalone executable with a proper command line arguments built from a clean bundle produced by Zach Beane's Quicklisp. CLI arguments will be handled by Clon – the Command-Line Options Nuker, an excellent deployment solution created by Didier Verna.
Creating the bundle
Bundle is a self-containing tree of systems packed with their
dependencies. It doesn't require internet access or Quicklisp
and is
a preferred solution for the application deployment.
Some dependencies aren't correctly detected – Quicklisp
can't
possibly know, that our plugin will depend on the cl-who
system, and
it can't detect cl-unicode
's requirement during the build phase –
flexi-streams
(this is probably a bug). We have to mention these
systems explicitly.
Clon
is added to enable the clonification (keep reading).
(ql:bundle-systems '(coleslaw flexi-streams
cl-who cl-fad
net.didierverna.clon)
:to #P"/tmp/clw")
Clonifying the application
(in-package :cl-user)
(require "asdf")
(load "bundle")
(asdf:load-system :net.didierverna.clon)
(asdf:load-system :coleslaw)
(asdf:load-system :cl-fad)
(use-package :net.didierverna.clon)
(defsynopsis (:postfix "DIR*")
(text :contents "Application builds websites from provided directories.")
(flag :short-name "h" :long-name "help"
:description "Print this help and exit."))
(defun main ()
"Entry point for our standalone application."
(make-context)
(when (getopt :short-name "h")
(help)
(exit))
(print (remainder))
(handler-case (mapcar
#'(lambda (p)
(coleslaw:main
(cl-fad:pathname-as-directory p)))
(remainder))
(error (c) (format t "Generating website failed:~%~A" c)))
(terpri)
(exit))
(dump "coleslaw" main)
You may generate the executable with sbcl
and ccl
(ecl
has some
problems with the coleslaw
dependency - esrap
, I'm working on
it). I have used ccl
, because it doesn't "derp" on the symbol exit
and produces slighly smaller executable than sbcl
.
Issue the following in the bundle directory (/tmp/clw
):
ccl -n -l clonify.lisp
This command should create native executable named coleslaw
in the
same directory. On my host ccl
produces binary with the approximate
size 50M.
Executable usage
This is a very simple executable definition. You may extend it with new arguments, more elaborate help messages, even colors.
To generate a websites with sources in directories /tmp/a
and
/tmp/b
you call it as follows:
./coleslaw /tmp/a /tmp/b
That's all. Deployment destination is set in the .coleslawrc
file in
each website directory.
Adding GIT hooks
You may configure a post-receive hook for your GIT repository, so your
website will be automatically regenerated on each commit. Let's
assume, that you have put the coleslaw
standalone executable in
place accessible with the PATH
environment variable. Enter your bare
git repository and create the file hooks/post-receive
:
cd website.git
cat > hooks/post-receive <<EOF
########## CONFIGURATION VALUES ##########
TMP_GIT_CLONE=$HOME/tmp-my-website/
########## DON'T EDIT ANYTHING BELOW THIS LINE ##########
if cd `dirname "$0"`/..; then
GIT_REPO=`pwd`
cd $OLDPWD || exit 1
else
exit 1
fi
git clone $GIT_REPO $TMP_GIT_CLONE || exit 1
while read oldrev newrev refname; do
if [ $refname = "refs/heads/master" ]; then
echo -e "\n Master updated. Running coleslaw...\n"
coleslaw $TMP_GIT_CLONE
fi
done
rm -rf $TMP_GIT_CLONE
exit
EOF
That's all. Now, when you push to the master branch your website will
be regenerated. By default .gitignore
file lists directory
static/files
as ignored to avoid keeping binary files in the
repository. If you copy something to the static directory you will
have to run coleslaw by hand.
Conclusion
Coleslaw
is a very nice project simplifying managing project website
with easy bootstrapping the site without any need to maintain working
lisp process on the server (this is static content which may be served
with nginx
or apache
) and allowing easy blogging (write a post in
markdown
and push to the repository).
Sample Common-Lisp Project
is a pre-configured website definition
with a theme inspired by the common-lisp.net
projects themes with
some nice features, like RSS feed and blog engine (thanks to
coleslaw).
We have described the process of creating a simple website, creating a standalone executable (which may be shared by various users) and chaining it with git hooks.