Decorate Your Model Attributes Using Laravel Presenter Package
Tags: opensource, laravel, packages
Published: 2022-02-15 00:18:31

---
title: Decorate Your Model Attributes Using Laravel Presenter Package
published: true
date: 2022-02-14 23:34:12 UTC
tags: OpenSource, laravel, packages
canonical_url: https://coderflex.com/blog/decorate-your-model-attributes-using-laravel-presenter-package
---

## Introduction
[Laravel Presenter](https://github.com/coderflexx/laravel-presenter) by [@ousid](https://github.com/ousid) is a clean way to decorate your models, 
and incrementally refactor from the simplest solution to a clean, reusable system.


## Prerequisite
You need to know the following:
- Need to know [PHP](https://php.net)
- Basics on Laravel & the artisan command [Laravel](https://laravel.com)
- Basics on composer [Composer][https://getcomposer.org]

## Why this package?
Sometimes we need to present some custom attributes and re-use them in many places in our app, and the simplest way is to put them inside your `model` class, but is it efficient?
This page allows you to make a place for all your custom attribute methods and decorate them to use them wherever you want, and help you to maintain/refactor your code easily.

## Installation

You can install the package via composer:

```bash
composer require coderflexx/laravel-presenter
```

You can publish the config file with:

```bash
vendor:publish --provider="Coderflex\LaravelPresenter\LaravelPresenterServiceProvider"
```

This is the contents of the published config file:

```php
return [

    /*
    |--------------------------------------------------------------------------
    | Presenter Namespace
    |--------------------------------------------------------------------------
    |
    | This value informs LaravelPresenter which namespace you will be 
    | selecting to store your presenters by default.
    | If this value equals to null, "App\Presenter" will be used 
    | by default.
    |
    */

    'presenter_namespace'   => 'App\\Presenters',
];
```

## Usage
The implementation of this package is so simple, all what you need to do is the following:

## Model Implementation

-  Implement `CanPresent` Interface 
-  Use `UsesPresenters` Trait

```php
use Coderflex\LaravelPresenter\Concerns\CanPresent;
use Coderflex\LaravelPresenter\Concerns\UsesPresenters;
// ...

class User extends Authenticatable implements CanPresent
{
    use UsesPresenters;

    // ...
}
```

## Create New Model Presenter class

This package gives you an easy way to generate new `Presenter` class, all you need to do is to use `presenter:make` command.

```bash
php artisan presenter:make UserPresneter
```

`UserPresenter` in our case, leaves by default in `App\Presenters`.

This is the contents of the `UserPresenter` file:

```php
<?php

namespace App\Presenters;

use Coderflex\LaravelPresenter\Presenter;

class UserPresenter extends Presenter
{
    // 
}

```


If you want to change the directory, you have two options.

First options is to set the full namespace while you're creating the presenter class

```bash
php artisna presneter:make App\Models\Presenter\UserPresenter
```

Or change `presenter_namespace` from `config/laravel-presenter` file.

```php
return [
    ...

    'presenter_namespace'   => 'App\\Presenters',

    ...
];
```

## Using the `Presenter` Generated Class
After you create the presenter class, you need to register it on the `Model` by adding the `$presenters` protected property:

```php
use App\Presenters\UserPresenter;
use Coderflex\LaravelPresenter\Concerns\CanPresent;
use Coderflex\LaravelPresenter\Concerns\UsesPresenters;
// ...

class User extends Authenticatable implements CanPresent
{
    use UsesPresenters;

    protected $presenters = [
        'default' => UserPresenter,
    ];
}
```
By default, the type of your presenter class is `default`, but you can use as many of presenters you want, just by identifying the type in `$presenters` property.

## Real Life Example
Now, after we generated the `presenter` class, and we implemented it successfully in our model, we can use it like so:

In your `UserPresenter` class or any presenter class you generated.

```php
...
class UserPresenter extends Presenter
{
    public function fullName()
    {
        return "{$this->model->first_name} {$this->model->last_name}";
    }
}
...
```

We add a new method to present the `fullName`.

In your blade or any place you want, you can do:

```php
$user->present()->fullName
```
Your application will show the full name from the method you added.

## Adding Another Presenter Type:
Like I said above, by default the type will be `deafult` but, you can add more types as you need.

Here is an example:

```php
use App\Presenters\UserPresenter;
use Coderflex\LaravelPresenter\Concerns\CanPresent;
use Coderflex\LaravelPresenter\Concerns\UsesPresenters;
// ...

class User extends Authenticatable implements CanPresent
{
    use UsesPresenters;

    protected $presenters = [
        'default' => UserPresenter,
        'setting' => UserSettingPresenter,
    ];
}
```

Generate new `UserSettingPresenter`

```bash
php artisan presenter:make UserSettingPresenter
```

Add anything to `UserSettingPresenter` method

```php
...
class UserSettingPresenter extends Presenter
{
    public function lang()
    {
        return $this->model->settings->defaultLang;
    }
}
...
```

Finally, set `setting` as a type:

```php
$user->present('setting')->lang;
```

By that, you can split your logic and make your code base even cleaner.


## Changelog

You can follow the changes on this [package](https://github.com/coderflexx/laravel-presenter) by accessing the [changelog](https://github.com/coderflexx/laravel-presenter/blob/main/CHANGELOG.md) or the [releases](https://github.com/coderflexx/laravel-presenter/releases)

## Contributing
If you want to contribute, feel free to read the [CONTRIBUTING](https://github.com/coderflexx/laravel-presenter/blob/main/.github/CONTRIBUTING.md) guidelines, and make your `PR`

## Conclusion
Today we s learned about [Laravel Presenter](https://github.com/coderflexx/laravel-presenter) package, and how to use it. To make our development process easier and save us time.