diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 0000000..14b86a1 --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,51 @@ +# Building bingus-blog + +this guide assumes you have git and are on linux. +at the moment, compiling on windows is supported, but not _for windows_. + +1. first, acquire _rust nightly_. + the recommended method is to install [rustup](https://rustup.rs/), + and use that to get _rust nightly_. choose "customize installation", + and set "default toolchain" to nightly to save time later, provided + you do not need _rust stable_ for something else +2. start your favorite terminal +3. then, download the repository: `git clone https://git.slonk.ing/slonk/bingus-blog && cd bingus-blog` +4. finally, build the application: `cargo +nightly build --release` +5. your executable is `target/release/bingus-blog`, copy it to your server and + you're done! + +## Building for another architecture + +you can use the `--target` flag in `cargo build` for this purpose. +examples are for Arch Linux x86_64. + +here's how to compile for `aarch64-unknown-linux-gnu` +(eg. Oracle CI Free Tier ARM VPS): + +```sh +# install the required packages to compile and link aarch64 binaries +sudo pacman -S aarch64-linux-gnu-gcc +cargo +nightly build --release --target=aarch64-unknown-linux-gnu +``` + +your executable will be `target/aarch64-unkown-linux-gnu/release/bingus-blog`. + +--- + +a more tricky example is building for `aarch64-unknown-linux-musl` +(eg. a Redmi 5 Plus running postmarketOS): + +```sh +# there is no toolchain for aarch64-unknown-linux-musl, +# so we have to repurpose the GNU toolchain. this doesn't +# work out of the box so we have to set some environment variables +sudo pacman -S aarch64-linux-gnu-gcc +export CC=aarch64-linux-gnu-gcc +export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=$CC +cargo +nightly build --release --target=aarch64-unknown-linux-musl +# the reason we had to do this is because cargo tries to use +# the same toolchain as the target's name. but we can tell it to use +# the GNU one like so. +``` + +your executable will be `target/aarch64-unkown-linux-musl/release/bingus-blog`. diff --git a/CONFIG.md b/CONFIG.md new file mode 100644 index 0000000..cca2107 --- /dev/null +++ b/CONFIG.md @@ -0,0 +1,61 @@ +# Configuration + +the configuration format, with defaults, is documented below: + +```toml +title = "bingus-blog" # title of the blog +# description of the blog +description = "blazingly fast markdown blog software written in rust memory safe" +markdown_access = true # allow users to see the raw markdown of a post + # endpoint: /posts/.md +js_enable = true # enable javascript (required for below 2 options) +date_format = "RFC3339" # format string used to format dates in the backend + # it's highly recommended to leave this as default, + # so the date can be formatted by the browser. + # format: https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers +default_sort = "date" # default sorting method ("date" or "name") +#default_color = "#f5c2e7" # default embed color, optional + +[rss] +enable = false # serve an rss field under /feed.xml + # this may be a bit resource intensive +link = "https://..." # public url of the blog, required if rss is enabled + +[dirs] +posts = "posts" # where posts are stored +media = "media" # directory served under /media/ +custom_templates = "custom/templates" # custom templates dir +custom_static = "custom/static" # custom static dir + # see CUSTOM.md for documentation +[http] +host = "0.0.0.0" # ip to listen on +port = 3000 # port to listen on + +[cache] +enable = true # save metadata and rendered posts into RAM + # highly recommended, only turn off if absolutely necessary +cleanup = true # clean cache, highly recommended +#cleanup_interval = 86400000 # clean the cache regularly instead of just at startup + # uncomment to enable +persistence = true # save the cache to on shutdown and load on startup +file = "cache" # file to save the cache to +compress = true # compress the cache file +compression_level = 3 # zstd compression level, 3 is recommended + +[render] +syntect.load_defaults = false # include default syntect themes +syntect.themes_dir = "themes" # directory to include themes from +syntect.theme = "Catppuccin Mocha" # theme file name (without `.tmTheme`) +``` + +configuration is done in [TOML](https://toml.io/) +if an option marked "optional" is not set, it will not be initialized with +a default value +you don't have to copy the whole thing from here, +it's generated by the program if it doesn't exist + +## Specifying Configuration + +the configuration file is loaded from `config.toml` by default, but the path +can be overriden by setting the environment variable `BINGUS_BLOG_CONFIG`, +which will make bingus-blog try to read that file or fail and exit. diff --git a/CUSTOM.md b/CUSTOM.md new file mode 100644 index 0000000..7b4b5a9 --- /dev/null +++ b/CUSTOM.md @@ -0,0 +1,50 @@ +# Custom Content + +bingus-blog supports loading custom content such as templates and static files +at runtime from custom locations. + +the configuration options `dirs.custom_templates` and `dirs.custom_static` +allow you to set where these files are loaded from. + +customizing the error page, other than CSS, is not supported at this time. + +## Custom Templates + +custom templates are loaded from `custom/templates` by default and they are +written in [Handlebars (the rust variant)](https://crates.io/crates/handlebars) + +the *custom templates directory* has a non-recursive structure: + +```md +./ + - index.html # ignored + - index.hbs # loaded as `index` + - post.hbs # loaded as `post` + - [NAME].hbs # loaded as `[NAME]` + - ... +``` + +templates will be loaded from first, the executable, then, the custom +templates path, overriding the defaults. + +template changes are also processed after startup, any changed template will be +compiled and will replace the existing template in the registry, or add a +new one (though that does nothing). +if a template is deleted, the default template will be recompiled into +it's place. +note that the watcher only works if the *custom templates directory* existed +at startup. if you delete/create the directory, you must restart the program. + +## Custom Static Files + +GET requests to `/static` will first be checked against `dirs.custom_static`. +if the file is not found in the *custom static directory*, bingus-blog will try +to serve it from the directory embedded in the executable. this means you can +add whatever you want in the *custom static directory* and it will be served +under `/static`. + +## Custom Media + +the endpoint `/media` is served from `dirs.media`. no other logic or mechanism +is present. + diff --git a/README.md b/README.md index 6d2cc16..7589fb8 100644 --- a/README.md +++ b/README.md @@ -9,85 +9,37 @@ created_at: 2024-04-18T04:15:26+03:00 blazingly fast markdown blog software written in rust memory safe +for bingus-blog viewers: [see original document](https://git.slonk.ing/slonk/bingus-blog) + +## Features + +- posts are written in markdwon and loaded at runtime, meaning you + can write posts from anywhere and sync it with the server without headache +- RSS is supported +- the look of the blog is extremely customizable, with support for + [custom drop-ins](/CUSTOM.md) for both templates and static content +- really easy to deploy (the server is one executable file) +- blazingly fast + ## TODO -- [x] RSS -- [x] finish writing this document -- [x] document config - [ ] blog thumbnail and favicon -- [x] fix webkit dates (what.) - [ ] sort asc/desc -- [x] alt text for post icon - [ ] extend syntect options -- [x] general cleanup of code - [ ] better error reporting and error pages - [ ] better tracing -- [x] cache cleanup task -- [ ] ^ replace HashMap with HashCache once i implement [this](https://github.com/wvwwvwwv/scalable-concurrent-containers/issues/139) -- [x] (de)compress cache with zstd on startup/shutdown +- [ ] replace HashMap with HashCache once i implement [this](https://github.com/wvwwvwwv/scalable-concurrent-containers/issues/139) - [ ] make date parsing less strict -- [x] make date formatting better -- [x] date formatting respects user timezone -- [x] clean up imports and require less features - [ ] improve home page -- [x] tags - [ ] multi-language support - [x] be blazingly fast - [x] 100+ MiB binary size ## Configuration -the default configuration with comments looks like this +see [CONFIG.md](/CONFIG.md) -```toml -title = "bingus-blog" # title of the blog -# description of the blog -description = "blazingly fast markdown blog software written in rust memory safe" -markdown_access = true # allow users to see the raw markdown of a post - # endpoint: /posts/.md -js_enable = true # enable javascript (required for below 2 options) -date_format = "RFC3339" # format string used to format dates in the backend - # it's highly recommended to leave this as default, - # so the date can be formatted by the browser. - # format: https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers -default_sort = "date" # default sorting method ("date" or "name") -#default_color = "#f5c2e7" # default embed color, optional - -[rss] -enable = false # serve an rss field under /feed.xml - # this may be a bit resource intensive -link = "https://..." # public url of the blog, required if rss is enabled - -[dirs] -posts = "posts" # where posts are stored -media = "media" # directory served under /media/ -custom_templates = "custom/templates" # custom templates dir -custom_static = "custom/static" # custom static dir - # see CUSTOM.md for documentation -[http] -host = "0.0.0.0" # ip to listen on -port = 3000 # port to listen on - -[cache] -enable = true # save metadata and rendered posts into RAM - # highly recommended, only turn off if absolutely necessary -cleanup = true # clean cache, highly recommended -#cleanup_interval = 86400000 # clean the cache regularly instead of just at startup - # uncomment to enable -persistence = true # save the cache to on shutdown and load on startup -file = "cache" # file to save the cache to -compress = true # compress the cache file -compression_level = 3 # zstd compression level, 3 is recommended - -[render] -syntect.load_defaults = false # include default syntect themes -syntect.themes_dir = "themes" # directory to include themes from -syntect.theme = "Catppuccin Mocha" # theme file name (without `.tmTheme`) -``` - -you don't have to copy it from here, it's generated if it doesn't exist - -## Usage +## Building this project uses nightly-only features. make sure you have the nightly toolchain installed. @@ -100,21 +52,7 @@ cargo +nightly build --release the executable will be located at `target/release/bingus-blog`. -### Building for another architecture - -you can use the `--target` flag in `cargo build` for this purpose - -building for `aarch64-unknown-linux-musl` (for example, a Redmi 5 Plus running postmarketOS): - -```sh -# install the required packages to compile and link aarch64 binaries -sudo pacman -S aarch64-linux-gnu-gcc -export CC=aarch64-linux-gnu-gcc -export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=$CC -cargo +nightly build --release --target=aarch64-unknown-linux-musl -``` - -your executable will be located at `target//release/bingus-blog` this time. +see [BUILDING.md](/BUILDING.md) for more information and detailed instructions. ## Writing Posts @@ -167,44 +105,29 @@ standard. examples of valid and invalid dates: - # everything else is also invalid ``` -## Custom Content (CSS, HTML, JS) - -though you can modify the content and commit it so you still get changes from -upstream with minimal problems. -you can edit the css and js however you want but changing the html requires a -recompilation as it is made from compile-time parsed templates. - -bingus-blog currently loads css files from `/static/custom`: - -- `/static/custom/style.css` for all pages -- `/static/custom/post.css` for posts -- `/static/custom/error.css` for the error page - -you can create a `custom` directory inside the `static_dir` you set in the -config and put the css files there. - -## Routes +## Non-static Routes - `GET /`: index page, lists posts - `GET /posts`: returns a list of all posts with metadata in JSON format - `GET /posts/`: view a post - `GET /posts/.md`: view the raw markdown of a post - `GET /post/*`: redirects to `/posts/*` +- `GET /feed.xml`: RSS feed ## Cache bingus-blog caches every post retrieved and keeps it permanently in cache. -the only way a cache entry is removed is when it's requested and it does -not exist in the filesystem. cache entries don't expire, but they get -invalidated when the mtime of the markdown file changes. +there is a toggleable cleanup task that periodically sweeps the cache to +remove dead entries, but it can still get quite big. -if cache persistence is on, the cache is compressed & written on shutdown, -and read & decompressed on startup. one may opt to set the cache location -to point to a tmpfs so it saves and loads really fast, but it doesn't persist -across boots, also at the cost of even more RAM usage. +if cache persistence is on, the cache is (compressed &) written to disk on +shutdown, and read (& decompressed) on startup. one may opt to set the cache +location to point to a tmpfs to make it save and load quickly, but not persist +across reboots at the cost of more RAM usage. -the compression reduced a 3.21 MB file cache into 0.18 MB with almost instantly. -there is basically no good reason to not have compression on. +in my testing, the compression reduced a 3.21 MB cache to 0.18 MB almost +instantly. there is basically no good reason to not have compression on, +unless you have filesystem compression already of course. ## Contributing diff --git a/templates/error.html b/templates/error.html index 0aa7565..6e1bdea 100644 --- a/templates/error.html +++ b/templates/error.html @@ -5,8 +5,6 @@ error - -