pug-php / pug

Pug template engine for PHP
https://www.phug-lang.com
MIT License
387 stars 42 forks source link

Helper function not working with pugjs engine #178

Closed MarcelRobitaille closed 6 years ago

MarcelRobitaille commented 6 years ago

Hello,

I am trying to set up a helper function like this:

$CONFIG = require(__DIR__ . '/../config.php');

$manifest = json_decode(file_get_contents(__DIR__ . '/../manifest.json'), true);

$pug = new \Pug\Pug([
  'extension' => 'pug',
  'pugjs' => true,
]);

$asset = function ($file) {
  if (isset($CONFIG['USE_RAW_ASSETS']) && $CONFIG['USE_RAW_ASSETS']) return $file;

  $filename = basename($file);
  $dirname = dirname($file);

  if (!array_key_exists($filename, $manifest)) return $file;

  return "$dirname/$manifest{$filename}";
};

$pug->share('asset', $asset);

When I try to use it like this:

script(src=asset('/something.js')

or

script(src=$asset('/something.js')

I get asset is not a function.

Is this because I am using pugjs => true? I doesn't say in the readme that pugjs => true will prevent helper functions. If so, is there an alternative?

I am using version 3.1.1.

Thanks.

kylekatarnls commented 6 years ago

Hi, yes it works with PHP engine. Basically, pugjs skip the whole PHP engine and thoses options to give you direct access to the native JS engine to make Pug class act as a simple wrapper.

So we have to polyfill each option to make it available with pugjs, we did not yet for shared variables.

Note: our main goal is to enhance and maintain the PHP engine because we consider it give more added value (provide access to all PHP functions and consistency with the running PHP back-end). pugjs is a secondary fallback option for specific case such as running the same templates from both PHP and JS scripts, prepare a migration to Node or a need to support a specific JS API. But we should be able to add soon this feature.

kylekatarnls commented 6 years ago

Hi, shared variables are now available with pugjs on. But it won't help in your case since you fall in this case descrbied by the README: "pugjs mode will flat you local vars (it means complex object like DateTime, or classes with magic methods will be striginfied in JSON as simple objects)".

We cannot pass a PHP closure to the JS program, we pass only flat data as JSON, if it cannot be stringifiedn we cannot be able to pass it either as local or global variable. When you choose 'pugjs' => true, you choose delegate all the template job to JS so all the PHP work must be done first, then you pass flat data and template to JS, so your helpers must be created in your templates:

-
  function asset(file) {
    if (useRawAssets) {
      return file;
    }

    var lastSlash = file.lastIndexOf('/');
    var filename = file.substr(lastSlash + 1);
    var dirname = file.substr(0, lastSlash);

    if (!filename in manifest) {
      return file;
    }
    return dirname + '/' + manifest[filename];
  }

Here we suppose your shared needed variables:

$pug->share([
  'useRawAssets' => isset($CONFIG['USE_RAW_ASSETS']) && $CONFIG['USE_RAW_ASSETS'],
  'manifest' => $manifest,
]);

(You need to install pug-php 3.1.2 or newer.)

MarcelRobitaille commented 6 years ago

Thanks. This seems like a good solution to me.