phug-php / phug

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

Output block as plain text in mixin #79

Closed lensco closed 1 year ago

lensco commented 3 years ago

Hi, when outputting plain text, you can use the dot syntax:

code.
    p test

This outputs <code>p test</code> – great. But in a mixin, this doesn't work:

mixin code()
    code.
        block

+code
    p test

This outputs <code>block</code> which makes sense, but not what we want. You can instead use the dot when calling the mixin:

+code.
    p test

This works, but I actually want to use the block both as plain text and parse it as HTML. Like so:

mixin code()
    .demo
        block
    pre: code.
        block

This breaks again. So is there any other way to output a block in a mixin as plain text, without parsing it? (Also, the Phug website is down?)

kylekatarnls commented 1 year ago

Hello,

This behavior is consistent with Pug-js. As a port-project, it's the reference we tends mimic.

Also it's incompatible with the caching mechanism we have. When a template is compiled, p test already becomes <p>test</p> if it's a markup or stay p test if it's a text, but mixin becomes a PHP function. Compiled templates are saved in cache in production which make them fast to load. Then only on runtime, this PHP function is executed. When reading a cached file, the source file is not used at all so there is no p test anymore nowhere in memory if it was compiled into <p>test</p>.

So you would need to repeat the code, once with . and once without. You can use the slot mechanism of phug/component for that.

Alternatively if you have long code you don't want to duplicate, I would suggest you put it in a file:

code.pug

p test

So then you only need to refer it twice with the filename, once using include which give you <p>test</p> and once passed as parameter so you can use file_get_contents() to load the raw file content, then wrap it in htmlspecialchars() so if it contain < > they are not rendered as HTML:

mixin code($file)
    .demo
        block
    pre: code
        =htmlspecialchars(file_get_contents($file))
+code("code.pug")
    include code.pug