Ignore

Please note that your browser is not supported.

We recommend upgrading to the latest Firefox or Google Chrome.

Frontend: Data Bindings

Pakyow view templates can present dynamic data, but don't contain any presentation logic themselves. Instead, they declare their semantic intent through a few special attributes that describe the dynamic data that the template wants to present.

Let's look at an example:

<h1>
  Your Messages:
</h1>

<article binding="message">
  <p binding="content">
    message content goes here
  </p>
</article>

The binding attribute declares the intent to present dynamic data on the node, while also defining what specific type or attribute to present. In this example, the article represents a message type, with content being the sole attribute of the message type.

How Pakyow understands bindings

This section contains a bit of backend Ruby code, but don't worry if it doesn't make sense! It's only there to help get a full understanding of how data bindings work across the stack.

Bindings extend the natural hierarchy of HTML to define a data structure within the template. Using the example from above, if you remove nodes that don't represent data bindings this simple data structure emerges:

message:
  - content

This structure is exactly what Pakyow. When Pakyow renders the view, it looks for data exposed on the backend that matches the data structure represented by the view, then populates the view with the data.

For example, a single message can be exposed like this:

expose "message", {
  content: "This is our first message!"
}

Pakyow presents the data in the template, resulting in this rendered view:

<h1>
  Your Messages:
</h1>

<article>
  <p>
    This is our first message!
  </p>
</article>

In a nutshell, that's all there is to view rendering in Pakyow! We can summarize the steps for view rendering like this:

  1. The view template declares its intent using the natural hierarchy found in HTML, along with sprinkles of data binding attributes.

  2. The backend gathers and exposes data for a presentation intent ahead of view rendering.

  3. Pakyow connects the frontend and backend together by matching their intents. The result is a fully rendered view that presents dynamic data.

The frontend and backend never talk directly to each other, even when it comes to presenting dynamic data. Instead, the frontend view templates define a presentation contract based on what it wants to present.

This approach gives the frontend designer full control over presentation without introducing any complex rendering logic to the view templates. It also benefits the backend developer by not involving them with all of the various presentation concerns. Each role is able to stay focused on their core concerns while communicating effectively through the common presentation contract.

Prototype values

Values defined in binding nodes are considered prototype values. They are automatically removed when data is presented during rendering, but they remain visible when running in prototype mode. This lets you design your interface using realistic values without needing to remove them later.

Presenting datasets

Datasets consisting of more than one object can also presented with data bindings. Building on example from above, we expose three objects to be presented in the same view template as before:

expose "message", [
  {
    content: "This is the first message."
  },
  {
    content: "This is the second message."
  },
  {
    content: "This is the third message."
  },
]

This is what the final rendered view will look like:

<h1>
  Your Messages:
</h1>

<article>
  <p>
    This is the first message.
  </p>
</article>

<article>
  <p>
    This is the second message.
  </p>
</article>

<article>
  <p>
    This is the third message.
  </p>
</article>

Once again we see that presentation is simply the process of making the underlying view template match the data being presented.

Removing un-presented bindings

If data isn't exposed for a binding, it will be removed during rendering. This works at both the level of a binding type as well as individual attributes. For example, say we expose a message object that doesn't have an attribute:

expose "message", {
}

The rendered view would look like this:

<h1>
  Your Messages:
</h1>

<article>
</article>

If a message isn't exposed at all, the rendered view would look like this:

<h1>
  Messages
</h1>

Cleaning up un-presented bindings ensures that prototype values are never presented in the final rendered view.

Presenting nested objects

Binding types can contain other types, giving you a way to present data that contains related data. Let's build on our message example from above to add the concept of replies to the view template:

<h1>
  Your Messages:
</h1>

<article binding="message">
  <p binding="content">
    message content goes here
  </p>

  <ul>
    <li binding="reply">
      <p binding="content">
        reply content goes here
      </p>
    </li>
  </ul>
</article>

Here we again rely on the hierarchical nature of HTML to represent our view in a way that not only makes sense from a frontend design perspective, but opens the door to presenting complex data.

Let's expose a single message with many replies for rendering:

expose "message", {
  content: "This is our first message!",

  replies: [
    {
      content: "Reply 1"
    },
    {
      content: "Reply 2"
    },
    {
      content: "Reply 3"
    }
  ]
}

Here's what the rendered view would look like:

<h1>
  Your Messages:
</h1>

<article>
  <p>
    This is our first message!
  </p>

  <ul>
    <li>
      <p>
        Reply 1
      </p>
    </li>

    <li>
      <p>
        Reply 2
      </p>
    </li>

    <li>
      <p>
        Reply 3
      </p>
    </li>
  </ul>
</article>

Pakyow has a basic understanding of language rules, allowing it to match the replies data to the reply binding in the view template. The result is a rendered view that exactly matches the exposed data.

Providing additional binding context

Sometimes it's necessary to have multiple bindings of the same type in a single view template. You might want to present two lists of posts—one presenting the latest messages, and the other presenting the most popular messages. Pakyow provides a feature called binding channels that lets you express additional intent behind your bindings.

Here's what a view template might look like for the case above:

<section>
  <h1>
    Latest Messages:
  </h1>

  <article binding="message:latest">
    <p binding="content">
      latest message content
    </p>
  </article>
</section>

<section>
  <h1>
    Most Popular Messages:
  </h1>

  <article binding="message:popular">
    <p binding="content">
      popular message content
    </p>
  </article>
</section>

Channels are defined on the binding attribute in the format of:

{binding}:{channel}:{channel}

Pakyow will treat both lists as the message type, while addressing them separately for presentation. Here's how data would be exposed to each binding channel from the backend:

expose "message:latest", [
  {
    content: "This is a recent message."
  }
]

expose "message:popular", [
  {
    content: "This is a popular message."
  }
]

And here's what the rendered view would look like:

<section>
  <h1>
    Latest Messages:
  </h1>

  <article>
    <p>
      This is a recent message.
    </p>
  </article>
</section>

<section>
  <h1>
    Most Popular Messages:
  </h1>

  <article>
    <p>
      This is a popular message.
    </p>
  </article>
</section>

Form binding channel

Pakyow automatically defines a binding channel for bindings defined on form elements. Forms serve a different intent in the user-interface, making it necessary to address them separately from other bindings.

To expose data to a form, data is exposed to the binding's form channel:

expose "message:form", [...]

Using parts of bound values

So far we've only seen examples of presenting content in binding nodes. However, one or more attributes can also be added to a binding node during presentation. The frontend designer can control how presentation affects a particular binding node by including or excluding specific parts.

To be sure that the binding node is only changed in a specific way, use the include attribute like this:

<article binding="message">
  <p binding="content" include="content class">
    message content goes here
  </p>
</article>

Now only the values for content and class will be presented on the node (content referring to the text content within the node). You can also use the exclude attribute to exclude specific parts:

<article binding="message">
  <p binding="content" exclude="class">
    message content goes here
  </p>
</article>

Now the title node will never present a value for class.

Next Up: View Versions