posthtml / posthtml-expressions

Use variables, JS-like expressions, and even markup-powered logic in your HTML.
Other
123 stars 20 forks source link

passing HTML through localsAttr isn't working #126

Closed kudg0 closed 2 years ago

kudg0 commented 2 years ago

Hi! First of all, i wanna say thank you for your plugin and your work! Love this thing)

I see the issue with passing HTML through localsAttr.

input:

<include src="src/partials/component/example.html">
  {
    "text": "Lorem ipsum dolor sit amet, <br><br> consectetuer adipiscing elit."
  }
</include>

src/partials/component/example.html

<span>
  {{{ text }}}
</span>

output:

src/partials/component/example.html

<span>
Lorem ipsum dolor sit amet, [object Object][object Object] consectetuer adipiscing elit.
</span>

Is it possible to do this by using localsAttr?

And yeah, some of my gulp config:

posthtml([
  include({ encoding: 'utf8' }),
  expressions()
])
thewebartisan7 commented 2 years ago

You can use extends plugin by passing HTML via block.

kudg0 commented 2 years ago

@thewebartisan7 thank's for your advise! Now i use extends plugin for this

But i have misunderstanding with one thing, maybe you know that to do with this) I have template file:

template.html


<div class="titleXtextContainer">
<div class="titleXtextContainer__title">
<slot name="title"></slot>
</div>


And when i include it more than 1 time in one HTML file, he doesn't replace `slot` tags correct. 
Here is that i mean:

**input:**
lorem loremloremlorem lorem loremloremlorem

**output:**
lorem
loremloremlorem
lorem
loremloremlorem

Somehow `slots` tags looks correct only in last including...

And my `gulp config`:

posthtml([ include({ encoding: 'utf8' }), expressions(), extend({ slotTagName: 'slot', fillTagName: 'fill', encoding: 'utf8' }), richtypo({ attribute: 'data-typo', rules: [quotes, sectionSigns, shortWords], }), removeAttributes([ // The only non-array argument is also possible 'data-typo', ]), ]),

thewebartisan7 commented 2 years ago

I see only now this issue. I use extends like you, and I didn't notice it since the block tag it's hidden by html.

I start using extends for include components with slots since the "include" and "modules" plugin doesn't allow that, but as I understand "extends" was intended to be used to extends just single layout, and not many components on pages. So for nested extends you have to set option strict=false to make it works, see https://github.com/posthtml/posthtml-extend/issues/44#issuecomment-1022127879

I suppose we have here the same problem.

Seem that extends require each slot / block to have unique name, then it works fine. It's like he fill only the last block by ignoring the others (or most probably overriding others, see https://github.com/posthtml/posthtml-extend/blob/77580921031249073ae2625131cf3cb163cb1eb8/src/index.js#L149). The odds is that works fine, but it just doesn't remove the blocks.

Considering this, I have found a workaround just now, but it's not ideal.

Basically you pass the slot / block name as variables via locals.

Example:


// template.html

<div class="titleXtextContainer">
    <div class="titleXtextContainer__title">
        <block name="{{ mytitleslot }}"></block>
    </div>

    <div class="titleXtextContainer__text">
        <block name="{{ mytextslot }}"></block>
    </div>
</div>

// index.html
<extends src="template.html" locals='{ "mytitleslot": "myfirstitle", "mytextslot": "myfirsttext" }'>
                <block name="myfirstitle">
                    <span>
                      lorem
                    </span>
                </block>
                <block name="myfirsttext">
                    <span>
                      loremloremlorem
                    </span>
                </block>
            </extends>

            <extends src="template.html" locals='{ "mytitleslot": "mysecondtitle", "mytextslot": "mysecondtext" }'>
                <block name="mysecondtitle">
                    <span>
                      lorem2
                    </span>
                </block>
                <block name="mysecondtext">
                    <span>
                      loremloremlorem2
                    </span>
                </block>
            </extends>
kudg0 commented 2 years ago

@thewebartisan7 thank you!

I go deep inside of this plugin, and see that it's work by operating trees with extends/layout content. But i think here we have opportunities to easy add support of this behavior.

Here is method from plugin code:

node_modules/posthtml-extend/lib/index.js


function getBlockNodes(tag, content = []) {
const blockNodes = {};

return ( _api.match.call(content, { tag }, (node) => { if (!node.attrs || !node.attrs.name) throw getError(errors.BLOCK_NO_NAME); return (blockNodes[node.attrs.name] = node), node; }), blockNodes ); }


if we just add unique uid to returning nodes attrs, it's can be more useful for users

Here is that i mean:

function getBlockNodes(tag, content = []) { const blockNodes = {};

return ( _api.match.call(content, { tag }, (node) => { if (!node.attrs || !node.attrs.name) throw getError(errors.BLOCK_NO_NAME); return (blockNodes[node.attrs.name + Object.keys(blockNodes).length] = node), node; }), blockNodes ); }


Because our `extendsBlockNodes` and `layoutBlockNodes` always have the same number of uses, seems like is can be worthy resolves.

But this is fast look, and I don't saw all of the pitfalls.

Maybe here is time for improvements)
I create issue in git repo of extend plugin!

Thank you so much @thewebartisan7 :)
thewebartisan7 commented 2 years ago

I just see that you can skip escape of HTML, see https://github.com/posthtml/posthtml-expressions#unescaped-locals

{{{ unescaped }}}

kudg0 commented 2 years ago

I just see that you can skip escape of HTML, see https://github.com/posthtml/posthtml-expressions#unescaped-locals

{{{ unescaped }}}

Yeeah, but it isn't working(

I try to use it: https://github.com/posthtml/posthtml-expressions/issues/126#issue-1125181767

thewebartisan7 commented 2 years ago

Strange.. I tried this morning and works fine.

There is even a test case here https://github.com/posthtml/posthtml-expressions/blob/master/test/fixtures/unescaped.html