Toura/mulberry — Issue #207: Standardize component API
Author: rmurphey
Created: 2011-12-15 13:31:26+00:00
State: open

Currently, the "Toura" set of components use `dojo.declare`, while Mulberry users are encouraged to use `mulberry.component`.

The latter takes two arguments: the name of the component, and the prototype for the component. The name is used to create `client.components.`. It also does the following:

- creates `this.$domNode` if jQuery is present
- inherits from `toura._Component`
- provides a fallback `templateString` value of `%div` if none is provided
- calls the user-provided `prep` method, if provided, at the conclusion of `prepareData`
- calls the user-provided `init` method, if provided, at the conclusion of `startup`

`mulberry.component` was created to provide a simpler and more fool-proof interface than `dojo.declare`, and I hesitate to eliminate it. If we want to standardize on an API for creating components, then it should be some variation of `mulberry.component`. This variation would need to do the following:

- support inheritance from other "classes," but without requiring a user to provide *any* base class, including `toura._Component`
- support multiple namespaces, but preferably without requiring a user to provide any namespace

Put another way, the following would need to work:

```
mulberry.component('MyCustomComponent', proto);
mulberry.component('toura.components.ImageGallery', [ toura._Component, toura._ImageGallery ], proto);
mulberry.component('toura.components.BodyText', toura._Component, proto);
mulberry.component('MyCustomComponent', toura._Component, proto);
mulberry.component('MyCustomComponent', [ toura._Component, toura._ImageGallery ], proto);
```

Support for inheritance from other "classes" is fairly straightforward -- we can check the number of arguments that were passed, and behave accordingly (see, for example, [jQuery](https://github.com/jquery/jquery/blob/master/src/ajax.js#L268)).

Support for optional namespacing could be achieved by checking whether the first argument contains a `'.'`. If it did, we would assume the user had properly namespaced their component; if it didn't, we'd automatically put the component in the `client.components` namespace. This is technically straightforward, but seems that it could end up causing confusion.

The outstanding questions, then:

- Is there any way to avoid the confusion around namespacing?
- Are there any additional use cases that need to be addressed?
- Should "internal" components adopt the `prep` and `init` style of doing things?
- Is there any magic that should be removed from the default behavior of `mulberry.component`?