Incredibly easy, interpolated server-side scripting for Gemini.
./certs.fish
and follow the prompts./main.fish
Dependencies:
Bliz is an extension to text files to allow interpolated shell scripting - in this case, the fish shell. Of course, the shell can call any other program to embed content from.
It's intended to be used to generate gemtext dynamically, but it can just as easily generate any kind of text file.
Some use cases of dynamic content and server-side scripting:
See /serve/scripting.bliz
for an example .bliz script.
The Gemini request URL accesses a file on the file system.
All files (except for those with extension .bliz
) will be sent as-is with automatically calculated MIME for the Gemini header. This includes text, images, media, binary streams, whatever.
Accessing a directory returns a directory listing.
Files with extension .bliz
activate bliz scripting mode. In scripting mode, Bliz reads the text file line by line and does different things depending on the contents of that line. No Gemini header is automatically inserted for .bliz
files, you must create it manually.
%%%
Lines starting with %%%
toggle shell script mode. When shell script mode is on, each line will be evaluated and its contents inserted into the document at that point.
It's like preformatted gemtext, but for scripts.
%
Lines starting with %
with a following space evaluate a single line of shell script and insert the result into the document.
Example:
% ls -lpB (dirname $blizfile) # insert a directory listing into the page
All other lines are text and will be unchanged, except if they contain variable interpolation.
%$variable
in normal text will insert the contents of the shell variable variable
inline into the document. To type %$
without activating this mode, escape it with a backslash.
See available settings in /src/config.fish
. Override settings by editing /personal/config.fish
.
Add your functions to /personal/script-includes.fish
. They will be available inside all .bliz scripts.
Everything configurable is reloaded on every new request. There should be no need to restart the server unless something goes terribly, horribly wrong.
gem_header 20 'text/gemini'
in script mode at the very top of the file to generate and send a Gemini header. You MUST send exactly one header in the execution of a .bliz script.$blizfile
to access the path on disk of the currently evaluating file.cadence_get_time
, j_get_time
, my_get_time
.Shell scripts have the power to do great harm. You are the one writing the shell scripts.
The only data that a user can input in the Gemini protocol is a single URL - the URL of the page they want to load.
.bliz script execution is not sandboxed, but it is unlikely that a user will be able to exploit unexpected flaws in your script using weird inputs, because they only have one input.
For this reason, I believe that .bliz scripts that you write are exactly as safe as shell scripts that you write that take no input. I sugges that, when writing .bliz scripts, you should take exactly the same amount of caution that you take while writing personal shell scripts, since they are exactly as capable as each other.
AGPL 3