laravel / pennant

A simple, lightweight library for managing feature flags.
https://laravel.com/docs/pennant
MIT License
474 stars 48 forks source link

Feature Request: Feature Alias #67

Closed devajmeireles closed 1 year ago

devajmeireles commented 1 year ago

Problem

When we choose to use features through classes created with pennant:feature, the feature name is composed of the class name: App\Features\NewDashboard, so when we need to check the feature we need to use the reference to the class:

use App\Features\NewDashboard;
use Laravel\Pennant\Feature;

Feature::active(NewDashboard::class);

The main problem with this is when we need to check the feature through the blade directives: 🥵

@feature(\App\Features\NewDashboard::class)

Solution

Considering the class name as a string, it would be possible to generate an alias name from the class name to enable an easier way to reference the feature without having to use the format mentioned above, that way we could interact with the feature in a similar way to when we define it via AppServiceProvider, without using classes.

Class: ...\NewDashboard::class 👉🏻 new-dashboard

Class: ...\Vip\NewDashboard::class 👉🏻 vip.new-dashboard

Usage

use Laravel\Pennant\Feature;

Feature::active('new-dashboard');
Feature::active('vip.new-dashboard');
@feature('new-dashboard')
@feature('vip.new-dashboard')

Default Alias

The stub for features generated from pennant:feature could contain the $alias property with the proposed alias value of the feature, according to the class name:

namespace App\Features;

class NewDashboard
{
    /**
     * The default alias.
     *
     * @var string
     */
    protected string $alias = 'new-dashboard';

    // ...

Observations:

  1. The null value or the removal of $alias property could be an option to ignore (don't generate) alias.
  2. The alias can be a database column or not, according to what the Laravel team decides.

Easy Way

Perhaps if something like this were possible it would result in the suggestion above 👇🏻

use Laravel\Pennant\Feature;
use App\Features\NewDashboard;

Feature::define('new-dashboard', NewDashboard::class);
// or ...
Feature::alias('new-dashboard', NewDashboard::class);

Final Words

We know that it is possible to do all of the above mentioned when we choose not to use classes for the features, but this ends up making the AppServiceProvider with a lot of definitions or that we need to create a specific ServiceProvider for this.


Hope this helps,

Thanks.

timacdonald commented 1 year ago

@devajmeireles I think this is already possible. You need to ensure that the class is being registered either explicitly via...

use App\Features\NewDashboard;

Feature::define(NewDashboard::class);

or conventionally via...

Feature::discover();

Then add a public "name" property to the feature with your alias.

namespace App\Features;

class NewDashboard
{
    public $name = 'new-dashboard';

    // ...
}

Please let me know if this doesn't work and we can open this one up and take another look.

Treggats commented 11 months ago

For anyone coming across this issue. Tim's suggestion works.

Laravel Pennant v1.5.0

timacdonald commented 11 months ago

🥳

Treggats commented 11 months ago

Created a pull request to add it to the docs.

https://github.com/laravel/docs/pull/9090