phug-php / phug

Phug - The Pug Template Engine for PHP
https://phug.selfbuild.fr
MIT License
63 stars 3 forks source link

Accessing helper functions in a namespace #16

Closed char101 closed 6 years ago

char101 commented 6 years ago

Hello,

Is it possible to access helper functions in a namespace (like a search path for functions), without prefixing it with the namespace. I am thinking to put the helper functions for pug in a namespace to prevent clobbering the global namespace. I also prefer not to pass closure since it might overlap other variables.

For example

namespace pug\helpers;

function linkto($controller, $method)
{
    return '...';
}
= linkto('index', 'hello')
kylekatarnls commented 6 years ago

Right now I have no solution but I will think of it.

char101 commented 6 years ago

Thanks,

so far I have tried injecting a namespace into the compiled file using a custom Adapter and it works at least on simple template.

<?php

use Phug\Renderer\Adapter\FileAdapter;

class View_Renderer_Pug_Adapter extends FileAdapter
{
    protected function cacheFile($destination, $output, $importsMap = [])
    {
        return parent::cacheFile($destination, preg_replace('/^<\?php\s*/', '<?php namespace pug; ', $output, 1), $importsMap);
    }
}
kylekatarnls commented 6 years ago

Hi,

You have some entry points for that: https://github.com/phug-php/formatter/blob/master/src/Phug/Formatter/AbstractFormat.php#L50

For example, to intercept <?php and <?=, you can use those options:

Phug::setOption('patterns', [
    'php_handle_code'  => '<?php namespace pug; %s ?>',
    'php_display_code' => '<?php namespace pug; echo %s ?>',
]);
echo Phug::compile("p=\$foo\n- foo()");

It will output:

<p><?php namespace pug; echo htmlspecialchars((is_bool($_pug_temp = (isset($foo) ? $foo : null)) ? var_export($_pug_temp, true) : $_pug_temp)) ?></p>
<?php namespace pug; foo() ?>

[EDIT] I see the replace happens only once (seems logical for a namespace statement). Maybe it's more simple to juste add it:


Phug::setOption('on_output', function (OutputEvent $event) {
  $event->setOutput(
    '<?php namespace pug; ?>'.
    $event->getOutput()
  );
});
kylekatarnls commented 6 years ago

We will not implement specific stuff for namespacing but we will mention this as a OutputEvent example use case.

windware-ono commented 4 years ago

Has this changed at some point?

I'm using phug/phug 1.4.0 and pug-php/pug 3.3.1 but the following doesn't seem to apply the namespace.

\Phug\Phug::setOption('on_output', function (\Phug\Compiler\Event\OutputEvent $event) {
  $event->setOutput('<?php namespace myNameSpace; ?>' . $event->getOutput());
});

$pug = new \Pug\Pug([
  'strict' => true,
  'pretty' => true,
  'cache'  => '/tmp/',
]);

$content = $pug->renderFile($file, []);
kylekatarnls commented 4 years ago

Using pug-php, the setOption becomes:

\Pug\Pug::setOption('on_output', function (\Phug\Compiler\Event\OutputEvent $event) {
  $event->setOutput('<?php namespace myNameSpace; ?>' . $event->getOutput());
});

(Pug\Pug extends Phug\Phug)

windware-ono commented 4 years ago

I've used the above code but it threw an error saying, Using $this when not in object context as the method wasn't static in Pug class.

I've run it as $pug->setOption after $pug = new \Pug\Pug but it didn't apply the namespace.

kylekatarnls commented 4 years ago

I opened a new issue for that: https://github.com/pug-php/pug/issues/230

kylekatarnls commented 4 years ago

Hi @ws-h-ono in fact the problem is just that you need to clear your cache and you can use:

<?php

include __DIR__.'/vendor/autoload.php';
include 'function.php';

\Phug\Phug::setOption('on_output', function (\Phug\Compiler\Event\OutputEvent $event) {
    $event->setOutput('<?php namespace myNameSpace; ?>' . $event->getOutput());
});

$pug = new \Pug\Pug([
    'strict' => true,
    'pretty' => true,
    'cache'  => '/tmp/',
]);

$pug->display('p=fooBar()');

Assuming function.php contains:

<?php

namespace myNameSpace;

function fooBar()
{
    return 'Hello';
}

This output: <p>Hello</p>

Still I will introduce an option to specify a functions namespace so it can make this case easier.

kylekatarnls commented 4 years ago

See the new solution here: https://github.com/pug-php/pug/issues/230#issuecomment-564635560