phpcakephpcakephp-3.0

How to create new Helper that uses the TemplaterTrait in CakePHP3?


I am trying to create a new Helper and I intend to use the templater.

My code is below.

<?php
/**
 * KimSia
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     TBD
 * @link          TBD
 * @since         0.1
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace Metronic\View\Helper;

use Cake\Core\Configure;
use Cake\View\Helper;
use Cake\View\StringTemplateTrait;
use Cake\View\View;

/**
 * Portlet helper library.
 *
 * Automatic generation of Portlet divs and HTML FORMs from given data.
 *
 * @property      HtmlHelper $Html
 * @property      FormHelper $Form
 * @link TBD
 */
class PortletHelper extends Helper
{

    /**
     * Other helpers used by PortletHelper
     *
     * @var array
     */
    public $helpers = ['Url', 'Html', 'Form'];

    /**
     * Default config for the helper.
     *
     * @var array
     */
    protected $_defaultConfig = [
        'templates' => [
            'portletStart' => '<!-- BEGIN FORM PORTLET--><div class="portlet box {{color}}">',
            'portletEnd' => '</div><!-- END FORM PORTLET-->',
        ]
    ];

    /**
     * Construct the widgets and binds the default context providers
     *
     * @param \Cake\View\View $View The View this helper is being attached to.
     * @param array $config Configuration settings for the helper.
     */
    public function __construct(View $View, array $config = [])
    {
        parent::__construct($View, $config);
    }

    /**
     * Returns an Portlet DIV element.
     *
     * ### Options:
     *
     * - `color` Color for the Portlet
     *
     * @param array $options An array of html attributes and options.
     * @return string An formatted opening FORM tag.
     * @link TBD
     */
    public function create(array $options = [])
    {
        $defaultOptions = [
            'color' => 'yellow',
        ];

        $options = array_merge($options, $defaultOptions);

        $templater = $this->templater();

        return $templater->format('portletStart', [
            'color' => $options['color']
        ]);
    }

    /**
     * Closes a Portlet DIV, cleans up values set by PortletHelper::create(), and writes hidden
     * input fields where appropriate.
     *
     * @return string A closing DIV tag.
     * @link TBD
     */
    public function end()
    {
        $out = '';

        $templater = $this->templater();
        $out .= $templater->format('portletEnd', []);

        $templater->pop();
        return $out;
    }

    /**
     * Restores the default values built into FormHelper.
     *
     * This method will not reset any templates set in custom widgets.
     *
     * @return void
     */
    public function resetTemplates()
    {
        $this->templates($this->_defaultConfig['templates']);
    }
}

I get an error at the $templater->format saying that I have a non-object for $templater.

How does the FormHelper and the HtmlHelper use the templater without incurring the same error?


Solution

  • You are not actually using the trait, all you do is importing it into the current namespace. To actually make use of it, you have to specify it inside the class definition using the use statement.

    class PortletHelper extends Helper
    {
        use StringTemplateTrait;
    
        // ...
    }
    

    See also http://php.net/manual/en/language.oop5.traits.php