pug-php / pug

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

Call to a member function is() on boolean - continue js directive parsing bug #205

Closed webarchitect609 closed 5 years ago

webarchitect609 commented 5 years ago

Hello, pug-php team! Thank you for this librarry, but...

I encountered an issue with the following code:

mixin demo(options)

    - var list = ['foo','bar','baz']
    ul
        each item, i in list
            if i === 1
                 - continue
            li [#{ i }] = `#{ item }`
    block

+demo()

I expected to get:

<ul><li>[0] = `foo`</li><li>[2] = `baz`</li></ul>

But I actually get:

[Symfony\Component\Debug\Exception\FatalThrowableError] E_ERROR
Call to a member function is() on boolean (0)

Please, see pug-continue-bug-full-stack-trace.txt file for a full stack trace.

Additional information about environment

php 7.0.32

composer packages versions:

pug-php/pug                                 3.2.0
js-phpize/js-phpize-phug                    2.0.0
phug/ast                                    0.1.0
phug/compiler                               0.5.19
phug/dependency-injection                   1.3.2
phug/event                                  0.1.2
phug/formatter                              0.5.42
phug/js-transformer-filter                  1.1.0
phug/lexer                                  0.5.28
phug/parser                                 0.5.8
phug/phug                                   0.3.2
phug/reader                                 0.2.1
phug/renderer                               0.4.5
phug/util                                   0.4.15
symfony/var-dumper                          v3.4.17

Some information about background of this problem

I'm trying to use pug-php to render layout, which is developed according to Block Element Modifier methodology and powered by bemto.pug node package, which has few - continue statements in its implementation.

Thanks!

kylekatarnls commented 5 years ago

The quicker work-around is simply: - continue;

js-phpize (the converter we developer to convert JS code into PHP) assumes the JS code respect the strict mode and so expect continue is always followed by something.

We will inspect if we can allow continue as a valid expression ending. If it does not conflict with any other syntax, we will add it, else valid codes have the priority.

kylekatarnls commented 5 years ago

js-phpize 2.1.0 has been released with a list of keywords now allowed to end instructions, so you can run composer update (clear cache if js-phpize is not shown as updated to 2.1.0) and - continue should be transformed properly into continue;.

webarchitect609 commented 5 years ago

Thank you very much for fixing and fast reaction! The problem described in this issue is now fixed. I've checked it.

Unfortunately a new error emerges while including bemto.pug node-package without using it. I keen to give you detailed information but I can't!

Steps to reproduce:

1 Download (or install via npm) node-package bemto.pug of version 2.1.0 2 Use the folowing pug-code, saved with a test.pug filename.

mixin demo(options)

    - var list = ['foo','bar','baz']
    ul
        each item, i in list
            if i === 1
                 - continue
            li [#{ i }] = `#{ item }`
    block

+demo()

4 Install composer-package pug-php/pug of version 3.2.0 with its dependencies (including js-phpize/js-phpize 2.1.0 )

5 Run the following php-code


require_once $_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/vendor/autoload.php';

$pug = new \Pug\Pug(
    [
        'includes' => [
            //Just include bemto.pug node-package
            $_SERVER['DOCUMENT_ROOT'] . '/static/src/node_modules/bemto.pug/bemto.pug',
        ],
    ]
);

//Render test code, which actually doesn't use bemto.pug and DOES NOT lead to an error by itself.
$pug->displayFile('./test.pug');

I expected to get:

<ul><li>[0] = `foo`</li><li>[2] = `baz`</li></ul>

But I actually get:

syntax error, unexpected 'var' (T_VAR), expecting ';'

without any detailed information or stack-trace

Shall I open a new issue about it? I see this as a set of two problems: impossible to get proper back-trace about some kinds of rendering errors and the second one - still impossible to use bemto.pug.

kylekatarnls commented 5 years ago

Bemto use a lot of "advanced" JS code injected inside Pug templates, such as .hasOwnProperty, Date objects and so on. All those are nearly impossible to convert properly into PHP. In this cas, the syntax we could not translate is - for (var attribute in attributes) and bemto.pug omit a lot of semi-colon in its code. This make bemto.pug JS-only.

But the library is not so big. It could ported in PHP. It seems a wiser option than handling every possible JS syntax.

We assume generally than templates only handle final display logic and so have very light embedded codes (other treatments should be in the backend/controller).

kylekatarnls commented 5 years ago

You still have the ability to use the native JS package using 'pugjs' => true, option, but this will consequently disable all PHP features (use of class instances inside templates, hooks, extensions, formatting options).

kylekatarnls commented 5 years ago

I'm pretty sure it will not be enough to be fully compatible but I made some progress for non-conflicted keyword (instanceof and the particular case of instanceof Array and typeof). .hasOwnProperty, Date or RegExp class still remain big problem. But I hope we could at least fix all syntax error, that would mean including bemto.pug would no longer fail on compile time and it would only fail when running some bemto features with particular values (complex PHP objects that would not have JS equivalent as exepcted by bemto.pug).

webarchitect609 commented 5 years ago

Sorry for keeping silence for so long. I had to work on the very project I wanted to use pug-php. Thank you for explanation all the options! We'll try to make next project without bemto or any other complex nodejs librarry and use your pug-php/pug to render. I believe it's the most simple, sustainable and even cheap way... At least in my particular situation.

Regarding your last comment, am I understand it right that you still want to make bemto compatible with pug-php/pug , but as 'no warranty' with risks it can crash?

kylekatarnls commented 5 years ago

I did the maximum viable of JS-to-PHP conversions. There are deep differences such as: in JS an associative map (object) is always a reference, in PHP an associative map (array) is copied by default.

But I'm working on a port of bemto for PHP (rewrite the whole library using PHP code and logic), this seems feasible and I already have ~50% of the unit tests that pass. Should be released before the end of the year.

kylekatarnls commented 5 years ago

https://github.com/phug-php/bemto

kylekatarnls commented 5 years ago

The pug/bemto package is out. You can start to test it if you like. A fix in Pug-php will be needed to pass all unit tests (https://github.com/pug-php/pug/issues/213), but most features should work just fine right now, so I close this issue.