Skip to content

Commit

Permalink
Added documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
easydatawarehousing committed Mar 27, 2018
1 parent 5924835 commit 98697c8
Show file tree
Hide file tree
Showing 16 changed files with 728 additions and 30 deletions.
8 changes: 8 additions & 0 deletions .yardopts
@@ -0,0 +1,8 @@
opal/**/*.rb
lib/**/*.rb
-
README.md
docs/GettingStarted.md
CHANGELOG.md
LICENSE.txt
CODE_OF_CONDUCT.md
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,7 @@
# 0.10.1 - March 31, 2018

- Added documentation (using Yard)

# 0.10.0 - February 2, 2018

Initial version
15 changes: 15 additions & 0 deletions README.md
@@ -1,4 +1,10 @@
# Opal-Ferro

[![GitHub](http://img.shields.io/badge/github-lsegal/yard-blue.svg)](https://github.com/easydatawarehousing/opal-ferro)
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.org/gems/opal-ferro)
[![Gem Version](https://badge.fury.io/rb/yard.svg)](https://github.com/easydatawarehousing/opal-ferro/releases)
[![License](http://img.shields.io/badge/license-MIT-yellowgreen.svg)](#license)

Ferro is a small Ruby library on top of [Opal](http://opalrb.com/)
that enables an object-oriented programming style for creating code
that runs in the webbrowser.
Expand Down Expand Up @@ -49,6 +55,15 @@ This project is intended to be a safe, welcoming space for collaboration
and contributors are expected to adhere to the
[Contributor Covenant](http://contributor-covenant.org) code of conduct.

## Documentation
Yard is used to generate documentation. In development start yard using:

yard server -r

To generate documentation for publication, cd into project root and use:

yardoc

## License
The gem is available as open source under the terms of the MIT License.
See LICENSE.txt
187 changes: 187 additions & 0 deletions docs/GettingStarted.md
@@ -0,0 +1,187 @@
# @title Getting started with Opal-Ferro

# Getting started with Opal-Ferro

Ferro is a small Ruby library on top of [Opal](http://opalrb.com/)
that enables an object-oriented programming style for creating code
that runs in the webbrowser.
No more distractions like HTML and searching for DOM elements,
just beautiful and simple Ruby code. Front-End-Ruby-ROcks!


* [How does Ferro work](#ferro)
* [Creating the Master Object Model](#mom)
* [Adding elements](#demo)
* [Creation lifecycle](#lifecycle)
* [Navigating the Master Object Model](#navigating)
* [Styling Ferro elements](#styling)
* [More information](#more)

<a name="ferro"></a>

## How does Ferro work?
Ferro uses an object oriented programming style. You instantiate an object, that object
in turn instantiates more child objects and add these as instance variables to itself.
And so on, producing a hierarchy of object instances.
This is called the Master Object Model (MOM).

When an object is instanciated in the MOM, Ferro will add an element to the webbrowsers
Document Object Model (DOM). The MOM keeps a reference to every DOM element.
This erradicates the need for element lookups (jquery $ searches).
If you need an element you know where to find it in the MOM.
Getter methods are automatically added by Ferro for easy access to instance variables.

Each object in the MOM inherits from a Ferro class.
Which Ferro class you use determines what type of DOM element will be created.
All Ferro classes inherit from one base class: FerroElement.
For most DOM elements in the html specs there is a corresponding Ferro class.
For instance if you need a html5 `<header>` element you would create a class that inherits
from FerroElementHeader.
Other html elements have a more abstract counterpart:
all text elements (`<p>`, `<h1>` .. `<h6>`) have one Ferro class `FerroElementText`.
The size of the text element is an option when you instantiate the object.

<a name="mom"></a>

## Creating the Master Object Model

First we need a class that inherits from FerroDocument.
This is the staring point for any Ferro application.
The Document instance will attach itself in the DOM to
`document.body`.

In the example below, the Document instance will create one child element.

class Document < FerroDocument

# The cascade method is called after the Document
# has been created and is ready to create child
# objects.
def cascade
add_child :demo, Demo
end
end

To start the application one instance of the Document must be created.
In the `application.js` file (if you are using Rails for instance)
`Document.new` is called when the browser has loaded the necessary
files.

`document.addEventListener("DOMContentLoaded", function() {#{Document.new};})`

The backticks are Opal's way of entering _raw_ Javascript. Using
familiar Ruby string interpolation `#{}` a reference to `Document.new` can
be inserted.
This is the first and last line of Javascript that is needed.
Everyting else is Ruby code.

<a name="demo"></a>

## Adding elements

Let's look at a very simple example. We will define a small component
with a title and a button. The button should change the title text when clicked.

class Demo < FerroElementComponent
def cascade
# Add a title
add_child :title, FerroElementText, size: 4, content: 'Title'

# Add a button
add_child :btn, DemoButton, content: 'Click me'
end

def rotate_title
# We have access to the 'title' instance variable
txt = title.get_text
title.set_text (txt[1..-1] + txt[0]).capitalize
end
end

class DemoButton < FerroFormButton
def clicked
# Every element knows its parent
parent.rotate_title
end
end

The code in Demo _cascade_ method is equivalent to something like this,
which should look more familiar to a Ruby programmer:

class Demo
def initialize
@title = FerroElementText.new(size: 4, content: 'Title')
@btn = DemoButton.new(content: 'Click me')
end
end

Just like above, the `add_child` method will create instance variables
`@title` and `@btn`. In Ferro we don't need to use the @.

<a name="lifecycle"></a>

## Creation lifecycle

Every Ferro class has 3 hooks into the object creation lifecycle:

- before_create
- after_create
- cascade

The first two are called just before and after the object itself
is created. The cascade hook is called when the object is ready
to create child objects.
In this example most of the action happens in the _cascade_ method.

By inheriting from _FerroFormButton_, _DemoButton_ has access
to the click event handler. After a click occurred, it signals
its parent (_Demo_) to rotate the title text.

<a name="navigating"></a>

## Navigating the Master Object Model

There are two ways to navigate around the MOM: upward and downward.
Every object in the MOM knows its parent. If an event is received by an
object like a button, the parent of that object usually can handle the
event. The parent element can be accessed using the `parent` method.

Searching upward further than one parent quickly becomes difficult to
follow. So you can always search downward starting from the top.
Every object in the MOM can access the root object using the `root`
method. From the root you can access all MOM objects.

There is a shortcut to find an object starting from the nearest element
in the hierarchy that is a component. All semantical elements
(like header and section) are components. All objects that are children
of a component have immediate access to that component using the
`component` method.

<a name="styling"></a>

## Styling Ferro elements

The created elements still need some styling. Ferro uses a handy
naming convention: CSS classnames match Ruby classnames.
For example:

class DemoButton < FerroFormButton
end

When we create this button in the MOM, its DOM counterpart receives
two classnames. One matching the Ruby classname `DemoButton` and
one for its Ruby superclass `FerroFormButton`.
These classnames are _dasherized_. In CSS you can reference these
classnames as `demo-button` and `ferro-form-button`.

<a name="more"></a>

## More information

Please see the [Ferro website](https://easydatawarehousing.github.io/ferro/)
for more information and examples.
The [source code](https://github.com/easydatawarehousing/ferro)
for that webapp is a good Ferro example in itself.

For some simple boilerplate code to get started with Ferro you can use
[this Rails example](https://github.com/easydatawarehousing/ferro-example-todolist).
7 changes: 6 additions & 1 deletion lib/opal-ferro/version.rb
@@ -1,5 +1,10 @@
module Opal
module Ferro
# Opal-Ferro follows the versioning scheme of Opal.
# The first two parts of the version number of Ferro imply
# compatibility with the Opal version with that same number.
# So Ferro 0.10.x should be compatible with and dependant
# on Opal 0.10.x.
VERSION = "0.10.0"
end
end
end
2 changes: 1 addition & 1 deletion opal-ferro.gemspec
Expand Up @@ -21,7 +21,7 @@ Gem::Specification.new do |s|

s.add_development_dependency 'bundler', '~> 1.16'
s.add_development_dependency 'rake', '~> 10.0'
# s.add_development_dependency 'yard', '~> 0.8.7'
s.add_development_dependency 'yard', '~> 0.8.7'
s.add_development_dependency 'minitest', '~> 5.0'
# s.add_development_dependency 'selenium-webdriver', '~> 3.8'
end

0 comments on commit 98697c8

Please sign in to comment.