lissio - e vai col lissio

lissio is a VCL (Vai Col Lissio) framework for Opal to implement frontends completely on the client side.

Here you can find the best musical background while developing lissio applications.

Getting Started

To create a new lissio application just run lissio new <path>, change to the created directory and run lissio start.

By default it will run the server on port 9001, you can change it with --port, run lissio help start to see a list of other options.

Application

Every lissio frontend begins with an Application singleton.

A Lissio::Application singleton is a Lissio::Component that takes ownership of the body element and renders itself on it, since it's just a component you can do anything you can do with any other component.

It also internally creates a router, so you can define the routes and what they do directly in the #initialize method.

class MyApplication < Lissio::Application
  def initialize
    super

    route '/' do
      alert "This is an awesome index, ain't it?"
    end

    route '/about' do
      alert "I don't know you, you don't know me"
    end
  end
end

Component

Components are the heart of any lissio application, in the MVC pattern a lissio component would be a mix of a view and a controller.

Every component has the ability to define the HTML, the CSS and the behaviour in pure Ruby using various DSLs.

class MyComponent < Lissio::Component
  on :click, '.title' do
    alert 'You clicked on the title'
  end

  on :hover, '.subtitle' do
    alert 'You hovered over the subtitle'
  end

  html do
    div.title 'hue'
    div.subtitle 'huehuehuehue'
  end

  css do
    rule '.title' do
      font size: 32.px
    end

    rule '.subtitle' do
      font size:  18.px,
           style: :italic
    end
  end
end

Every component has a #render method, once it's called it will create an element based on the #tag definition or render itself in the defined #element.

On rendering the #html DSL block will produce the DOM directly, there won't be any generate-parse passes, and the #css block will generate the CSS style and put it in the <head>

Model

Models are the classic models, they have properties and can be populated using adapters.

class Message < Lissio::Model
  property :id, as: Integer, primary: true
  property :at, as: Time, default: -> { Time.now }
  property :content, as: String
end

You can then instantiate the model Message.new(id: 2, content: "huehue").

Collection

Collections are, well, collections of models, they're separate entities since they can have different adapters and have different methods of fetching or working on the models they contain.

class Messages < Lissio::Collection
  model Message
end

Adapter

Without adapters models and collections would be pretty much useless since you wouldn't be able to persist them.

When you define a model you can set an adapter calling the #adapter method.

lissio comes with two default adapters, REST and localStorage, they take various options to define endpoints and other behaviour.

class Message < Lissio::Model
  adapter Lissio::Adapter::REST, endpoint: '/message'

  property :id, as: Integer, primary: true
  property :at, as: Time, default: -> { Time.now }
  property :content, as: String
end

Now you'll be able to fetch a model like this.

Message.fetch(1).then {|msg|
  alert msg.content
}.rescue {|error|
  alert error.inspect
}

All operations using adapters use promises, since they're all asynchronous.

Server

lissio comes with a server to run and provide the built application, you're not forced to use it, but it provides seamless access to the HTML5 history.

This means it always gives you the index when accessing any URL that isn't a static file.

In the future it will do prerendering using phantomjs to make lissio applications indexable and crawlable by search engines, so you might want to stick with it.

Following an example on how to run the server.

require 'bundler'
Bundler.require

run Lissio::Server.new {|s|
    s.append_path 'app'
    s.append_path 'css'
    s.append_path 'js'

    s.index = 'index.html.erb'
    s.debug = true
}

The application usually goes in app/.

External CSS should go in css/, usually you don't need to write CSS at all, you should just use the #css method in the component.

External JavaScript should go in js/, typically compatibility files like json2 and sizzle go there, or other libraries you are using that aren't Opal libraries.