1

I have this following code that basically renders partials. However I was trying to find a way to prevent polluting $templatePath variable into the template (the variable is currently accessible from template which is not what I want). I only want $template and $viewHelper variables to be accessible in the template scope. Do you have any idea?

public function renderComponent(string $templatePath, ViewComponentEntityInterface $component): string
{
        if (! file_exists($templatePath)) {
            throw new RuntimeException('Incorrect component template path: ' . $templatePath);
        }

        $viewHelper = $this->viewHelperFactory->create();

        ob_start();

        try {
            (static function (ViewComponentEntityInterface $template,ViewHelper $viewHelper) use ($templatePath) {
                include $templatePath;
            })($component, $viewHelper);

            return ob_get_clean();
        } catch (Throwable $e) {
            ob_end_clean();

            throw $e;
        }
}

I tried to find something like array_shift but for single variable that would just unset the value and return it at the same time.

8
  • $tempatePath is not a variable, it's a parameter to the function. It won't be visible outside. Right? Commented Jul 6, 2024 at 19:12
  • @TimRoberts Yes it's parameter in context of the method. This method is responsible for rendering contents of $templatePath file. I can currently access the $templatePath variable from within any template I render using this method because of the use ($templatePath) which is necessary to include the template. So if I do <?php dd($templatePath); ?> in template, it dumps the value of $templatePath variable. Commented Jul 6, 2024 at 19:18
  • I don't quite see the point of the anonymous function inside the try { .... } catch(....) { .... } block. Is it your attempt to isolate the code inside the $templatePath? I would just use include $templatePath; since the method itself already isolates the code. Simple is often better, and certainly easier to read. Commented Jul 6, 2024 at 19:23
  • @KIKOSoftware That is why static functions exist. Simple include is not enough because A) calling renderComponent or any other method from template would become possible B) There are currently only variables that I want to be accessible in template except $templatePath but to encapsulate it like this is safer because if someone decides to refactor and add more variables, they become accessible in template without explicitly passing them as function argument or the use thing. Commented Jul 6, 2024 at 19:32
  • Well, yes, I guess the object, of which renderComponent() is a part, would be reachable within the template code when you just include the template. Given the anonymous function, what if you make $templatePath an argument instead of use it? Then a change to it won't affect the value of $templatePath outside the anonymous function. But I also notice that you don't use $templatePath after you included the template, so any change won't have any effect (yet). Commented Jul 6, 2024 at 19:42

1 Answer 1

0

Disclaimer: this is just for research purpose. IMHO introducing unnecessary eval is more troublesome than allowing reading $templatePath variable in template.

The idea in this solution is to create anonymous function where the template path will be constant instead of variable.

$code = <<<CODE
\$f = static function (
    ViewComponentEntityInterface \$template,
    ViewHelper \$viewHelper
) {
   include $templatePath; 
}
CODE;
eval($code);
$f($component, $viewHelper);
Sign up to request clarification or add additional context in comments.

1 Comment

Interesting solution. It did not even occur to me to use eval and I agree using it is probably not worth it here and definitely not the best practice. Anyway objective accomplished, marking as answer, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.