Skip to content

Process slots before processing subtree#200

Merged
cossssmin merged 2 commits into
posthtml:mainfrom
StratusFearMe21:reorder_processing
Sep 25, 2025
Merged

Process slots before processing subtree#200
cossssmin merged 2 commits into
posthtml:mainfrom
StratusFearMe21:reorder_processing

Conversation

@StratusFearMe21
Copy link
Copy Markdown
Contributor

@StratusFearMe21 StratusFearMe21 commented Jul 14, 2025

I attempted to use a component inside of another component like so:

<script props>
  module.exports = {
    onclick: props.onclick || '',
    titlestyle: props.titlestyle || '',
    headerstyle: props.headerstyle || '',
    person: props.person,
  }
</script>
<div class="interest">
  <a href="/src/who_we_are.html#{{person}}" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#{{person}}"
    hx-swap="innerHtml show:#{{person}}:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>
  <x-project onclick="{{onclick}}" titlestyle="{{titlestyle}}" headerstyle="{{headerstyle}}">
    <if condition="$slots.img?.filled">
      <fill:img>
        <slot:img></slot:img>
      </fill:img>
    </if>
    <if condition="$slots.title?.filled">
      <fill:title>
        <slot:title></slot:title>
      </fill:title>
    </if>
    <if condition="$slots.links?.filled">
      <fill:links>
        <slot:links></slot:links>
      </fill:links>
    </if>
    <if condition="$slots.subtitle?.filled">
      <fill:subtitle>
        <slot:subtitle></slot:subtitle>
      </fill:subtitle>
    </if>
  </x-project>
</div>

When I did this, it didn't fill in any of the slots of the subcomponent.

This is the pipeline that the HTML goes through now:

Original:

<script props>
  module.exports = {
    onclick: props.onclick || '',
    titlestyle: props.titlestyle || '',
    headerstyle: props.headerstyle || '',
    person: props.person,
  }
</script>
<div class="interest">
  <a href="/src/who_we_are.html#{{person}}" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#{{person}}"
    hx-swap="innerHtml show:#{{person}}:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>
  <x-project onclick="{{onclick}}" titlestyle="{{titlestyle}}" headerstyle="{{headerstyle}}">
    <if condition="$slots.img?.filled">
      <fill:img>
        <slot:img></slot:img>
      </fill:img>
    </if>
    <if condition="$slots.title?.filled">
      <fill:title>
        <slot:title></slot:title>
      </fill:title>
    </if>
    <if condition="$slots.links?.filled">
      <fill:links>
        <slot:links></slot:links>
      </fill:links>
    </if>
    <if condition="$slots.subtitle?.filled">
      <fill:subtitle>
        <slot:subtitle></slot:subtitle>
      </fill:subtitle>
    </if>
  </x-project>
</div>

expressions():

<div class="interest">
  <a href="/src/who_we_are.html#isaac" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#isaac" hx-swap="innerHtml show:#isaac:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>
  <x-project onclick="" titlestyle="" headerstyle="">

      <fill:img>
        <slot:img></slot:img>
      </fill:img>

      <fill:title>
        <slot:title></slot:title>
      </fill:title>

      <fill:subtitle>
        <slot:subtitle></slot:subtitle>
      </fill:subtitle>
    </x-project>
</div>

processTree():

<div class="interest">
  <a href="/src/who_we_are.html#isaac" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#isaac" hx-swap="innerHtml show:#isaac:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>

<div class="project">
  <div class="project-title" style="">

      <div class="figure">



      </div>



    </div>
  <div class="description">
    <div onclick="" style="">



    </div>

  </div>
</div>
</div>

You can see that by the time we reach the subcomponent, none of the slots are filled in, so they get removed entirely. My subcomponent has no <yield> tags either, so that probably doesn't help.

I reordered the pipeline to work like this

Original:

<script props>
  module.exports = {
    onclick: props.onclick || '',
    titlestyle: props.titlestyle || '',
    headerstyle: props.headerstyle || '',
    person: props.person,
  }
</script>
<div class="interest">
  <a href="/src/who_we_are.html#{{person}}" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#{{person}}"
    hx-swap="innerHtml show:#{{person}}:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>
  <x-project onclick="{{onclick}}" titlestyle="{{titlestyle}}" headerstyle="{{headerstyle}}">
    <if condition="$slots.img?.filled">
      <fill:img>
        <slot:img></slot:img>
      </fill:img>
    </if>
    <if condition="$slots.title?.filled">
      <fill:title>
        <slot:title></slot:title>
      </fill:title>
    </if>
    <if condition="$slots.links?.filled">
      <fill:links>
        <slot:links></slot:links>
      </fill:links>
    </if>
    <if condition="$slots.subtitle?.filled">
      <fill:subtitle>
        <slot:subtitle></slot:subtitle>
      </fill:subtitle>
    </if>
  </x-project>
</div>

expressions():

<div class="interest">
  <a href="/src/who_we_are.html#isaac" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#isaac" hx-swap="innerHtml show:#isaac:top">
    <div class="figure">
      <slot:person></slot:person>
    </div>
  </a>
  <x-project onclick="" titlestyle="" headerstyle="">

      <fill:img>
        <slot:img></slot:img>
      </fill:img>

      <fill:title>
        <slot:title></slot:title>
      </fill:title>

      <fill:subtitle>
        <slot:subtitle></slot:subtitle>
      </fill:subtitle>
    </x-project>
</div>

processSlotContent():

<div class="interest">
  <a href="/src/who_we_are.html#isaac" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#isaac" hx-swap="innerHtml show:#isaac:top">
    <div class="figure">

      <img src="/assets/isaac.jpg" class="person">

    </div>
  </a>
  <x-project onclick="" titlestyle="" headerstyle="">

      <fill:img>

      <img src="https://f4.bcbits.com/img/0020339057_10.jpg">

      </fill:img>

      <fill:title>

      <markdown>
        # Diverse System
      </markdown>

      </fill:title>

      <fill:subtitle>

      <markdown>
        ## This website is under construction
      </markdown>

      </fill:subtitle>
    </x-project>
</div>

processTree():

<div class="interest">
  <a href="/src/who_we_are.html#isaac" hx-get="/partials/who_we_are.html" hx-push-url="/who_we_are.html#isaac" hx-swap="innerHtml show:#isaac:top">
    <div class="figure">

      <img src="/assets/isaac.jpg" class="person">

    </div>
  </a>

<div class="project">
  <div class="project-title" style="">

      <div class="figure">


      <img src="https://f4.bcbits.com/img/0020339057_10.jpg">


      </div>


      <markdown>
        # Diverse System
      </markdown>


    </div>
  <div class="description">
    <div onclick="" style="">


      <markdown>
        ## This website is under construction
      </markdown>


    </div>

  </div>
</div>
</div>

Now, the component renders properly!

@StratusFearMe21
Copy link
Copy Markdown
Contributor Author

I also snuck in a change to fix the location of the filledSlots variable so that it's set to empty for each component instead of being the same for every component in a node with multiple components

@cossssmin
Copy link
Copy Markdown
Member

Oh boy I'm only now seeing this PR, just tested and you're right, we've had this bug all along!

Thanks for adding the fix, will release a patch as soon as possible.

@cossssmin cossssmin merged commit 468ef23 into posthtml:main Sep 25, 2025
3 checks passed
@cossssmin
Copy link
Copy Markdown
Member

Published in v2.2.1, thanks again!

https://github.com/posthtml/posthtml-components/releases/tag/v2.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants