first commit
This commit is contained in:
commit
3a50b4288d
|
@ -0,0 +1,2 @@
|
|||
bin/
|
||||
*.fasl
|
|
@ -0,0 +1,16 @@
|
|||
define LISP_CMDS
|
||||
"(handler-case \
|
||||
(progn (ql:quickload :lspx) \
|
||||
(asdf:make :lspx)) \
|
||||
(error (e) \
|
||||
(format t \"~A~%\" e) \
|
||||
(uiop:quit 1)))"
|
||||
endef
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all:
|
||||
ros --eval $(LISP_CMDS)
|
||||
|
||||
clean:
|
||||
rm -ri bin/
|
|
@ -0,0 +1,34 @@
|
|||
# lspx
|
||||
### _a. fox_
|
||||
|
||||
a lisp take on [LuaX](https://bvisness.me/luax/)
|
||||
|
||||
## !! THIS SOFTWARE IS ALPHA QUALITY. USE AT YOUR OWN RISK
|
||||
|
||||
## Building
|
||||
|
||||
1. install [roswell](https://github.com/roswell/roswell)
|
||||
2. `$ ros install sbcl-bin/2.3.11 && ros use sbcl-bin/2.3.11`
|
||||
3. `$ git clone https://dev.focks.website/focks/lspx ~/common-lisp/lspx`
|
||||
4. `$ cd ~/common-lisp/lspx && make`
|
||||
|
||||
## Using
|
||||
|
||||
`$ ./lspx -s ./my-site`
|
||||
|
||||
## Setup
|
||||
|
||||
After building the binary, you need to do a bit of work to setup your site.
|
||||
|
||||
The program expects all site files to live either in the specified directory (provided by `-s`) or the current directory if one isn't provided.
|
||||
All pages are generated by compiling lisp files, then loading the compiled files. URLs are resolved by checking for files with names matching the URL slug (e.g., `my-site.com/toplevel/subpage` is loaded from `site-directory/pages/toplevel/subpage.lisp`)
|
||||
|
||||
Each page file should return a function that accepts no arguments and returns a string that should render the page.
|
||||
|
||||
## Tips and Tricks
|
||||
|
||||
;; TODO
|
||||
|
||||
## License
|
||||
|
||||
lol. lmao.
|
|
@ -0,0 +1,9 @@
|
|||
;;;; errors.lisp
|
||||
|
||||
(in-package :lspx)
|
||||
|
||||
(defmacro http-error (code html)
|
||||
`(defun ,(intern (format nil "~A-HANDLER" code)) ()
|
||||
'(,code nil (,html))))
|
||||
|
||||
(http-error 404 "404 - page not found")
|
|
@ -0,0 +1,20 @@
|
|||
;;;; lspx.asd
|
||||
|
||||
(asdf:defsystem #:lspx
|
||||
:description "Describe lspx here"
|
||||
:author "a. fox"
|
||||
:license "Specify license here"
|
||||
:version "0.0.1"
|
||||
:serial t
|
||||
:depends-on (#:clack #:unix-opts #:str #:hunchentoot)
|
||||
:components ((:file "package")
|
||||
(:file "opts")
|
||||
(:file "errors")
|
||||
(:file "lspx"))
|
||||
:build-operation "program-op"
|
||||
:build-pathname "bin/lspx"
|
||||
:entry-point "lspx::main")
|
||||
|
||||
#+sb-core-compression
|
||||
(defmethod asdf:perform ((o asdf:image-op) (c asdf:system))
|
||||
(uiop:dump-image (asdf:output-file o c) :executable t :compression t))
|
|
@ -0,0 +1,51 @@
|
|||
;;;; lspx.lisp
|
||||
|
||||
(in-package #:lspx)
|
||||
|
||||
(defparameter *server* nil)
|
||||
|
||||
(defun web-handler (env)
|
||||
"handle the request by searching for a lisp file that matches the path provided in the url
|
||||
|
||||
if we find the file we compile it using block compilation and load the fasl
|
||||
if we cannot find the file we throw an error"
|
||||
(destructuring-bind (&key path-info &allow-other-keys) env
|
||||
(let* ((logical-path (str:replace-all "/" ";" path-info))
|
||||
(path (if (string= logical-path ";")
|
||||
";index" logical-path))
|
||||
(filepath (str:concat "web:pages;" path ".lisp"))
|
||||
(faslpath (str:replace-all "lisp" "fasl" filepath)))
|
||||
(if (uiop:file-exists-p filepath)
|
||||
(progn
|
||||
(unless (uiop:file-exists-p faslpath)
|
||||
(compile-file filepath
|
||||
:block-compile t :entry-points nil
|
||||
:output-file faslpath))
|
||||
`(200 nil ,(funcall (load faslpath))))
|
||||
(404-handler)))))
|
||||
|
||||
(defun main ()
|
||||
(multiple-value-bind (opts args) (get-opts)
|
||||
|
||||
;; --help
|
||||
(when (getf opts :help)
|
||||
(opts:describe :usage-of "lspx")
|
||||
(uiop:quit 0))
|
||||
|
||||
;; handles -d/--dir
|
||||
(setf (logical-pathname-translations "WEB")
|
||||
`(("WEB:*;**;*.*.*"
|
||||
,(if (getf opts :site)
|
||||
(format nil "~A~:[/~;~]*/**/*.*"
|
||||
(getf opts :site)
|
||||
(uiop:string-suffix-p (getf opts :site) "/"))
|
||||
"./*/**/*.*"))))
|
||||
|
||||
;; handles -p/--port
|
||||
(setf *server*
|
||||
(clack:clackup #'web-handler
|
||||
:port (getf opts :port 5000)))
|
||||
;;
|
||||
;; todo: block here while we handle our http requests
|
||||
;;
|
||||
))
|
|
@ -0,0 +1,21 @@
|
|||
;;;; opts.lisp
|
||||
|
||||
(in-package :lspx)
|
||||
|
||||
(define-opts
|
||||
(:name :help
|
||||
:description "prints this help"
|
||||
:short #\h
|
||||
:long "help")
|
||||
(:name :site
|
||||
:description "specify the path where the site files live. defaults to current directory"
|
||||
:short #\s
|
||||
:long "site"
|
||||
:arg-parser #'identity
|
||||
:meta-var "DIRECTORY")
|
||||
(:name :port
|
||||
:description "port to use for server. defaults to 5000"
|
||||
:short #\p
|
||||
:long "port"
|
||||
:arg-parser #'parse-integer
|
||||
:meta-var "PORT"))
|
|
@ -0,0 +1,7 @@
|
|||
;;;; package.lisp
|
||||
|
||||
(defpackage #:lspx
|
||||
(:use #:cl)
|
||||
(:import-from :unix-opts
|
||||
:define-opts
|
||||
:get-opts))
|
Loading…
Reference in New Issue