Syntropy
A Web Framework for Ruby
What is Syntropy?
| Syntropy: A tendency towards complexity, structure, order, organization of
ever more advantageous and orderly patterns.
Syntropy is a web framework for building multi-page and single-page apps.
Syntropy uses file tree-based routing, and provides controllers for a number of
common patterns, such as a SPA with client-side rendering, a standard
server-rendered MPA, a REST API etc.
Syntropy also provides tools for working with lists of items represented as
files (ala Jekyll and other static site generators), allowing you to build
read-only apps (such as a markdown blog) without using a database.
For interactive apps, Syntropy provides basic tools for working with SQLite
databases in a concurrent environment.
Syntropy is based on:
- UringMachine - a lean mean io_uring machine for Ruby.
- TP2 - an io_uring-based web server for concurrent Ruby apps.
- Qeweney a uniform interface for working with HTTP requests and responses.
- Papercraft HTML templating with plain Ruby.
- Extralite a fast and innovative SQLite wrapper for Ruby.
Routing
Syntropy routes request by following the tree structure of the Syntropy app. A
simple example:
site/ ├ _layout/ | └ default.rb ├ _articles/ | └ 2025-01-01-hello_world.md ├ api/ | └ v1.rb ├ assets/ | ├ css/ | ├ img/ | └ js/ ├ about.md ├ archive.rb ├ index.rb └ robots.txt
Syntropy knows how to serve static asset files (CSS, JS, images…) as well as
render markdown files and run modules written in Ruby.
What does a Syntropic Ruby module look like?
Consider archive.rb
in the example above. We want to get a list of articles
and render it with the given layout:
# archive.rb @@layout = import('$layout/default') def articles Syntropy.stamped_file_entries('/_articles') end export @@layout.apply(title: 'archive') { div { ul { articles.each { |article| li { a(article.title, href: article.url) } } } } }
But a module can be something completely different:
# api/v1.rb class APIV1 < Syntropy::RPCAPI def initialize(db) @db = db end # /posts def all(req) @db[:posts].order_by(:stamp.desc).to_a end def by_id(req) id = req.validate_param(:id, /^{4,32}$/) @db[:posts].where(id: id).first end end export APIV1
Basically, the exported value can be a template, a callable or a class that
responds to the request.