pug-php / pug

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

Fatal error when rendering objects in UPPER CASE #179

Closed glodov closed 6 years ago

glodov commented 6 years ago

Hello,

Here is where I tested http://pug-demo.herokuapp.com/

The result is:

Use of undefined constant t - assumed 't' (this will throw an Error in a future version of PHP)

It throws an error after 2.7.2. In 2.7.2 it works on our server, but it does not work in http://pug-demo.herokuapp.com/

Pug code:

span#hello-bug-no-error
  | #{t.account.login}
span#hello-bug-fatal-error
  | #{t.ACCOUNT.LOGIN}

Data:

[
  't' => (object) [
    'account' => (object) [
      'login' => 'My login'
    ],
    'ACCCOUNT' => (object) [
      'LOGIN'  => 'MY LOGIN'
    ]
  ]
]

Thanks!

kylekatarnls commented 6 years ago

Hi, there is no proper way to port constant PHP system to the js emulator. So we choose to follow a wide-used convention: UPPER_CASE are constants.

That's why full upper case object keys, variables, functions etc. have to be wrapped with quotes, in you case, it gives you the following:

span#hello-bug-no-error
  | #{t.account.login}
span#hello-bug-fatal-error
  | #{t['ACCOUNT']['LOGIN']}
glodov commented 6 years ago

Can I change this? Is there a way to do this with some option:

$pug = new Pug(
  [
    'constants' => false
  ]
);
kylekatarnls commented 6 years ago

Nop sorry, it's not a trivial change since null, undefined, Infinity, NaN, true, false, Math.* are also constants handled the same way.

I will think of it, it needs some conditional pattern here in js-phpize: https://github.com/pug-php/js-phpize/blob/0e13b055ea31d9655f98287c5131af1037dd8a6a/src/JsPhpize/JsPhpizeOptions.php#L60

glodov commented 6 years ago

so it seems like I can use it with options 'patterns' and just remove constants in regular expression?

kylekatarnls commented 6 years ago

Indeed! I tested this and it works as you want:

<?php

use JsPhpize\Lexer\Pattern;
use Pug\Pug;

include 'vendor/autoload.php';

$pug = new Pug([
    'module_options' => [
        'jsphpize' => [
            'patterns' => [
                new Pattern(10, 'newline', '\n'),
                new Pattern(20, 'comment', '\/\/.*?\n|\/\*[\s\S]*?\*\/'),
                new Pattern(30, 'string', '"(?:\\\\.|[^"\\\\])*"|\'(?:\\\\.|[^\'\\\\])*\''),
                new Pattern(40, 'number', '0[bB][01]+|0[oO][0-7]+|0[xX][0-9a-fA-F]+|(\d+(\.\d*)?|\.\d+)([eE]-?\d+)?'),
                new Pattern(50, 'lambda', '=>'),
                new Pattern(60, 'operator', array('delete', 'typeof', 'void'), true),
                new Pattern(65, 'unexpected', array('::')),
                new Pattern(70, 'operator', array('>>>=', '<<=', '>>=', '**=')),
                new Pattern(80, 'operator', array('++', '--', '&&', '||', '**', '>>>', '<<', '>>')),
                new Pattern(90, 'operator', array('===', '!==', '>=', '<=', '<>', '!=', '==', '>', '<')),
                new Pattern(95, 'regexp', '\/(?:\\\\\S|[^\s\/\\\\])*\/[gimuy]*'),
                new Pattern(100, 'operator', '[\\|\\^&%\\/\\*\\+\\-]='),
                new Pattern(110, 'operator', '[\\[\\]\\{\\}\\(\\)\\:\\.\\/\\*~\\!\\^\\|&%\\?,;\\+\\-]'),
                new Pattern(120, 'keyword', array('as', 'async', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'do', 'else', 'enum', 'export', 'extends', 'finally', 'for', 'from', 'function', 'get', 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'of', 'package', 'private', 'protected', 'public', 'return', 'set', 'static', 'super', 'switch', 'throw', 'try', 'var', 'while', 'with', 'yield', 'yield*'), true),
                new Pattern(130, 'constant', 'null|undefined|Infinity|NaN|true|false|Math\.[A-Z][A-Z0-9_]*', true),
                new Pattern(135, 'variable', '[a-zA-Z\\\\\\x7f-\\xff\\$_][a-zA-Z0-9\\\\_\\x7f-\\xff\\$]*', '$'),
                new Pattern(140, 'operator', '[\\s\\S]'),
            ],
        ],
    ],
]);

$pug->display("span#hello-bug-no-error
  | #{t.account.login}
span#hello-bug-fatal-error
  | #{t.ACCOUNT.LOGIN}", [
  't' => (object) [
    'account' => (object) [
      'login' => 'My login'
    ],
    'ACCOUNT' => (object) [
      'LOGIN'  => 'MY LOGIN'
    ]
  ]
]);

Output:

<span id="hello-bug-no-error">My login
</span><span id="hello-bug-fatal-error">MY LOGIN
</span>
glodov commented 6 years ago

awesome! thanks

kylekatarnls commented 6 years ago

Hi, last js-phpize version allow you to disable constants without redefining all patterns (it's the recommended way):

$pug = new Pug([
    'module_options' => [
        'jsphpize' => [
            'disableConstants' => true,
        ],
    ],
]);