StirFry 🥡
A small, simple web framework that lets you enjoy ruby with a JSX type flavour. Develop on the backend with view components that can access your data directly! Have a little fun! Go ahead mix all of your concerns into one delicious dish!
Installation
gem install 'stir_fry'
Usage
Your app could look like the following (gemfile and other small things omitted):
layout.rb
# Layout shared across pages class Layout < StirFry::Component; end __END__ <html> <!-- Yield allows for having child content inside this component. --> <body>{ yield }</body> </html>
home_page.rb
# A specific page to render, with the Layout wrapping it. class HomePage < StirFry::Component def name = "Bobby" end __END__ <!-- Loads the Layout component and the child content is yielded in the layout template --> <Layout> <h1>Hello {name}</h1> </Layout>
app.rb
# The central and starting point for the app, to define routes and any other setup. require "stir_fry" require "layout" require "home_page" class App < StirFry::App # declare a public directory that serves static assets. static File.join(__dir__, "public") # Render the HomePage component get "/", HomePage # Test response get "/hello/:name" { |response:, name:, **| response.text("Hello #{ name }") } # JSON response get "/api/hello/:name" { |response:, name:, **| response.json({message: "Hello #{ name }"}) } end
Run the App
Once you have the app ready, run bundle install and bundle exec stirfry . to start the development server with whatever webserver you have added to your gemfile such as puma.
Templates
The template definitions leverage a weird feature of ruby, the __END__ data sections ref. This enables stir_fry to parse inline templates in the same file as the behaviour class. I have not yet figured out how to add syntax highlighting for it but it is a start.
Multiple Inline templates
Multiple templates can be defined in the same file as well with an addition of an @@ label. This idea was taken from Sinatra.
class Layout < StirFry::Component; end class Home < StirFry::Component; end __END__ @@Layout <html> <body>{ yield }</body> </html> @@Home <Layout><h1>Hello Bobby</h1></Layout>
Development
After checking out the repo,
-
run
bundle installto install dependencies. -
run
bundle exec stirfry ./example/todosto run the example todo app. -
run
bundle exec stirfry ./example/chatto run the example chat app. -
run
raketo run the specs, rubocop and rdoc.
Acknowledgment
These are the projects that I took both inspiration and code chunks from. Since I wanted an interface a lot like Sinatra, I used their codebase heavily for routing. Also since I wanted a reactjs markdown style, I used rbexy initially but then ended up re-writing a lot of it to remove all rails integrations and I ended up rewriting to more of a classical recursive descent parser since I find push-down automata harder to parse personally and it would be more comfortable for me to work on.