1

I want to write a plugin in ZF2,

An example of the plugin is a like button that shows in every post. It should for example print in PostsAction,

I know I can use:

$like = $this->forward()->dispatch('Application\Controller\Index', array(
    'action' => 'like',
    'postId'   => $Id
));

$like variable returns a button that users can click on. But I want to echo this in the view. In forward the view is not defined.

Also if I use

return $this->getView()->render('application/index/like', array('postId' => $Id));

I don't have access to postId in likeController, because it is set in the view. How I can implement these type of plugins that need a dynamic variables?

Wilt
  • 41,477
  • 12
  • 152
  • 203
MD66
  • 101
  • 3
  • 11
  • I hope you don't mind but I made some changes to make your question more understandable. I also answered your question. I think view helpers are what you are looking for. – Wilt Jul 30 '15 at 14:53

3 Answers3

1

Solution using view helper

I think what you are looking for is a custom view helper. You can read on this in the official ZF2 documentation.

You have to write your custom button view helper, register it and then you can use it in your view.

The helper class:

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;

class LikeButtonHelper extends AbstractHelper
{
    public function __invoke($post)
    {
        //return here your button logic, you will have access to $post

    }
}

Register your helper within a configuration file:

'view_helpers' => array(
    'invokables' => array(
        'likeButtonHelper' => 'Application\View\Helper\LikeButtonHelper',
    ),
)

And finally in the view you can use it like this:

foreach($posts as $post){
    echo( ... your code to show the post ...);
    echo $this->likeButtonHelper($post);
}

UPDATE - Solution using forward plugin

I think I get what you mean now. I also think the example you are talking about is what in the ZF2 forward plugin documentation is referred to as “widgetized” content.

I think you are doing it correctly. You can attach the return value $like as a child to the view of the original controller (from where you forwarded in the first place).

So in your WidgetController:

use Zend\View\Model\ViewModel;

class WidgetController extends AbstractActionController 
{
    public function likeAction()
    {
        $post= $this->params()->fromRoute('post');
        $viewModel = new ViewModel(array('post' => $post));
        $viewModel->setTemplate('view/widgets/like');

        return $viewModel;
    }
}

So in your PostController:

use Zend\View\Model\ViewModel;

class PostController extends AbstractActionController 
{
    public function postsAction()
    {
        $likeWidget = $this->forward()->dispatch('Application\Controller\WidgetController', array(
            'action' => 'like',
            'post'   => $post
        ));

        $viewModel = new ViewModel();
        $viewModel->setTemplate('view/posts/post');
        $viewModel = new ViewModel(array(
             //...add your other view variables...
        ));

        // Add the result from the forward plugin as child to the view model
        if ($likeWidget instanceof ViewModel) 
        {
            $viewModel->addChild($likeWidget , 'likeWidget');
        }

        return $view;
    }
}

And finally in your post view template add:

echo($this->likeWidget);

That is where the widget will eventually output.

The problem remains that you can not do this inside a foreach loop (a loop for printing your posts) in the view. That is why I suggested using a view helper and @copynpaste suggests using a partial, those are more suitable for adding additional logic inside a view.


Note: Personally I don't like this forward solution for something so simple as a like button. There is hardly any logic in the controller and it seems overly complicated. This is more suitable for reusing a whole view/page that will be both rendered by itself as well as nested in another view. The partials or view helpers seem much more suitable for what you want to do and those are very proper ZF2 solutions.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • i saw a code that echo output of a controller and it's view,in your example we just have controller, i want to use a MVC structure plugin,i want to create models views controllers of my like button and use them, i saw a code ago,it listen in onDispatch event and use forward then retrun output.i have not that code right now – MD66 Jul 30 '15 at 18:14
  • @MD66 I updated my answer, but I would recommend you to seriously consider view helpers or partials instead of using the forward plugin for what you want to do. – Wilt Jul 31 '15 at 08:17
  • Thank you so much,But i believe we can use forward in view with onRender or onDispatch event listener,anyway thank you for you answer – MD66 Jul 31 '15 at 13:25
  • Thank you so much, I found it ,developed by Mohammad Rostami,Special thanks to him : https://github.com/mbrostami/zf2Plugin – MD66 Aug 03 '15 at 18:00
1

Looks like you only need partials. A partial in ZF2 is only a view which you print in another view and give some params to it.

So you could define a View:

// application/partials/button.phtml
<button data-postId="<?php echo $this->postId ?>">Like It!</button>

And use it in other View:

echo $this->partial('application/partials/button.phtml', array(
    'postId' => $thePostId
));

Official Documentation
Nice Answer on SO to implement with template_map

Community
  • 1
  • 1
danopz
  • 3,310
  • 5
  • 31
  • 42
  • sory, but my porpose was a way to get output of another controller, my button controller may contain a complex code such as access models and services, in partial we have view only. – MD66 Jul 30 '15 at 18:04
0

I found it ,developed by Mohammad Rostami,Special thanks to him : Plugin In ZF2

MD66
  • 101
  • 3
  • 11
  • From your question it was not clear you were looking for another module. It would be good to add a full code example on how to use this to your answer. It might help other people who end up here. Adding a only a link to the source is not considered a proper answer. – Wilt Aug 04 '15 at 07:29
  • i can't publish all of code here,it is not a little code to insert here – MD66 Dec 09 '15 at 05:52
  • You should not publish all the code, but a code example on how you can use this... The module is badly documented and it will be helpful to other stack**overflow** users to see how they can use this plugin and how the code relates to your question. – Wilt Dec 09 '15 at 08:18