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,

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.