CoreCMP
=======

CoreCMP is a framework to create web apps based on HTML and CSS

### How it works

The idea behind CoreCMP is to create a tree construct that describes a web app.
A tree does not represent the final page, it is more like a blueprint of a page structure.

Lets start with a simple example.

We want to render a todo list as follows

```html
<div class="todo">
  <div class="editor">
    <form class="create-form">
      <input class="create-input" type="text" size="200">
      <button class="submit-button">Add item</button>
    </form>
  </div>
  <div class="listing">
    <ul class="todo-list">
      <li class="todo-item">
        <span class="item-id">001</span>
        <span class="item-title">First todo item</span>
        <span class="item-status">open</span>
      </li>
      <li class="todo-item">
        <span class="item-id">002</span>
        <span class="item-title">Second todo item</span>
        <span class="item-status">progress</span>
      </li>
      <li class="todo-item">
        <span class="item-id">003</span>
        <span class="item-title">Third todo item</span>
        <span class="item-status">done</span>
      </li>
    </ul>
  </div>
</div>
```

In CoreCMP topic, this means we create a class for each Node. Don't worry, it sounds lots of work, but it isn't. First lets break the structure down to a simple tree.

```yaml
Todo
  Editor
    CreateForm
      CreateInput
      SubmitButton

  Listing
    TodoList
      ItemId
      ItemTitle
      ItemStatus
```

This would be our tree structure. Each html node has become a tree item. It is not necessary to repeat a list of nodes in the tree structure. This will be done during the rendering process.

Next, we create a class of each of the tree's node and connect them so that we get a tree like in the example above.

A CoreCMP class is a javascript class which describes one node of the structure tree.

Lets take the last node first.

```js
class ItemStatus extends Node {
  create () {
    this.tag = 'span'
  }

  render (data) {
    return this.createNode(data.status)
  }
}
```

Here we go, the first node class is done.
Lets go through the class. The class name is identical with the tag's css class. `ItemStatus` <=> `item-status` CoreCMP uses the class name to generate a snake cased css class name. (There is an option to define an additional class name.)
The class has two methods. `create()` creates a tree node and describes the node itself and `render()` renders the node and returns it as html. The call to `createNode()` is important, it creates the html node and introduces it into the tree.

If we call the node it renders a html tag.

```js
const node = new ItemStatus()
const html = node.render({
  status: 'open'
})

// html == <span class="item-status">open</span>
```

Next, add ItemID and ItemTitle node.

```js
class ItemId extends Node {
  create () {
    this.tag = 'span'
  }

  render (data) {
    return this.createNode(data.id)
  }
}

class ItemTitle extends Node {
  create () {
    this.tag = 'span'
  }

  render (data) {
    return this.createNode(data.title)
  }
}
```

Lets go one level up, the TodoList node, which contains the three node we already created.
The TodoList node extends the internal `List` class which renders a `<ul> <li>` list.

```js
class TodoList extends List {
  create () {
    this.childNodes(ItemId, ItemTitle, ItemStatus)
  }
}
```

The method `childNodes()` defines a node's child node(s). It adds 1 or more node classes (Not instances!). If we call `render()` we get the node's html.

The class `TodoList` has its own `render()` method, we do not overwrite it here. A list's `render()` method expects an array of objects as its argument. It walks through the array and creates one instance of the child node(s) for each array element wrapped by `<li class="list-item"></li>`

```js
const node = new TodoList()
const html = node.render([{
  id: '001',
  title: 'First todo item',
  status: 'open'
}, {
  id: '002',
  title: 'Second todo item',
  status: 'progress'
}, {
  id: '003',
  title: 'Third todo item',
  status: 'done'
}])
```

The rendered html:

```html
<ul class="todo-list">
  <li class="list-item">
    <span class="item-id">001</span>
    <span class="item-title">First todo item</span>
    <span class="item-status">open</span>
  </li>
  <li class="list-item">
    <span class="item-id">002</span>
    <span class="item-title">Second todo item</span>
    <span class="item-status">progress</span>
  </li>
  <li class="list-item">
    <span class="item-id">003</span>
    <span class="item-title">Third todo item</span>
    <span class="item-status">done</span>
  </li>
</ul>
```

The `Listing` class is a container for the `TodoList`.

```js
class Listing extends Node
  create () {
    this.childNodes(TodoList)
  }
```

The `tag` property and `render()` method is not necessary here. It is defined in the `Node` core class.

Default tag: `div`  

Render method default:
```js
render (data) {
  return this.createNode(data)
}
```

The `Editor` element, a html form to add new items. Lets do it all at once, we go through the tree from the end up to `Editor`.

```
Editor
  CreateForm
    CreateInput
    SubmitButton
```

```js
class CreateInput extends Node {
  create () {
    this.tag = 'input'
    this.isVoidTag = true // Avoid rendering a closing tag
  }
}

class SubmitButton extends Node {
  create () {
    this.tag = 'button'
  }

  render (data) {
    return this.createElement('Add item') // Use a string as data
  }
}

class CreateForm extends Node {
  create () {
    this.tag = 'form'
    this.childNodes(CreateInput, SubmitButton)
  }
}

class Editor extends Node {
  create () {
    this.tag = 'form'
    this.childNodes(CreateForm)
  }
}

```

Last node! The `Todo` node, our root node.

```js
class Todo extends Node {
  create () {
    this.childNodes(Editor, Listing)
  }
}
```

Lets test it.

```js
const node = new Todo()
const html = node.render([{
  id: '001'
  title: 'First todo item'
  status: 'open'
},{
  id: '002'
  title: 'Second todo item'
  status: 'progress'
}, {
  id: '003'
  title: 'Third todo item'
  status: 'done'
}])
```

The rendered html is the same as the first example above.


### IDs

All objects in in blueprint have an unique id. This list shows the prefixes.

| Prefix | Object       |
| ------ | ------------ |
| `c`    | Component    |
| `t'`   | Tags         |
| `l`    | TagList      |
| `e`    | Templates    |
| `g`    | Signals      |
| `s`    | States       |
| `a`    | Actions      |
| `d`    | DataServices |
