## 1. Project Overview & Quickstart (bbatsov/clojure-style-guide)

## 1. Project Overview & Quickstart (bbatsov/clojure-style-guide)

# clojure-style-guide

A community coding style guide for the Clojure programming language

### Repository Details
- **Repository:** [bbatsov/clojure-style-guide](https://github.com/bbatsov/clojure-style-guide)
- **GitHub Stars:** ⭐ 4,092
- **Primary Language:** Unknown

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (bbatsov/docs)

# Introduction

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 updates 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 template language where you can put ruby between ```{{``` and ```}}```.  Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or any 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=Tg-EtRnMz7o)
- [Pagination Example](https://www.youtube.com/watch?v=1uanfzMLP9g)
- [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
** Note: The blog video is outdated, expect an updated version soon.

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

## 2. Official Technical Reference & Guides (bbatsov/docs)

## File: README.md

# Introduction

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 updates 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 template language where you can put ruby between ```{{``` and ```}}```.  Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or any 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=Tg-EtRnMz7o)
- [Pagination Example](https://www.youtube.com/watch?v=1uanfzMLP9g)
- [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
** Note: The blog video is outdated, expect an updated version soon.

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

---

## File: en/contributing/README.md

# Contributing

You want to contribute?  Great!  Thanks for being awesome!  We have full docs on how to contribute here:
https://github.com/voltrb/volt/blob/master/CONTRIBUTING.md

---

## File: en/deployment/README.md

# Volt Deployment

This chapter highlights various deployment options for Volt on popular cloud providers.

---

## File: en/docs/arraymodel_events.md

## ArrayModel Events

Models trigger events when their data is updated.  Currently, models emit two events: ```added``` and ```removed```.  For example:

```ruby
    model = Volt::Model.new

    model._items.on('added') { puts 'item added' }
    model._items << 1
    # => item added

    model._items.on('removed') { puts 'item removed' }
    model._items.delete_at(0)
    # => item removed
```

---

## File: en/docs/assets.md

## Assets

**Note, asset management is still early, and likely will change quite a bit**

In Volt, assets such as JavaScript and CSS (or sass) are automatically included on the page for you.  Anything placed inside of a components asset/js or assets/css folder is served at /assets/{js,css} (via [Sprockets](https://github.com/sstephenson/sprockets)).  Link and script tags are automatically added for each css and js file in assets/css and assets/js respectively.  Files are included in their lexical order, so you can add numbers in front if you need to change the load order.

Any JS/CSS from an included component or component gem will be included as well.  By default [bootstrap](http://getbootstrap.com/) is provided by the volt-bootstrap gem.

**Note: asset bundling is on the TODO list**

---

## File: en/docs/attribute_bindings.md

# Attribute Bindings

Bindings can also be placed inside of attributes.

```html
Text
```

There are some special features provided to make elements work as "two way bindings":

```html

```

## CheckBoxes

In the example above, if ```_name``` changes, the field will update, and if the field is updated, ```_name``` will be changed:

```html

```

If the value of a checked attribute is ```true```, the checkbox will be shown checked. If it's checked or unchecked, the value will be updated to ```true``` or ```false``` respectively.

## Radio Buttons

Radio buttons bind to a checked state as well, except instead of setting the value to true or false, they set it to a supplied field value.

```html


```

When a radio button is checked, whatever checked is bound to is set to the field's value.  When the checked binding value is changed, any radio buttons where the binding's value matches the fields value are checked.  NOTE: This seems to be the most useful behavior for radio buttons.

## Select Boxes

Select boxes can be bound to a value (while not technically a DOM property, this is another convenient behavior Volt adds).

```html
<select value="{{ _rating }}">
  <option value="1">*</option>
  <option value="2">**</option>
  <option value="3">***</option>
  <option value="4">****</option>
  <option value="5">*****</option>
</select>
```

When the selected option of the select above changes, ```_rating``` is changed to match.  When ```_rating``` is changed, the selected value is changed to the first option with a matching value.  If no matching values are found, the select box is unselected.

---

## File: en/docs/automatic_model_conversion.md

## Automatic Model Conversion

### Hash -> Model

For convenience, when placing a hash inside of another model, it is automatically converted into a model.  Models are similar to hashes, but provide support for things like persistence and triggering reactive events.

```ruby
    user = Volt::Model.new
    user._name = 'Ryan'
    user._profiles = {
      twitter: 'http://www.twitter.com/ryanstout',
      dribbble: 'http://dribbble.com/ryanstout'
    }

    user._name
    # => "Ryan"
    user._profiles._twitter
    # => "http://www.twitter.com/ryanstout"
    user._profiles.class
    # => Volt::Model
```

Models are accessed differently from hashes.  Instead of using `model[:symbol]` to access, you call a method `model.method_name`.  This provides a dynamic unified store where setters and getters can be added without changing any access code.

You can get a Ruby hash back out by calling `#to_h` on a Model.

### Array -> ArrayModel

Arrays inside of models are automatically converted to an instance of ArrayModel.  ArrayModels behave the same as a normal Array except that they can handle things like being bound to backend data and triggering reactive events.

```ruby
    model = Volt::Model.new
    model._items << {name: 'item 1'}
    model._items.class
    # => Volt::ArrayModel

    model._items[0].class
    # => Volt::Model
    model._items[0]
```


To convert a Volt::Model or a Volt::ArrayModel back to a normal hash, call .to_h or .to_a respectively.
To convert them to a JavaScript Object (for passing to some JavaScript code), call `#to_n` (to native).

```ruby
    user = Volt::Model.new
    user._name = 'Ryan'
    user._profiles = {
      _twitter: 'http://www.twitter.com/ryanstout',
      _dribbble: 'http://dribbble.com/ryanstout'
    }

    user._profiles.to_h
    # => {twitter: 'http://www.twitter.com/ryanstout', dribbble: 'http://dribbble.com/ryanstout'}

    items = Volt::ArrayModel.new([1,2,3,4])
    # => #<Volt::ArrayModel:70226521081980 [1, 2, 3, 4]>

    items.to_a
    # => [1,2,3,4]
```

You can get a normal array again by calling .to_a on a Volt::ArrayModel.

---

## File: en/docs/buffers.md

## Buffers

Because the store collection is automatically synced to the backend, any change to a model's property will result in all other clients seeing the change immediately.  Often this is not the desired behavior.  To facilitate building [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete) apps, Volt provides the concept of a "buffer".  A buffer can be created from one model and will not save data back to its backing model until .save! is called on it.  This lets you create a form thats not saved until a submit button is pressed.

```ruby
    store._items << {name: 'Item 1'}

    item1 = store._items[0]

    item1_buffer = item1.buffer

    item1_buffer._name = 'Updated Item 1'
    item1_buffer._name
    # => 'Updated Item 1'

    item1._name
    # => 'Item 1'

    item1_buffer.save!

    item1_buffer._name
    # => 'Updated Item 1'

    item1._name
    # => 'Updated Item 1'
```

```#save!``` on buffer also returns a [promise](http://opalrb.org/blog/2014/05/07/promises-in-opal/) that will resolve when the data has been saved back to the server.

```ruby
    item1_buffer.save!.then do
      puts "Item 1 saved"
    end.fail do |err|
      puts "Unable to save because #{err}"
    end
```

Calling .buffer on an existing model will return a buffer for that model instance.  If you call .buffer on a Volt::ArrayModel (plural sub-collection), you will get a buffer for a new item in that collection.  Calling .save! will then add the item to that sub-collection as if you had done << to push the item into the collection.

---

## File: en/docs/callbacks_and_actions.md

# Controller Actions

When a template binding or tag renders a view, it first loads a controller.  There are four callbacks around the rendering.  The ```{action}``` is the same as the view file's name.  So if you were rendering ```about.html```, ```about``` would be the action.  Simply create the correct method in the controller and it will called at the time.

| action name           | description |
|-----------------------|-----------------------------------------------------|
| ```{action}``` | called before anything renders.  Setup data you need       |
| ```{action}_ready``` | called after the view renders.  Run any code where you need to bind directly to the dom.  jQuery setup code for example (bootstrap components) |
| ```before_{action}_remove``` | called before the view is removed (unrendered).  Cleanup any dom bindings here. |
| ```after_{action}_remove``` | called after the view is removed from the dom.  Cleanup anything in the controller that needs to be cleaned up. |

Most of the time all you will need is the action method to setup the controller, model, etc...

---

## File: en/docs/channel.md

# Channel

Controllers provide a `#channel` method, that you can use to get the status of the connection to the backend.  Channel's access methods are reactive and when the status changes, the watching computations will be re-triggered.  It provides the following:

| method      | description                                               |
|-------------|-----------------------------------------------------------|
| connected?  | true if it is connected to the backend                    |
| status      | possible values: :opening, :open, :closed, :reconnecting  |
| error       | the error message for the last failed connection          |
| retry_count | the number of reconnection attempts that have been made without a successful connection |
| reconnect_interval | the time until the next reconnection attempt (in seconds) |