<commit_before>[![Gem Version](https://badge.fury.io/rb/volt.png)](http://badge.fury.io/rb/volt)
[![Code Climate](https://codeclimate.com/github/voltrb/volt.png)](https://codeclimate.com/github/voltrb/volt)
[![Build Status](https://travis-ci.org/voltrb/volt.png?branch=master)](https://travis-ci.org/voltrb/volt)
[![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)



# Volt

Volt is a ruby web framework where your ruby code runs on both the server and the client (via [opal](https://github.com/opal/opal).)  The DOM automatically update as the user interacts with the page.  Page state can be stored in the URL, if the user hits a URL directly, the HTML will first be rendered on the server for faster load times and easier indexing by search engines.

Instead of syncing data between the client and server via HTTP, volt uses a persistent connection between the client and server.  When data is updated on one client, it is updated in the database and any other listening clients.  (With almost no setup code needed)

Pages HTML is written in a handlebars like template language.  Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or anything other code wanting to know when a value updates)  When something in the DOM changes, Volt intelligently updates only the nodes that need to be changed.

See some demo videos here:
 - [Volt Todos Example](https://www.youtube.com/watch?v=6ZIvs0oKnYs)
 - [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
 - [Reactive Values in Volt](https://www.youtube.com/watch?v=yZIQ-2irY-Q)

Check out demo apps:
 - https://github.com/voltrb/todos
 - https://github.com/voltrb/blog
 - https://github.com/voltrb/contactsdemo


## Goals

Volt has the following goals:

1. Developer happiness
2. Write once on the client and the server
3. Automatic data syncing between client and server
4. Apps are built as nested components.  Components can be shared (via gems)
5. Concurrent.  Volt provides tools to simplify concurrency.  Component rendering is done in parallel on the server.
6. Intelligent asset management
7. Secure (shouldn't need to be said, but it does)
8. Be fast/light
9. Understandable code base
10. Control upgradeability

# Road Map

Many of the core Volt features are implemented.  We still have a bit to go before 1.0, most of it involving models.

1. Database storing models
2. Model validations (client and server side)
3. Reactive model queries
4. Reactive Enumerators with Blocks (.map .count, etc...)
5. Full managed render loop (for fast rendering)
6. Fix N+1 issue with some reactive values (I know how to fix, just haven't gotten around to doing it)

# VOLT guide

This guide will take you through creating a basic web application in Volt.  This tutorial assumes a basic knowledge of ruby and web development.

To get started, install volt:

    gem install volt

Then create a new project:

    volt new project_name

This will setup a basic project.  Now let's run the server.

    volt server

You can access the volt console with:

    volt console

# Guide Sections

1. [Getting Help](#getting-help)
2. [Rendering](#rendering)
  1. [Reactive Values](#reactive-values)
    1. [ReactiveValue Gotchas](#reactivevalue-gotchas)
3. [Views](#views)
  1. [Bindings](#bindings)
    1. [Content Binding](#content-binding)
    2. [If Binding](#if-binding)
    3. [Each Binding](#each-binding)
    4. [Attribute Bindings](#attribute-bindings)
    5. [Escaping](#escaping)
4. [Models](#models)
  1. [Provided Collections](#provided-collections)
  2. [Reactive Models](#reactive-models)
  3. [Model Events](#model-events)
  4. [Automatic Model Conversion](#automatic-model-conversion)
5. [Controllers](#controllers)
6. [Components](#components)
  1. [Dependencies](#dependencies)
  2. [Assets](#assets)
  3. [Component Generator](#component-generator)
  4. [Provided Components](#provided-components)
    1. [Notices](#notices)
    2. [Flash](#flash)
7. [Controls](#controls)
8. [Routes](#routes)
  1. [Routes file](#routes-file)


# Getting Help

Volt is still a work in progress, but early feedback is appreciated.  Use the following to communicate with the developers, someone will get back to you very quickly:

- **If you need help**: post on [stackoverflow.com](http://www.stackoverflow.com). Be sure to tag your question with `voltrb`.
- **If you found a bug**: post on [github issues](https://github.com/voltrb/volt/issues)
- **If you have an idea or need a feature**: post on [github issues](https://github.com/voltrb/volt/issues)
- **If you want to discuss volt**: use #voltrb on freenode.


# Rendering

When a user interacts with a web page, typically we want to do two things:

1. Change application state
2. Update the DOM

For example when a user clicks to add a new todo item to a todo list, we might create a JavaScript object to represent the todo item, then add an item to the list's DOM.  A lot of work needs to be done to make sure that the JavaScript object and the DOM always stay in sync.

The idea of "reactive programming" has been used to simplify maintaining the DOM.  The idea that is instead of having event handlers that manage a model (or JavaScript object) and manage the DOM, we have event handlers that manage reactive data models.  We describe our DOM layer in a declarative way so that it automatically knows how to render our data models.

## Reactive Values

To build bindings, Volt provides the ReactiveValue class.  This wraps any object in a reactive interface.  To create a ReactiveValue, simply pass the object you want to wrap as the first argument to new.

```ruby
    a = ReactiveValue.new("my object")
    # => @"my object"
```

When `#inspect` is called on a ReactiveValue (like in the console), an '@' is placed in front of the value's inspect string, so you know its reactive.

When you call a method on a ReactiveValue, you get back a new reactive value that depends on the previous one.  It remembers how it was created and you can call `#cur` on it any time to get its current value, which will be computed based off of the first reactive value.  (Keep in mind below that + is a method call, the same as `a.+(b)` in ruby.)

```ruby
    a = ReactiveValue.new(1)
    a.reactive?
    # => true

    a.cur
    # => 1

    b = a + 5
    b.reactive?
    # => true

    b.cur
    # => 6

    a.cur = 2
    b.cur
    # => 7
```

This provides the backbone for reactive programming.  We setup computation/flow graphs instead of doing an actual calculation.  Calling .cur (or .inspect, .to_s, etc..) runs the computation and returns the current value at that time, based on all of its dependencies.

ReactiveValues also let you setup listeners and trigger events:

```ruby
    a = ReactiveValue.new(0)
    a.on('changed') { puts "A changed" }
    a.trigger!('changed')
    # => A Changed
```

These events propagate to any reactive values created off of a reactive value.

```ruby
    a = ReactiveValue.new(1)
    b = a + 5
    b.on('changed') { puts "B changed" }
<commit_msg>In Readme, use backticks to mark code regions in the description for how ReactiveValue methods run their computations.<commit_after>[![Gem Version](https://badge.fury.io/rb/volt.png)](http://badge.fury.io/rb/volt)
[![Code Climate](https://codeclimate.com/github/voltrb/volt.png)](https://codeclimate.com/github/voltrb/volt)
[![Build Status](https://travis-ci.org/voltrb/volt.png?branch=master)](https://travis-ci.org/voltrb/volt)
[![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)



# Volt

Volt is a ruby web framework where your ruby code runs on both the server and the client (via [opal](https://github.com/opal/opal).)  The DOM automatically update as the user interacts with the page.  Page state can be stored in the URL, if the user hits a URL directly, the HTML will first be rendered on the server for faster load times and easier indexing by search engines.

Instead of syncing data between the client and server via HTTP, volt uses a persistent connection between the client and server.  When data is updated on one client, it is updated in the database and any other listening clients.  (With almost no setup code needed)

Pages HTML is written in a handlebars like template language.  Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or anything other code wanting to know when a value updates)  When something in the DOM changes, Volt intelligently updates only the nodes that need to be changed.

See some demo videos here:
 - [Volt Todos Example](https://www.youtube.com/watch?v=6ZIvs0oKnYs)
 - [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
 - [Reactive Values in Volt](https://www.youtube.com/watch?v=yZIQ-2irY-Q)

Check out demo apps:
 - https://github.com/voltrb/todos
 - https://github.com/voltrb/blog
 - https://github.com/voltrb/contactsdemo


## Goals

Volt has the following goals:

1. Developer happiness
2. Write once on the client and the server
3. Automatic data syncing between client and server
4. Apps are built as nested components.  Components can be shared (via gems)
5. Concurrent.  Volt provides tools to simplify concurrency.  Component rendering is done in parallel on the server.
6. Intelligent asset management
7. Secure (shouldn't need to be said, but it does)
8. Be fast/light
9. Understandable code base
10. Control upgradeability

# Road Map

Many of the core Volt features are implemented.  We still have a bit to go before 1.0, most of it involving models.

1. Database storing models
2. Model validations (client and server side)
3. Reactive model queries
4. Reactive Enumerators with Blocks (.map .count, etc...)
5. Full managed render loop (for fast rendering)
6. Fix N+1 issue with some reactive values (I know how to fix, just haven't gotten around to doing it)

# VOLT guide

This guide will take you through creating a basic web application in Volt.  This tutorial assumes a basic knowledge of ruby and web development.

To get started, install volt:

    gem install volt

Then create a new project:

    volt new project_name

This will setup a basic project.  Now let's run the server.

    volt server

You can access the volt console with:

    volt console

# Guide Sections

1. [Getting Help](#getting-help)
2. [Rendering](#rendering)
  1. [Reactive Values](#reactive-values)
    1. [ReactiveValue Gotchas](#reactivevalue-gotchas)
3. [Views](#views)
  1. [Bindings](#bindings)
    1. [Content Binding](#content-binding)
    2. [If Binding](#if-binding)
    3. [Each Binding](#each-binding)
    4. [Attribute Bindings](#attribute-bindings)
    5. [Escaping](#escaping)
4. [Models](#models)
  1. [Provided Collections](#provided-collections)
  2. [Reactive Models](#reactive-models)
  3. [Model Events](#model-events)
  4. [Automatic Model Conversion](#automatic-model-conversion)
5. [Controllers](#controllers)
6. [Components](#components)
  1. [Dependencies](#dependencies)
  2. [Assets](#assets)
  3. [Component Generator](#component-generator)
  4. [Provided Components](#provided-components)
    1. [Notices](#notices)
    2. [Flash](#flash)
7. [Controls](#controls)
8. [Routes](#routes)
  1. [Routes file](#routes-file)


# Getting Help

Volt is still a work in progress, but early feedback is appreciated.  Use the following to communicate with the developers, someone will get back to you very quickly:

- **If you need help**: post on [stackoverflow.com](http://www.stackoverflow.com). Be sure to tag your question with `voltrb`.
- **If you found a bug**: post on [github issues](https://github.com/voltrb/volt/issues)
- **If you have an idea or need a feature**: post on [github issues](https://github.com/voltrb/volt/issues)
- **If you want to discuss volt**: use #voltrb on freenode.


# Rendering

When a user interacts with a web page, typically we want to do two things:

1. Change application state
2. Update the DOM

For example when a user clicks to add a new todo item to a todo list, we might create a JavaScript object to represent the todo item, then add an item to the list's DOM.  A lot of work needs to be done to make sure that the JavaScript object and the DOM always stay in sync.

The idea of "reactive programming" has been used to simplify maintaining the DOM.  The idea that is instead of having event handlers that manage a model (or JavaScript object) and manage the DOM, we have event handlers that manage reactive data models.  We describe our DOM layer in a declarative way so that it automatically knows how to render our data models.

## Reactive Values

To build bindings, Volt provides the ReactiveValue class.  This wraps any object in a reactive interface.  To create a ReactiveValue, simply pass the object you want to wrap as the first argument to new.

```ruby
    a = ReactiveValue.new("my object")
    # => @"my object"
```

When `#inspect` is called on a ReactiveValue (like in the console), an '@' is placed in front of the value's inspect string, so you know its reactive.

When you call a method on a ReactiveValue, you get back a new reactive value that depends on the previous one.  It remembers how it was created and you can call `#cur` on it any time to get its current value, which will be computed based off of the first reactive value.  (Keep in mind below that + is a method call, the same as `a.+(b)` in ruby.)

```ruby
    a = ReactiveValue.new(1)
    a.reactive?
    # => true

    a.cur
    # => 1

    b = a + 5
    b.reactive?
    # => true

    b.cur
    # => 6

    a.cur = 2
    b.cur
    # => 7
```

This provides the backbone for reactive programming.  We setup computation/flow graphs instead of doing an actual calculation.  Calling `#cur` (or `#inspect`, `#to_s`, etc..) runs the computation and returns the current value at that time, based on all of its dependencies.

ReactiveValues also let you setup listeners and trigger events:

```ruby
    a = ReactiveValue.new(0)
    a.on('changed') { puts "A changed" }
    a.trigger!('changed')
    # => A Changed
```

These events propagate to any reactive values created off of a reactive value.

```ruby
    a = ReactiveValue.new(1)
    b = a + 5
    b.on('changed') { puts "B changed" }

{'fraction_non_alphanumeric': 0.09463898790801706, 'fraction_numerical': 0.010484378276368212, 'mean_word_length': 3.8534599728629577, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 32, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5024128', 'n_tokens_mistral': 4373, 'n_tokens_neox': 4079, 'n_words': 1895}