Presenter API

Bryan Powell edited this page Jul 26, 2017 · 16 revisions

Definition of the 1.0 Presenter API for View, ViewSet, Presenter, and a handful of subclasses.

For Consideration:

  • Form objects will be created only using the form method.
    • Can we automatically set them up to some extent?
  • Will forms (and other semantic elements) have presenters?
  • Should component, partial, and other traversal methods that return a set be plural?
  • Need a better way of defining navigations. For example, currently you have to add a binding to setup a link. This seems wrong. Instead, perhaps we define navigations both on the backend and the frontend.
  • Consider exposing semantic elements to the backend (e.g. nav, header, footer, main, section, article).
  • Whose concern is it to build views? Presenter or View?

Significant View Types

Defined as significant in StringDoc. Probably accessible through View.

  • title
  • container
  • partial
  • component
  • form
  • scoped

View

Single view, which is either a doc or a node.

Traversal

Methods for narrowing to a specific part of the view.

find

Finds a specific scoped node within the view, returning a new view set (even if the set is empty).

Note that internally we still keep up with whether a node is a scope (a scoped node that contains a prop) or a prop (a scoped node that doesn't contain a scoped child). Requiring the developer to know what node is a scope vs a prop is unnecessary; both scopes and props can be traversed and interacted with in the same way.

Given this view:

<div@post>
  <p@body>body goes here</p>
</div>

The top level scope can be found:

view.find(:post)

Traversal through n scopes is also possible in a single method call:

view.find(:post, :body, ...)

The above example is equivalent to:

view.find(:post).find(:body).find(...)

with

Creates a context in which the view can be further manipulated. Returns the resulting view.

view.with do |view|
  ...
end

This is more for organization as anything else, though it could be thought of as a transaction for transformations.

container

Finds a container by name. Returns a view or nil.

view.container(:foo)

partial

Finds a partial by name. Returns a view set.

view.partial(:foo)

component

Finds a component by name. Returns a view set.

view.component(:foo)

form

Finds a form by scope. Returns a view set.

view.form(:post)

Transformation

Methods that transform the view with data.

bind

Recursively binds values to a view.

<div@post>
  <h1@title></h1>
</div>
view.bind(post: { title: "..." })

# or
view.find(:post).bind(title: "...")

bind optionally accepts a block, which is yielded the view and object for each binding.

transform

Previously known as match.

Transforms a view to match the shape of the data.

<div@post>
  <h1@title></h1>
  <p@body></p>
</div>
view.find(:post).transform({})

Resulting view:

<div@post>
</div>
view.find(:post).transform(title: "foo")

Resulting view:

<div@post>
  <h1@title></h1>
</div>

Optionally accepts a block, which is yielded the transformed view and object for each transformation.

present

Previously known as apply.

Tranforms the view, then binds data to it.

Optionally accepts a block, which is yielded the presented view and object for each presentation.

Modification

General modification methods.

append

Appends a string, view, or view set as a child to the view.

prepend

Prepends a string, view, or view set as a child to the view.

after

Inserts a string, view, or view set after the view.

before

Inserts a string, view, or view set before the view.

replace

Replaces the view with a string, view, or view set.

remove

Removes the view.

clear

Removes the view's children.

text=

Sets the view's text (works like innerText in JavaScript).

html=

Sets the view's html (works like innerHTML in JavaScript).

Attributes

Methods for dealing with attributes of the view.

attributes

Returns an attributes object for the view.

Aliased as attrs.

attributes=

Sets multiple attributes for the view at once. Accepts a hash or attributes object.

This method will always override what attributes are already set on the view.

Aliased as attrs=.

Front Matter

Front matter will be more useful in 1.0 via the info method (available on view).

Given this view:

---
foo: bar
---

...

The info can be accessed:

view.info(:foo)

Front matter can be defined on any layout, page, or partial. Info will be merged for layouts/pages during compilation.

Front matter in partials is scoped only to the partial, meaning it cannot access front matter defined on the including view.

Introspection

Methods for learning more about a view.

html, text, ==, type, name

  • container?
  • partial?
  • component?
  • form?
  • decorated?

Initialization

Methods for creating new view objects.

new, self.load

Rendering

Methods for rendering a view.

to_html, to_s

ViewSet

Set of View objects that can be acted on at once.

TODO: each, ==, remove, to_a, to_html, to_s, <<, append, first, last, delete, concat, [], length, find, with, transform, bind, present, other view modification methods (?), name (scope name via find)

for

Yields a view and its matching data.

Attributes

Gets and sets attributes on a View.

Presenter

Presents a View object in context of a request.

mixin

TODO

title=

Gets the title (available only on full presenters).

title

Sets the title (available only on full presenters).

Form

TODO

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.