daftspunk / backpack-plugin

A collection of useful front-end components
2 stars 2 forks source link

Component behaviors similar to Controllers in backend #1

Open tomaszstrojny opened 7 years ago

tomaszstrojny commented 7 years ago

I know it is not the best place to contact, but I am currently considering to start working on something similar to this project. My idea is to create open-sourced plugin that is giving some componentBehaviors to extend functionality of components to render list similar to those in backend (using config_list.yaml in component's view plugin) and render forms as well using the same approach. My question here is, do you think it is good idea (maybe there is more OctoberCMS-way to do this)? If my thinking makes sense than I have to get the answer in https://github.com/octobercms/october/issues/2654.

daftspunk commented 7 years ago

That is one idea, yes. This plugin is not finished cooking. We still need to decide the best way to approach front-end tools. Feel free to develop your own plugin and share your ideas.

tomaszstrojny commented 7 years ago

I am trying to create plugin that provides much more than styling components, but if there will be more such "component behaviors" I will probably move this to a separate plugin. The plugin's code is here: https://github.com/initbizlab/oc-cumuluscore

As you can see I had to move functions to traits. I wanted to write those in behavior but for now it is not possible.

I have no idea if there is a simple way to use backend controllers behaviors in components and I created something similar, but it hurts so much to copy paste your code instead of using it in a different place (components) :)

daftspunk commented 7 years ago

As you can see I had to move functions to traits. I wanted to write those in behavior but for now it is not possible.

I recall there was an issue logged already about using behaviors with components, something about them was not working. See if you can locate this issue and I'll take a look.

tomaszstrojny commented 7 years ago

I think I have located the issue and I have described it in the issue you mentioned: https://github.com/octobercms/october/issues/2654 Please take a look at what I have written in "actual behavior" part. I have no idea why there is the second check (the if method_exists one) in ComponentBase.php:

public function __call($method, $parameters)
{
    try {
        parent::__call($method, $parameters);
    }
    catch (BadMethodCallException $ex) {}

    if (method_exists($this->controller, $method)) {
        return call_user_func_array([$this->controller, $method], $parameters);
    }

    throw new BadMethodCallException(Lang::get('cms::lang.component.method_not_found', [
        'name' => get_class($this),
        'method' => $method
    ]));
}

I think this might be the faulty part.

LukeTowers commented 7 years ago

@czerwonyd There may be a fix for this https://github.com/octobercms/october/issues/2654 here: https://github.com/octobercms/october/issues/2654#issuecomment-279954089. Let me know if that fix works for you and then I'll apply it in core.

tomaszstrojny commented 7 years ago

@LukeTowers this one fixed the problem with running method from behaviors in onRun() method. I do not understand though why methods in behavior are not visible for component's defineProperties() method. Probably defineProperties() is run before behavior gets implemented.

The example is: I want to create component that will be rendering a list of records from model (as in backend). Example code:

class ProductsList extends ComponentBase
{
    public $implement = [
      'InitBiz.CumulusCore.Behaviors.ListComponent'
    ];
. . .
    public function defineProperties()
    {
        dd($this->listProperties());
    }
. . .
class ListComponent extends ComponentBehavior {
. . . 
    public function listProperties() {
        return [
            'updatePage' => [
                'page'        => 'Page to update record',
                'description' => 'Pick the page where records update component is embedded',
                'type'        => 'dropdown'
            ],
            'createPage' => [
                'page'        => 'Page to create record',
                'description' => 'Pick the page where records create component is embedded',
                'type'        => 'dropdown'
            ]
        ];
    }
. . . 

And the defineProperties() throws exception: Method listProperties() not found. listProperties() makes sense for me as there will be some properties that should be set in all list-components like updatePage for page that user should be redirected after clicking the record in the list.

I just don't get why the dd($this->listProperties()); in onRun() works while in defineProperties() does not...

tomaszstrojny commented 6 years ago

It's been a while, but finally I have a living beta version of the building list functionality. I am showing how it works here: https://www.youtube.com/watch?v=jaRWCCYo6wk Lists are loaded using AJAX framework and all partials can be overridden by a partial in component view directory.

Right now I am considering creating behavior for form components. But I have to ensure that you guys are not working on something similar because I am sure you will do it better than me and I just don't want to put away my code after you introduce such a functionality :)