---
title: Presenters
---

# Presenters

<div class="documentation__toc"></div>

## Introduction

Presenters help you organize view layer (presentation) logic for objects. Logic in the `presenter` should _only_ be for display purposes.

An important secondary purpose for presenters is to map the decorated object's API in a clean way for views.

For example, instead of requiring verbose code like this:

```twig
{{ person.getRelation('cousins').first().first_name }}
```

Presenters help you with much cleaner syntax:

```twig
{{ person.cousins.first.first_name }}
```

> All **presentable** objects including entry models and collections are automatically decorated with a presenter in the view layer.{.notice}

## Basic Usage

The `\Robbo\Presenter\PresentableInterface` interface tells the Streams Platform that the class is `presentable` and has a `getPresenter` method. By default `getPresenter` return an instance of `\Anomaly\Streams\Platform\Support\Presenter` or the nearest presenter to the class.

    public function newPresenter()
    {
        return new Presenter($this);
    }

### getObject

The `getObject` returns the decorated object instance from a presenter.

```php
$presenter->getObject();
```

```twig
{{ presenter.getObject() }}
```

> This method is very useful when working with API objects in the view layer where the **instance** is generally required and not the **presenter**.{.tip}

### __get

The `__get` magic method is invoked any time you attempt to access a decorated object's attribute. However you can also lazy-call methods (with no arguments) in this way.

Below we outline how you can leverage `__get` behavior to achieve clean view syntax. Procedure is listed in order of priority and the first matching scenario will be used.

#### Check the presenter for a method where the method is the camel case of the `{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->displayName();
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.displayName() }}
```

#### Check the presenter for a getter method where the method is the camel case of `get_{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getDisplayName();
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getDisplayName() }}
```

#### Check the presenter for a getter method where the method is the camel case of `is_{attribute_name}`.

```php
$presenter->enabled; // Returns: $presenter->isEnabled();
```

```twig
{{ presenter.enabled }} // Returns: {{ presenter.isEnabled() }}
```

#### Check the decorated object for a getter method where the method is the camel case of `get_{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getObject()->getDisplayName();
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getObject().getDisplayName() }}
```

#### Check the decorated object for a boolean getter method where the method is the camel case of `is_{attribute_name}`.

```php
$presenter->enabled; // Returns: $presenter->getObject()->isEnabled();
```

```twig
{{ presenter.enabled }} // Returns: {{ presenter.getObject().isEnabled() }}
```

#### Check the decorated object for a method where the method is the camel case of the `{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getObject()->displayName();
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getObject().displayName() }}
```

#### Check the decorated object for a getter style hook where the hook is `get_{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getObject()->call('get_display_name');
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getObject().call('get_display_name') }}
```

#### Check the decorated object for a standard hook where the hook is `{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getObject()->call('display_name');
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getObject().call('display_name') }}
```

#### Return the decorated object's attribute named `{attribute_name}`.

```php
$presenter->display_name; // Returns: $presenter->getObject()->display_name;
```

```twig
{{ presenter.display_name }} // Returns: {{ presenter.getObject().display_name }}
```

### __call

The `__call` magic method will try running the `method` on the decorated object. Remember the `__call` function is only invoked when the method does not exist on the presenter itself. So this effectively maps decorated object methods to the presenter.

> Presenters globally block calls to **delete**, **save**, and **update**.{.important}

## Manually Decorating Objects

You can manually `decorate` an object with the `\Anomaly\Streams\Platform\Support\Decorator` class.

##### Decorator::decorate()

The `decorate` method decorates the object. It can also decorate an entire collection of presentable items.

#### Returns: `\Anomaly\Streams\Platform\Support\Presenter` or `\Illuminate\Database\Eloquent\Collection`

#### Arguments

<table class="table table-bordered table-striped">

<thead>

<tr>

<th>Key</th>

<th>Required</th>

<th>Type</th>

<th>Default</th>

<th>Description</th>

</tr>

</thead>

<tbody>

<tr>

<td>

$value

</td>

<td>

true

</td>

<td>

mixed

</td>

<td>

none

</td>

<td>

The presentable object or collection of presentable items.

</td>

</tr>

</tbody>

</table>

#### Example

    $decorated = $decorator->decorate($model);

> Non-presentable values will be returned as is.{.notice}

##### Undecorating Values

The `\Anomaly\Streams\Platform\Support\Decorator` class can also be used for obtaining the original undecorated values.

##### Decorator::undecorate()

The `undecorate` reverses the decoration method's action. This is helpful for wrapping API methods for objects inside the view layer.

#### Returns: `mixed`

#### Arguments

<table class="table table-bordered table-striped">

<thead>

<tr>

<th>Key</th>

<th>Required</th>

<th>Type</th>

<th>Default</th>

<th>Description</th>

</tr>

</thead>

<tbody>

<tr>

<td>

$value

</td>

<td>

true

</td>

<td>

mixed

</td>

<td>

none

</td>

<td>

The presenter or collection of presenters.

</td>

</tr>

</tbody>

</table>

#### Example

    $original = $decorator->undecorate($model);

> Non-presentable values will be returned as is.{.notice}

#### Writing Presenters

Presenters are automatically generated for you when using the make stream command:

    php artisan make:stream stream_slug example.module.test

You can also create your own addon presenter in most cases by transforming the model class name into it's corresponding presenter class name:

    TestModel -> TestPresenter

In all other cases all you need to do is define your own `newPresenter` method on the `presentable` class:

    <?php namespace Anomaly\ExampleModule\Test;

    use Robbo\Presenter\PresentableInterface;
    use Anomaly\Streams\Platform\Support\Presenter;

    class TestObject implements PresenterInterface
    {

        /**
         * Return the presenter.
         *
         * @return string
         */
        public function newPresenter()
        {
            return new Presenter($this);
        }
    }

An example presenter looks like this:

    <?php namespace Anomaly\ExampleModule\Test;

    use Anomaly\Streams\Platform\Support\Presenter;

    class TestPresenter extends Presenter
    {

        /**
         * Return the full name.
         *
         * @return string
         */
        public function name()
        {
            return implode(' ', array_filter([$this->object->getFirstName(), $this->object->getLastName()]));
        }
    }

Now you can use this method in your API:

    $test->name();

Or view layer:

    {{ test.name() }}

