Operator is an experimental web server for static and dynamic content. You give it a directory and it makes a website.
It serves static files the way you'd expect, but it can also serve dynamic content that is generated by handlebars templates or executables at request time.
⚠️ Operator is extremely alpha! Please don't use it for anything important until there's a 1.0 release.
Operator is a single self-contained binary. At the moment, the best way to get a binary for your platform is to build one yourself. First install Rust, then:
sh
git clone https://github.com/mkantor/operator.git
cd operator
cargo build --release # This will take a while.
echo '{{#if true}}Hello, Operator!{{/if}}' \
| ./target/release/operator eval --content-directory=/dev/null
The CLI has three subcommands:
eval
evaluates a handlebars template from STDIN.get
renders content from a content directory.serve
starts an HTTP server.serve
is where the real action is, but the other two come in handy at times.
These commands all require a "content directory", which is just the folder
where your website lives. There are a bunch of example content directories in
samples/
.
To learn more, run operator --help
or operator <SUBCOMMAND> --help
.
Let's start a server for one of the samples:
sh
operator -vv serve \
--content-directory=samples/realistic-advanced \
--index-route=home \
--error-handler-route=error-handler \
--bind-to=127.0.0.1:8080
Open http://localhost:8080 in your browser of choice to see the website!
When Operator starts up, it crawls through your content directory to build a representation of your website. The site's routes and configuration are derived from this directory.
There are three different kinds of content files:
1. Static files are served directly. For example, you can drop a photo into
your content directory and it'll be served as-is.
1. Executables are executed at request time, with standard output piped out
as the response body. Any program that your operating system can run will
work (think scripting languages, compiled binaries, etc). The executable is
invoked with no CLI arguments, no special environment, and with its working
directory set to its own parent folder. Operator requires execute
permissions on these files, and scripts typically need a
shebang so your operating
system knows how to interpret them.
1. Handlebars templates are compiled during server startup and evaluated at
request time. The heavy lifting is done by the handlebars
Rust
library which is largely compatible
with the original JavaScript implementation.
Operator provides some render data and a custom get
helper to make your
content composable.
Operator needs to know what media type will be emitted by each content file. This is specified via file extensions. The rules are pretty simple:
.html
is text/html
, .js
is text/javascript
, .png
is image/png
,
and so on).foo.html
, bar.mp4
, etc).baz.html.py
, quux.css.sh
,
garply.jpg.exe
, etc). Operator actually does not care what the second
extension is, but you can use it to indicate the file type (so
baz.html.py
would be a Python script that outputs HTML—for executables the
file type is usually not the same as its output type, although if you're
feeling feisty then things like wat.js.js
are certainly possible). As
mentioned previously, make sure you set the executable bit on these files..hbs
(plugh.html.hbs
, xyzzy.json.hbs
, etc).Hidden files and directories (whose name begins with .
) are always completely
ignored by Operator.
Operator is very young and has not been battle-hardened. There are known flaws and obvious missing features that need to be addressed. The major ones are filed as issues. All feedback is greatly appreciated.
This is my first nontrivial Rust project and I'm sure there are places where things are unidiomatic or non-optimal. The main reason I created Operator was to get more experience using the language, so if you notice anything that could be improved (no matter how small), please open an issue to help me learn! ❤️