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

about a month ago

josef.sabl
Backer | 144
+
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.

about a month ago

Martk
Member | 412
+
+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)

about a month ago

CZechBoY
Member | 3129
+
+1
-

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

about a month ago

josef.sabl
Backer | 144
+
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)

about a month ago

josef.sabl
Backer | 144
+
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.

about a month ago

CZechBoY
Member | 3129
+
+1
-

You can make your own FormComponent which renders that template.