Closed dzpt closed 7 years ago
The javascript expressions evaluation (with multiple operations: here concatenation and property getter) is not yet possible, the project js-phpize should fix that in the future but it is not yet ready to be used in concatened attributes.
For the moment, you have to use PHP syntax:
each i in ModuleAtMenu
li: a.indent(href='?act=module&module=' . $i['module_key'])=i.module_title
Or if i
is an object:
each i in ModuleAtMenu
li: a.indent(href='?act=module&module=' . $i->module_key)=i.module_title
An elegant solution could be to add a method getLink() to the i module and call it with the getter short-cut:
each i in ModuleAtMenu
li: a.indent(href=i.link)=i.module_title
Thanks for the reply, what's the different between using php syntax $i['module_key']
vs i[module_key]
, i.module_key
or #{i.module_key} ?
Like this example, i found out it works with '?act=module&module=#{i.module_key}'
ps: Sorry for asking but i can't find any syntax document here
Hi,
Indeed, '?act=module&module=#{i.module_key}'
is a good solution. The problem is we can support both PHP syntax and JS syntax.
To use the exact same syntax as Pug-js, you can directly call the node module to compile your templates, but the point is you first have to dump you data as JSON before you pass it to the view.
Pug-php allows you to keep your PHP data untouched, and call objet methods, example:
p=$bob->sayHello()
This mean no loss of recursive structures, and method can be called only on the fly since Pug-php compile templates into PHP code and not JS code. So for every syntaxes we need to do a translation from JS to PHP. i.module_key
is a JS syntaxe, and it must be translated first to PHP, your code will render:
'?act=module&module=<?php echo $i['module_key']; ?>'
This become tricky with concatenation, because with '?act=module&module=' + i.module_key
, the +
can be addition or concatenation in JS, but it's addition only in PHP, .
is getter in JS, concatenation in PHP. So we cannot handle easily both PHP and JS syntaxes in the pug template.
This is what I try to improve with js-phpize and the expressionLanguage option (modes JS, PHP or auto).
For the last possibility in your question (the interpolation), it's an option given by Pug-js, and we implemented it to match its API. As you can do "a$b"
or "a" . $b
in PHP, you can do "a#{b}"
or "a" . b
in Pug-php. This is equivalent.
I really appreciate your help. I understand now.
The last thing i care is about the performance, does it get faster or take less memory if i use php variable directly like $i['module_key']
instead of js / mark up string?
I'm thinking about using one consistent syntax (php or js) to optimize the code.
In production, you should use cache, and the best of all is to compile all your templates during the deployment with:
$pug->cacheDirectory('path/to/your/templates/directory');
See https://github.com/pug-php/pug#cache
If you follow this best pratice, it means users only load pure PHP compiled cached versions of the templates, and so, as they never trigger any Pug compilation, you don't care about compilation performance.
I know using cache, but i just want to use only one kind of synta for avoiding messing. Because javascript syntax doesn't work sometimes, like examples bellow.
it works with php syntax and every function
if in_array($g['group_id'],$item['module_group'])
but doesn't work like this
if in_array(g.group_id,item.module_group)
or this
if item.module_group.indexOf(g.group_id) >= 0
but also work for this (??!)
if in_array(g[group_id],item[module_group])
As i understand, it uses only variable calling by js syntax like object ~> array access.
I can't use any function of js, but on the example two, it didn't work while mixing php function in_array
vs js accessor g.group_id
, but why switch to write as g[group_id]
like the last one, it works? It made me confused
This one is really not a good option:
if in_array(g[group_id], item[module_group])
In this case, only var names are transformed like this:
if in_array($g[group_id], $item[module_group])
But with a strict E_NOTICE report in PHP you will get errors because group_id
are recognized as constants and PHP will translate into the equivalent string because the constant is not found.
For example, try this:
- define('group_id', 'module_group')
- define('module_group', 'group_id')
if in_array(g[module_group], item[group_id])
This will works! Because we create the missing constants, this is the mess.
For this one:
if item.module_group.indexOf(g.group_id) >= 0
It will never work, we can't have both the PHP functions (like in_array) and the JS prototypes (like .indexOf).
If you want pure JS syntax, use pug-cli. Pug-php is made to get "php everywhere". And if you want to disable all JS to PHP translation done for help to translate basic templates from one language to the other, you can set expressionLanguage to php:
$pug = new Pug(array(
'expressionLanguage' => 'php',
));
With this option, expressions are keeped as it, this mean you should prepend every variable with $
, get properties with ->
and array entries with []
.
But I know there are possible improvement in syntaxes detections and I work on it.
@Tom29 When you pass params to PHP functions you can't pass pug objects.
Like:
ul.list.no
each post in posts
li.post
.equalize.not
.wp1-3.caption
-> img(src=media("post/"+post.thumb), alt="")
.wp2-3.body.cF
.wrp.r
.info
.title.b.tu= post.title
.user= post.name
.date.i= post.date
article.mt20.mb20.i #{post.intro}
.ab.b0
-> a(href=base(post.slug)).cp0.bcF.more. More
You must to pass string value, and post.slug (example) is not a string.
If you need concat a string to PHP:
Instead: `$post->slug
and media("post/!{post.thumb})
or ^media("post/"+$post->thumb)
if an object, like @kylekatarnls said.
Neither concat with +
in PHP context.
div(style="background:url("+img('image.jpg')+");another:properties;")
Wrong:
div(style="background:url("+img(value+another_value)+");another:properties;")
div(style="background:url("+img($asset->image)+");another:properties;")
Correct using $ scope.
Other ways:
``` "&url="+item->value+"...
If you use .
as scope it's like it was javascript/Java objects:
value.charAt(0)
@kylekatarnls How's about this example :(
each item in groupList
option(value=item.group_id, selected=(item['group_id']==se_groupid))=item.title
-> Doesn't work
each item in groupList
option(value=item.group_id, selected=($item['group_id']==$se_groupid))=item.title
Works.
Here is groupList
array:
Array
(
[0] => Array
(
[group_id] => 1
[title] => Group A
)
[1] => Array
(
[group_id] => 2
[title] => Group B
)
[2] => Array
(
[group_id] => 3
[title] => Group C
)
[3] => Array
(
[group_id] => 4
[title] => Group D
)
)
se_groupid
= 4.
I thought this is really simple comparing operator and it might work. I print both item.group_id
and se_groupid
, it equals, but it seems in the comparing, javascript engine can't do the comparison
This is exactly the same explication, there is no javascript engine, so we do quick transformation of js-like expressions to turn it into PHP code. If you see a simple way ot make it work, feel free to open a pull request to propose your solution.
Else, you will have to wait for the js-phpize (pug sub-project to handle js expressions) improvements.
Hi, js-phpize refactorization done!
Please can you try to composer update
, set expressionLanguage to js and tell me if it fix your bug?
Thanks!
@kylekatarnls Hello there, i've done some few quick tests, and it have really weird errors.
$TPL->share('list',array(1,2,3,4));
$TPL->share('logged',array('id'=>1,'name'=>'name'));
$TPL->share('LANG',array('id'=>1,'name'=>'name'));
each i in list
if i==logged.id
h1 matched
else
h1 failed
~> it works
each i in list
if i==logged.id
h1 matched
else
h1 failed
div=LANG.name
( ! ) Fatal error: Uncaught exception 'JsPhpize\Parser\Exception' with message 'Unexpected . in on line 1 near from LANG.' in
If i change LANG
to lang
for avoiding case sensitive, it can run but the result is wrong, i
never equals to logged.id
(?!).
I think js phpize doesn't parse properly.
@kylekatarnls how was that? have you checked it?
Indeed, uppercase names are reserved for constants. And the js mode is not yet compatible in conditions such as if
, I must work on it.
So, this syntax you reported first is available with the expressionLanguage js mode:
li: a.indent(href='?act=module&module=' + i.module_key)=i.module_title
This is what is now fixed.
For a stable behaviour that handle conditions, attributes dans tag contents, you should use for the moment the expressionLanguage php mode and use PHP syntax in templates:
each $i in $list
if $i == $logged['id']
h1 matched
else
h1 failed
div=$LANG['name']
Thanks,
@kylekatarnls If i change LANG
to lang
div=lang.name
will not show anything.
and if i switch expressionLanguage to php , each $i in $list
doesn't work, it prints $i in $list
but each i in list
does.
So i think it should be fix for the consistency in syntax
Yes, I must admit that's an inconsistency, but I will not do big evolutions on pug-php until the next major version that will be a complete refactorization.
Hi, there is a new option now available to use the native pugjs engine (until the 3.0):
$pug = new Pug(array(
'pugjs' => true
));
echo $pug->render('
-
var list = ["Uno", "Dos", "Tres",
"Cuatro", "Cinco", "Seis"]
each item in list
li= item
');
This is a pure wrapper solution with no PHP support in templates (all run with node.js).
You can update to 3.0.0-alpha2
, it should be fixed. Please don't hesitate to test the new pug-php 3 and give us your feedback.
I want to show array member in foreach loop. It works fine except inline code combination like this:
But this one is ok