Write your own ViewHelper

Return values and add attributes...

  • 8 LTS
  • 9 LTS
  • 10-dev

Preamble

Today we´re writing our own ViewHelper. In this example, I add it to an existing extension. If you start from scratch, create an extension for example with the Extension Builder and continue with this tutorial.

Write an "Hello World" view helper

Let´s write our first view helper. View helpers are stored in  Classes/ViewHelpers. The file name must end with ViewHelper.php e.g. HelloWorldViewHelper.php

 

typo3conf/ext/my_ext/Classes/ViewHelpers/HelloWorldViewHelper.php

 

The next important thing is the namespace. The namespace  <VendorName>\<ExtensionName>\ViewHelpers. For example:

 

namespace Kronovanet\MyExt\ViewHelpers;

 

Up next we need to create class that extends the AbstractFluidViewHelper. The class name equals the filename without the php ending.

To get some output we need to create the method render(). Because this is a hello world view helper we wanna render a "hello world". Returning the string inside the method is the only thing we need.

 

<?php
namespace Kronovanet\MyExt\ViewHelpers;

use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;

class AuthorNameViewHelper extends AbstractViewHelper
{
    use CompileWithRenderStatic;

    public static function renderStatic(
        array $arguments,
        \Closure $renderChildrenClosure,
        RenderingContextInterface $renderingContext
    ): string {
        return 'hello world';
    }
}

 

Now our first view helper is ready to be used inside a fluid template...

Use the view helper inside a template

The ViewHelper must now be integrated into our fluid template. To do this, we must refer to the namespace in the fluid template and give it a shorthand.

In this example i´ll use p as shorthand to call view helpers from given namespace:

 

{namespace p=Kronovanet\MyExt\ViewHelpers}
<h1>ViewHelper-Test</h1>
<p><p:HelloWorld /></p>

 

That´s it. Clear the cache and open the page that uses the template and you´ll see at least a hello world.

Add attributes to a view helper

In our next example we wanna pass an argument to our view helper. I´ll pass the uid of the page creator. This uid is accessible via "data.cruser_id" inside a page fluid template.

We need to add the public method initializeArguments()  to register arguments. Inside of this method we use $this->registerArgument() to define them. The method $this->registerArgument() has the follwing parameters:

 

* @param string $name Name of the argument
* @param string $type Type of the argument
* @param string $description Description of the argument
* @param bool $required If TRUE, argument is required. Defaults to FALSE.
* @param mixed $defaultValue Default value of argument

 

For my example the initializeArguments() method will look like this:

 

public function initializeArguments()
{
   $this->registerArgument('authorUid', 'integer', 'uid of the author', true);
}

Pass the cruser to the view helper

To pass the cruser to the view helper we need to add the registered name as an HTML-Attribute. For example:

 

<p:authorname authoruid="{data.cruser_id}"></p:authorname>

 

 

AuthorNameViewHelper

And that´s how the view helpers looks like:

 

<?php
namespace Kronovanet\MyExt\ViewHelpers;

/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;

class AuthorNameViewHelper extends AbstractViewHelper
{
    use CompileWithRenderStatic;

    /**
     * Initialize arguments
     *
     * @return void
     */
    public function initializeArguments()
    {
        $this->registerArgument('authorUid', 'integer', 'uid of the author', true);
    }

    public static function renderStatic(
        array $arguments,
        \Closure $renderChildrenClosure,
        RenderingContextInterface $renderingContext
    ): string {
        return self::getAuthorRealName($arguments['authorUid']);
    }

    /**
     * Returns the realName of selected author by uid if set
     * otherwise returns the username
     *
     * @param int $authorUid
     * @return string
     */
    protected static function getAuthorRealName(int $authorUid): string
    {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users');
        $result = $connection->select(['username', 'realName'], 'be_users', ['uid' => ($authorUid)])->fetch();
        if ($result['realName']) {
            return $result['realName'];
        } else {
            return $result['username'];
        }
    }
}