blade-parser icon indicating copy to clipboard operation
blade-parser copied to clipboard

Parsing nested literal nodes

Open mattkingshott opened this issue 11 months ago • 4 comments

Hey @JohnathonKoster!

So I wanted to give you some feedback about the Parser. Firstly, amazing!

Secondly, there’s only one thing that I’d really love to see handled differently, and that’s Literal Nodes.

As you may have seen in the Bint formatter project, the biggest obstacle is dealing with nested HTML tags (in fact, if I remember correctly, it’s the only real problem) e.g.

<div>
  <p>
    <a>
      Some plain text content
    </a>
  </p>
</div>

Right now, the parser just lumps this all together as a single literal node (even when building a root / tree)

Ideally, (at least IMO), literal nodes would be solely plain text. HTML tags would be parsed similarly to ComponentNodes but maybe with a different type e.g. HtmlElementNode?

Lastly HTML comments would be e.g. HtmlCommentNode.

So you’d get something like this for the above example when creating a root / tree using getRootNodes()…

<HtmlElementNode>
  <HtmlElementNode>
    <HtmlElementNode>
      <LiteralNode>

Eager to hear what your thoughts are on this. Do you think it is possible? Are you open to adding it?

Thanks again! 🙏🏻

mattkingshott avatar Feb 08 '25 23:02 mattkingshott

It's definitely possible; the current behavior of treating everything that isn't Blade as literal text is just because it "wasn't interesting" for historical use-cases. I'm definitely open to adding support, and it would likely be an opt-in feature (and possibly the default of a future major version). There is a very primitive version of something like this that could be expanded on to do what you want (this drives the feature letting you know "where" a Blade structure is relative to other items in the document).

One question I do have is what would be more useful for your use case in a scenario like the following:

<{{ $dynamicElementName }} class="something here">

</{{ dynamicElementName }}>

It'd be possible to emit nodes to specify the start of an element, followed by the Blade echo, the element's attributes, and then the end of the element. Alternatively, we could also just emit a typical <HtmlElementNode>, whose "name" just happens to be a Blade structure.

Would you be interested in having these be paired with all of the child nodes associated?

JohnathonKoster avatar Feb 09 '25 01:02 JohnathonKoster

That's great news!

Regarding the specific use case you describe, I don't know how many people are creating the HTML element's type dynamically (but IMO, I don't think it's something devs should really be doing 🙊).

Personally, I think I would go with a typical HtmlElementNode with the name set to a dynamic expression / Blade structure. I think it's also the closest representation of what is actually in the template.

And yes, I would be interested in pairing with child nodes.

Essentially, what I want to be able to with every ComponentNode and HtmlElementNode is to be able to get it's name, parameters / attributes, children (if it has any), and inner content.

When using the getRootNodes() method, the resulting collection already does it for ComponentNode, it's just a case of doing it for HtmlElementNode.

Having these features will allow me to work out proper indentation for formatting, and will allow me to sort parameters / attributes e.g. by length, alphabetically, according to a framework's rules (Vue, React etc.).

Once that is in place, I reckon, the formatter can be released, as that's all I would want to include as its defaults. People can then submit or use their own custom rules as needed.

Let me know if you need any more feedback or clarification 🙏🏻

Thanks again!

mattkingshott avatar Feb 09 '25 11:02 mattkingshott

Thanks for the extra feedback! I'll do some more thinking before diving into this one; it may take some time to implement this - I'll reach out when I have something that can be experimented with before a general release 🤝

JohnathonKoster avatar Feb 09 '25 16:02 JohnathonKoster

Awesome! Can’t wait 🚀

mattkingshott avatar Feb 09 '25 17:02 mattkingshott

Closing as not planned in this project. You've been invited to the private alpha/beta of Forte, which can do this.

JohnathonKoster avatar Aug 22 '25 05:08 JohnathonKoster

Thanks for the invite!

mattkingshott avatar Aug 22 '25 07:08 mattkingshott