Welcome to Spider

Spider is a Model-View-Controller application framework, mainly intended for Web applications.

Its main features are:

  • A model layer that is easy to use, yet flexible enough to adapt to legacy schemas. Models are defined in Ruby: schemas are autogenerated, but can be specified manually when needed. Direct sql is almost never used, but you can embed custom sql behaviour per model for each storage.

    Deep loading and deep querying are supported, through a simple pure-Ruby query language:

    planets = Planet.find{ |planet| planet.stars.diameter <= 1500000 }
    p planets[0].atmosphere.type

    No N+1 queries are performed: deep data is loaded in batches, using windows if needed.

    A Unit of Work is available for complex saves. An Identity Mapper mantains the integrity of an object's tree; but it isn't forced globally, so data replication and translation is still possible.

  • A view layer based on HTML, with reusable widgets that are easy to extend in both their controller and their view.

    Templates are mostly HTML, but implement variable substitution, widget instantiation, conditional and iteration logic. They are valid XML, though the namespace is implied.

    <div id="my-view">
        <h1>Hello, { @my_name }</h1>
        <core:table model="Music" />
    </div>

    A view can be extended by another one like

    <tpl:extend src="view.shtml">
        <tpl:append search="#my-view h1">, and welcome to the show.</tpl:append>
    </tpl:extend>

    Or, a widget can be customized directly when instantiated:

    <div id="my-view">
        <core:table model="Music">
            <tpl:after search="tbody td">
                <a sp:if="element == :title" href="#listen">Listen</a>
            </tpl:after>
        </core:table>
    </div>

    Views are compiled, so they are fast; so are the overrides, which always work on the source template.

    No code blocks are available in the views. This forces clear separation of the logic from the presentation and allows the programmatic manipulation of the templates. Still, full Ruby is available on the “scene” variables, so formatting logic can be applied inline.

  • A light controller with flexible redirection, before and after stacks, and an annotation system to expose methods with different content types.

    class MyController < Spider::PageController
        route 'admin', MyAdminController
        route /books/(.+)/, :book
    
        __.html
        def book(id)
            @scene.book = Book.new(id)
            render 'book'
        end
    
    end

    Widgets are controllers, too, so they get the same funtionality; still, it's the main controller that manages them, and can easily customize the widgets' behaviour.

  • A JavaScript library (jQuery based) that interacts with the backend. Controllers have their corresponding Javascript objects that allow actions on the server; so do widgets instances, which have a direct line with the same instance on the server.

    $W('my_gallery').reload({place: 'Barcelona'});

    Widgets instances can be rendered individually, allowing a zero-work ajax which can be refined later while still preserving the non-javascript functionality.

    Javascript and CSS dependencies are managed by requiring them in controller and widget templates; they are automatically resolved and compressed when running in production mode.

In addition, Spider provides:

  • Thread safety (if you play it safe, of course): Spider runs equally well in a single process mode as in a multiple process mode. A threaded single process can be faster and less resource intensive; multiple threaded or single-threaded processes can be pooled. Thread safety has been a requirement since the beginning of the project.

  • CRUD administration but no scaffolding: administration is composed with widgets that can be extended and customized, ensuring that common functionality can be globally modified when needed.

  • Multiple app support: apps are packages which can be distributed and activated as needed.

  • A (writable) YAML-based configuration system with smart defaults and includable sets.

  • No pollution: monkey-patching is kept to the minimum. ActiveSupport is definitely not needed, but is grudgingly accepted if it is loaded.

  • Full internazionalization using gettext and CLDR, even for Javascript files.

To install:

$ gem install spiderfw

Dive in by running

$ spider create home test
$ cd test
$ spider create app my_app

Add 'my_app' to the apps in config/config.yml, run

$ spider webserver start

and point your browser to localhost:8080/my_app/

Have fun!