MD66
MD66

Reputation: 101

how to use forward in view zend 2

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?

Upvotes: 1

Views: 511

Answers (3)

MD66
MD66

Reputation: 101

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

Upvotes: 0

Wilt
Wilt

Reputation: 44356

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.

Upvotes: 1

danopz
danopz

Reputation: 3408

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

Upvotes: 1

Related Questions