Skip to content

Conversation

@ianjosephwilson
Copy link
Contributor

Proof of concept for discussion, needs tests and more refactoring.

  • Repacks TNode tree into a new Template after parsing to determine the structure.
  • Renders Template directly to str without Node using iterative solution.
  • Extension point concepts
    • Components can affect tdom's rendering of descendents by returning a dict[str, object] in a 2-tuple
      • ie. Components can ask tdom to set context vars for descendent components to access by returning (Template, {'context_values': ((CTX_VAR, 'value-to-set'),)})
    • "System" kwargs can be provided to participating components (beyond just children).
      • ie. def Component(sys_context, children) -> Template

Some of this we might be able to back-port into tdom's Node renderer.

…marker for this during parsing instead of having this weird component return API.
@pauleveritt
Copy link
Contributor

Minor point, related to component result types and my aria-testing package. For "component driven development" I prefer doing my development via tests, not browser reloads. I want others too also, so I really want to make develop-via-tests the easiest path.

String assertions are certainly easiest, until the moment it gets even a bit structural.

Node assertions have proven really convenient, with the added benefit that they are accessibility-focused.

@ianjosephwilson
Copy link
Contributor Author

@pauleveritt Just to clarify, can the "node"ifying occur at the "very end" or does it have to occur at every level? It seems that you could just wrap the highest level template under test and convert that to nodes. Besides giving hints to tooling with html() does it need to be part of the component pattern?

For example something like this:

def Heading(children: Template) -> Template:
    return t'<h2>{children}</h2>'
def Section(title: str) -> Template:
    return t'<section><{Heading}>{title}</{Heading}></section>'
def Body(sections: list[SectionDO]) -> Template:
    return t'<body>{[t"<{Section} title={section.title} />" for section in sections]}</body>'

# Just makes a tree of Templates into Nodes but do it all at once:
node = html(Body(sections=[SectionDO(title="News"), SectionDO(title="Sports")]))
assert isinstance(node, Element)
# The optimized for making strings version.
html_str = html_to_str(Body(sections=[SectionDO(title="News"), SectionDO(title="Sports")]))
def Heading(children: Node) -> Node:
    return html(t'<h2>{children}</h2>')
def Section(title: str) -> Node:
    return html(t'<section><{Heading}>{title}</{Heading}></section>')
def Body(sections: list[SectionDO]) -> Node:
    return html(t'<body>{[t"<{Section} title={section.title} />" for section in sections]}</body>')

node = html(Body(sections=[SectionDO(title="News"), SectionDO(title="Sports")]))
assert isinstance(node, Element)

@pauleveritt
Copy link
Contributor

@ianjosephwilson That certainly would work for test-writing but it would eliminate other uses of Node. I previously mentioned middleware and tooling.

But I'm also interested in interoperability. For example, I have a decorator that lets an htpy "component" be used in tdom. They both have similar concepts of a node structure. It would be great to converge on a common standard, to prevent tdom from being yet-another-template-language.

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