Is there a way to set something like a layout for a component?

josef.sabl
Member | 153
+
0
-

Let's say I have a base Component class I extend to create concrete components.

Now I need to include a block I typically have imported in @layout. But as components can't see blocks imported in the presenter template I need to import these blocks in a component.

I obviously don't want to import all the blocks I use (e.g. form template) in each component (and mess with ../.. to find the correct file).

I tried to use this trick to include @layout for the component but it doesn't seem to work.

What can be done about this? Thank you.

Martk
Member | 660
+
+1
-

Original UIMacros

class LatteMacros extends MacroSet {

	public static function install(Compiler $compiler): void {
		...
	}

	public function finalize() {
		return [Helpers::class . '::init($this, $this->parentName, $this->blocks);'];
	}

}

Original UIRuntime

class Helpers {

	public static function init(\Latte\Runtime\Template $template, &$parentName, array $blocks): void {
		$providers = $template->global;
		$blocks = array_filter(array_keys($blocks), function ($s) { return $s[0] !== '_'; });
		if (
			$parentName === null
			&& $blocks
			&& !$template->getReferringTemplate()
			&& ($providers->uiControl ?? null) instanceof IControlLayout
		) {
			$parentName = $providers->uiControl->findLayoutTemplateFile();
		}
	}

}
interface IControlLayout {
	public function findLayoutTemplateFile(): ?string;
}

and delete cache

Last edited by Martk (2018-09-19 16:51)

CZechBoY
Member | 3608
+
+1
-

Why do you need it?
You can separate render logic into another component/latte template and include it in your components.

josef.sabl
Member | 153
+
0
-

@Martk

Wow, it was I bit hard to make it work. But I finally made it :-) The biggest problem was that I didn't know what to put in the install method. I made it to work by adding this.

	public static function install(Latte\Compiler $compiler)
	{
		$compiler->addMacro(NULL, new static($compiler));
	}

Thank you very much.

And also thanks for the pro tip to clear the cache. It was important to do it more often then I expected :)

Last edited by josef.sabl (2018-09-19 18:13)

josef.sabl
Member | 153
+
0
-

CZechBoY wrote:

Why do you need it?
You can separate render logic into another component/latte template and include it in your components.

Exactly, I have render logic separated into another latte template. But I need to somehow import the latte template as components don't see the imports from presenter layout. And I don't want to repeat the import in all components.

It is for rendering forms. I have it exactly as is used in Nette\Sandbox. But now try that in a component. Like you have a component and you need to render a form inside.

CZechBoY
Member | 3608
+
+1
-

You can make your own FormComponent which renders that template.