Add namespace to compiled latte files?

bernhard
Member | 47
+
0
-

TL;DR: Is there a way to add “namespace ProcessWire” to compiled latte php files?

Background:

I've created RockFronted, a module for the ProcessWire CMS that makes it easy to use Latte for frontend development.

In ProcessWire, we have the ProcessWire API, which consists of several API variables to access several functionalities, examples are $wire for the main ProcessWire object, or $modules to access modules, $files, $session, etc.

I've made all these API variables available to any latte file, which is great :)

The problem arises, when we try to use the “functions API”, which is accessible through functions in the ProcessWire namespace, like wire(), modules(), etc.

In latte, I have to write {ProcessWire\modules()->get(‘MyModule’)} instead of <? modules()->get(‘MyModule’) ?>

I don't really have a problem with that, but some users have: https://processwire.com/…ne-by-nette/?…

It's understandable, that if you are a frontend dev, you are not really familiar with the concept of namespaces or even more understandable that you don't know what latte does behind the scenes (compile latte to php).

I did experiment a little with adding a custom extension to expose all available API functions to latte files like this:

<?php

namespace ProcessWire;

use Latte\Extension;

final class CustomLatteExtension extends Extension
{
  /**
   * Define functions available in all Latte files
   * These can be anything ProcessWire related or not, any functions defined here will be available everywhere
   */
  public function getFunctions(): array
  {
    $functions = [];
    foreach (wire('all')->getArray() as $key => $value) {
      if (!is_object($value)) continue;
      $functions[$key] = fn() => $value;
    }
    return $functions;
  }
}

But this is not a reliable solution, because some functions might take arguments, some might not. The next problem is that not all available functions are listed in wire(‘all’), because anyone could develop a module and add a custom function foo() and this would be available via ProcessWire\foo() but it would not be listed in wire(‘all’)

I have looked into compiled latte php files and I see that they don't have a namespace. So I'm wondering if it is possible to add a namespace to these files? I'm a little afraid, that this would have unintended side effects though ^^

Maybe you have better ideas? Maybe we could add exception handlers that kicks in whenever a function is called that does not exist (like wire()->… ) and then tries to call the same function with a “ProcessWire” namespace?

Thx for your help and ideas!

PS: Could the subscribe checkbox be moved to the send button? It's so easy to miss! Or even better make it checked by default!

David Grudl
Nette Core | 8206
+
0
-

In Latte 3, you can do absolutely anything, it's perfectly configurable. But the easiest way would be to use getFunctions(). I don't know what wire('all')->getArray() is for, but in 2024, I would handle it this way:

  1. Open https://chatgpt.com
  2. Type: “Create a class ProcessWire\CustomLatteExtension that extends from Latte\Extension and has a method getFunctions(). This method will create a list of all defined PHP functions that are located in the ProcessWire namespace. It will return an array where the key will be the function name (without the namespace) and the value will be a callback to that function.”

:-)

bernhard
Member | 47
+
0
-

Thank you @DavidGrudl I didn't think of using get_defined_functions() for that even though I used get_defined_vars for something similar ^^

Unfortunately I didn't get an email from the forum even though I'm subscribed.

Thx for your help and your great software!