Show formatted properties in Laravel's blade template

Viewed 820

Let's say, I have some Model with updated_at attribute. I want to show it in template like this

{{ $model->updated_at }}

This can be used in many places so I DO NOT do this

{{ $model->updated_at->format('d/m/Y H:i:s') }}

But instead

public function getUpdatedAtAttribute($value)
{
    return $value->format('d/m/Y H:i:s');
}

But there is one big problem with this solution, I can not use $model->updated_at in controllers anymore, because it returns string, not Carbon instance.

Two possible solutions

1.

public function getUpdatedAtFormatterAttribute($value)
{
    return $this->updated_at->format('d/m/Y H:i:s');
}

and in template

{{ $model->updated_at_formatted }}

2.

Use package like this

class ModelPresenter extends Presenter {

    public function updated_at()
    {
        return $this->updated_at->format('d/m/Y H:i:s');
    }
}

And

{{ $model->present()->updated_at }}

From architectural point view I think second version is cleaner but are there some proven solutions? This can be not about Laravel only but about any popular PHP framework.

2 Answers

The two methods described in the question are, in fact, the standard and widely-accepted approaches to adding DRY date-formatting on Laravel models:

  • Add one or more accessors to a model for specific date formats
  • Use a presenter that wraps the model with logic for display

Both approaches consolidate the formatting logic at one location so we can update the format later, if needed, without changing every line that outputs a date. Both also avoid overriding the source attribute so the functionality is available when needed.

Which to choose depends on the size and requirements of the application. Smaller applications with small teams can certainly justify the first approach, which avoids introducing complexity by adding a presenter layer. The second approach may suit larger teams that can benefit from the abstraction and seperation-of-concerns.

In some applications, I like to make a trait that we can add to any model which enables automatic date formatting attributes using the dates and date format declared on the model:

class User extends Model 
{
    use FormatsDates; 

    protected $dates = [ 'last_login_at' ]; 
    ...
}

$user->formatted_last_login_at; // mm/dd/yyyy

Because this question doesn't include such a trait in its scope, I'll leave the implementation as an exercise to the reader, but I'm happy to help if needed.

try this - don't forget call in model- use Carbon\Carbon; Model:

public function getUpdatedAtAttribute($updated_at)
{
    return Carbon::parse($updated_at)->format('d/m/Y H:i:s');
}

In your blade view call like this

{{$model->getUpdatedAtAttribute($updated_at)}}
Related