rcrowe / TwigBridge

Give the power of Twig to Laravel
MIT License
893 stars 167 forks source link

Twig in combination with Eloquent #255

Open ceesvanegmond opened 8 years ago

ceesvanegmond commented 8 years ago

Hello there, I've a question about this package, in particular with the use of this package in combination with Eloquent.

In the past, i've worked with Doctrine (icm Twig) cool thing about this is i could write the following.

<?php

// User Entity
class User
{
    private $name;

    public function getName()
    {
        return $this->name
    }
}
<!-- TWIG -->
<span>{{ user.name }}</span>

In this case, the getName() function in the entity is fired, because Twig automatically converts the name to getName(), which makes sense.

Now we're using Laravel and Eloquent as the ORM layer, and were experiencing some problems with it. Take a look at the next example:

<?php

use Illuminate\Database\Eloquent\Model;

// Eloquent
class User extends Model
{
    public function getName()
    {
        return $this->name;
    }
}
<!-- TWIG -->
<span>{{ user.name }}</span>

In this case, the getName() in Eloquent is not fired, because it uses the __get() method underneath prior to the specified getName() method. I really want Twig to fire the getName() method. Does anyone experience the same problem, any ideas how to solve it?

One way could be to rename the getName() method to getNameAttribute(), in that case that method is being fired, downside of this is that you lose autocompletion in your templates.

Another way could be to write this in html:

<!-- TWIG -->
<span>{{ user.getName() }}</span>

In this way the method getName() in Eloquent is being fired, this actually works but i like the short user.name notation more than fully specify the method name.

Any solutions?

josephlavin commented 8 years ago

This is just a guess, no actual testing done.

<?php

use Illuminate\Database\Eloquent\Model;

// Eloquent
class User extends Model
{
    public function name()
    {
         return $this->getName();
    }

    public function getName()
    {
        return $this->name;
    }
}
<!-- TWIG -->
<span>{{ user.name }}</span>

Twig should execute the name method (and you do not have to put () I believe).

Or you could write a trait that changes the behavior of __get() and executes any __getFoo methods that exist, otherwise fall back to default behavior.

ghost commented 8 years ago

Just come across this problem myself. I have a mutator which gets/sets a file object which is not firing when using twig. This is a shame as I much prefer twig to blade.

ghost commented 8 years ago

Ignore that, I made a mistake (which @ceesvanegmond also made) which is that for Eloquent models the accessor is defined as getNameAttribute not getName.

ceesvanegmond commented 8 years ago

@Nyorai Right. I think there's no direct solution right?

barryvdh commented 8 years ago

So what is the problem with using the Eloquent mutators? Just the IDE autocompletion?

Doesn't it autocomplete user.name when you have a property $name? (Could be auto generated using https://github.com/barryvdh/laravel-ide-helper#automatic-phpdocs-for-models )