# \[RFC\] laminas-form Twig integration

**URL:** <https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456>\
**Category:** Contributors\
**Tags:** twig, laminas-form, rfc\
**Created:** [March 20, 2020, 1:04pm UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456 "2020-03-20T13:04:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![cherifb](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/cherifb/32/69_2.png) [@cherifb](https://discourse.laminas.dev/u/cherifb)\
**Post date:** [March 20, 2020, 1:04pm UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/1 "2020-03-20T13:04:19Z")

</div>

### Goal

Integrate `laminas-form` with Twig template.

### How:

Extend Twig with the `laminas-form` functions and helpers.  
I’m not sure if some parts of `laminas-view` are required to make the integration works.

### Demo:

I did a small [demo](https://github.com/cherifGsoul/slim4-laminas-from-twig) but I couldn’t make it work, all it renders is form labels.  
It was inspired from @akrabat [demo](https://akrabat.com/using-zf2-forms-with-twig/) (outdated)

---

<div class="post-metadata">

**Author:** ![cherifb](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/cherifb/32/69_2.png) [@cherifb](https://discourse.laminas.dev/u/cherifb)\
**Post date:** [March 26, 2020, 11:14am UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/2 "2020-03-26T11:14:32Z")

</div>

Hi everybody, I made it work, I hope it is the right way to do it, I updated the [repository](https://github.com/cherifGsoul/slim4-laminas-from-twig):

```php

// ... get twig environment

$helper = new FormElement();
$renderer = new PhpRenderer();

$helpers = $renderer->getHelperPluginManager();
$config = new HelperConfig();
$serviceManager = $config->configureServiceManager($helpers);

$helper->setView($renderer);

$twigEnvironment->registerUndefinedFunctionCallback(function($name) use($serviceManager){
	
	$helper = $serviceManager->get($name);
	$callable = [$helper, '__invoke'];
	$options = ['is_safe' => ['html']];
	$fn = new TwigFunction($name, $callable, $options);
	
	return $fn;

});

```

---

<div class="post-metadata">

**Author:** ![cherifb](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/cherifb/32/69_2.png) [@cherifb](https://discourse.laminas.dev/u/cherifb)\
**Post date:** [March 28, 2020, 2:58pm UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/3 "2020-03-28T14:58:13Z")

</div>

An example of this integration as a twig extensions could be like the following:

```php
class LaminasFromTwigExtension extends AbstractExtension
{
	private $formElement;
	private $renderer;
	private $config;

	/**	
	 * @inherit
	 */
	public function __construct(FormElement $formElement, PhpRenderer $renderer, HelperConfig $config)
	{
		$this->formElement = $formElement;
		$this->renderer = $renderer;
		$this->config = $config;
	}

	public function getFunctions()
    {
		$fns = [];
		$pluginManager = $this->pluginManager();
		$serviceManager = $this->serviceManager($pluginManager);
		$aliases = $this->configure($serviceManager);
		$options = ['is_safe' => ['html']];
		foreach ($aliases as $name => $definition) {
			if ($serviceManager->has($name)) {
				$plugin = $serviceManager->get($name);
				$callable = [$plugin, '__invoke'];
				$fns[] = new TwigFunction($name, $callable, $options);
			}
		}
		return $fns;
	}

	private function pluginManager(): HelperPluginManager
	{
		return $this->renderer->getHelperPluginManager();
	}

	private function serviceManager(HelperPluginManager $pluginManager): ServiceManager
	{
		$this->renderer->setHelperPluginManager($this->config->configureServiceManager($pluginManager));
		return $this->config->configureServiceManager($pluginManager);
	}

	private function configure(ServiceManager $serviceManager): array
	{
		$this->renderer->setHelperPluginManager($serviceManager);
		$this->formElement->setView($this->renderer);
		$config = $this->config->toArray();
		return $config['aliases'];
	}
}

```

---

<div class="post-metadata">

**Author:** ![Saeven](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/saeven/32/100_2.png) [@Saeven](https://discourse.laminas.dev/u/Saeven)\
**Post date:** [July 17, 2020, 7:07pm UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/4 "2020-07-17T19:07:26Z")

</div>

Is this still required? It’s more work than Twig+Form with ZF3.

---

<div class="post-metadata">

**Author:** ![cherifb](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/cherifb/32/69_2.png) [@cherifb](https://discourse.laminas.dev/u/cherifb)\
**Post date:** [August 31, 2020, 11:53am UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/5 "2020-08-31T11:53:48Z")

</div>

> [@Saeven](#):
>
> Is this still required?

Do you mean there’s another easy way to do the integration?

---

<div class="post-metadata">

**Author:** ![cherifb](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/cherifb/32/69_2.png) [@cherifb](https://discourse.laminas.dev/u/cherifb)\
**Post date:** [October 7, 2020, 9:47am UTC](https://discourse.laminas.dev/t/rfc-laminas-form-twig-integration/1456/6 "2020-10-07T09:47:23Z")

</div>

Using `laminas-form` with plates is pretty much the same:

```php
<?php

declare(strict_types=1);

namespace Common\Plates;

use Laminas\Form\View\Helper\FormElement;
use Laminas\Form\View\HelperConfig;
use Laminas\ServiceManager\ServiceManager;
use Laminas\View\HelperPluginManager;
use Laminas\View\Renderer\PhpRenderer;
use League\Plates\Engine;
use League\Plates\Extension\ExtensionInterface;

class LaminasFormExtension implements ExtensionInterface
{
	private $formElement;
	private $renderer;
	private $config;

	public function __construct(FormElement $formElement, PhpRenderer $renderer, HelperConfig $config)
	{
		$this->formElement = $formElement;
		$this->renderer = $renderer;
		$this->config = $config;
	}

	/**
	 * @return void
	 */
	public function register(Engine $engine)
	{
		$pluginManager = $this->pluginManager();
		$serviceManager = $this->serviceManager($pluginManager);
		$aliases = $this->configure($serviceManager);
		foreach ($aliases as $name => $definition) {
			if (!strpos($name, '/') && !strpos($name, '\\')) {
				if ($serviceManager->has($name)) {
					$plugin = $serviceManager->get($name);
					$callable = [$plugin, '__invoke'];
					$engine->registerFunction($name, $callable);
				}
			}
		}
	}

	/**
	 * 
	 */
	private function pluginManager(): HelperPluginManager
	{
		return $this->renderer->getHelperPluginManager();
	}

	private function serviceManager(HelperPluginManager $pluginManager): ServiceManager
	{
		$this->renderer->setHelperPluginManager($this->config->configureServiceManager($pluginManager));
		return $this->config->configureServiceManager($pluginManager);
	}

	private function configure(ServiceManager $serviceManager): array
	{
		$this->renderer->setHelperPluginManager($serviceManager);
		$this->formElement->setView($this->renderer);
		$config = $this->config->toArray();
		return $config['aliases'];
	}
}

```
