Skip to content

Add a consistent rendering protocol. #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2025
Merged

Add a consistent rendering protocol. #92

merged 1 commit into from
Apr 12, 2025

Conversation

pelme
Copy link
Owner

@pelme pelme commented Mar 8, 2025

This change provides a consistent API to render a htpy object as HTML or
iterate over it.

This commit introduces the iter_chunks() method which is identical with
__iter__() but with a better name.

With the introduction of Fragment, this commit makes render_node and
iter_node redundant.

This commit deprecates render_node, iter_node and direct iteration of elements.

More info: #86 (comment)

@pelme pelme force-pushed the pelme-zsxolror branch 5 times, most recently from 70657cb to 49b3d74 Compare March 14, 2025 20:25
@pelme pelme changed the base branch from main to pelme-zlurnkrs March 14, 2025 20:25
@pelme pelme force-pushed the pelme-zsxolror branch 2 times, most recently from 87d6e24 to b0ca361 Compare March 15, 2025 09:00
Base automatically changed from pelme-zlurnkrs to main March 16, 2025 13:32
@pelme pelme mentioned this pull request Mar 20, 2025
@davepeck
Copy link

davepeck commented Mar 20, 2025

I've been playing with these changes (well, after fixing that one lint issue) and: so far, so good. All my "template" functions return h.Renderable now and everything feels that much simpler.

As a random aside: these changes also caused me to slightly update my @with_children decorator, which I still use to make regular functions support __getitem__ and look a bit more like any other htpy Element:

@dataclass(frozen=True)
class with_children[C, R: h.Renderable, **P]:
    """Wrap a function to make it look more like an htpy.Element."""

    _f: t.Callable[t.Concatenate[C, P], R]
    _args: tuple[t.Any, ...] = field(default_factory=tuple)
    _kwargs: t.Mapping[str, t.Any] = field(default_factory=dict)

    def __getitem__(self, children: C) -> R:
        """Render the component with the given children."""
        return self._f(children, *self._args, **self._kwargs)

    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> t.Self:
        """Return a new instance of the class with the given arguments."""
        return replace(self, _args=args, _kwargs=kwargs)

    def __str__(self) -> str:
        """Return the name of the function being wrapped."""
        # CONSIDER: alternatively, invoke the function here? If the function
        # provides a default value for its arguments, it'll work; otherwise,
        # it will blow up... which might be a good thing?
        return f"with_children[{self._f.__name__}]"

@pelme pelme force-pushed the pelme-zsxolror branch 2 times, most recently from 29ceefa to 57fae08 Compare March 20, 2025 20:59
@pelme
Copy link
Owner Author

pelme commented Mar 20, 2025

@davepeck awesome, thanks for the update! pushed an updated version that fixes the lint problem.

I renamed stream_chunks() to iter_chunks() which I like better, thoughts about that?

I will also add some kind of DeprecationWarning to render_node/iter_node and then hopefully merge this PR in the next few days. Then we can hopefully also get #38 done. Feel free to have a look there too!

@davepeck
Copy link

I renamed stream_chunks() to iter_chunks() which I like better, thoughts about that?

I prefer iter_chunks() too!

Then we can hopefully also get #38 done. Feel free to have a look there too!

Will do...

@jodal
Copy link
Contributor

jodal commented Apr 2, 2025

I'm trying to get our version of with_children to work on components that also use contexts. I'm trying to juggle both the current implementation of htpy and these changes in my head at the same time, so that I won't have to redo it once this is merged.

What I'm saying is that I'd love for this to be merged and released, so that I can garbage collect half of my mental state 😅

@pelme
Copy link
Owner Author

pelme commented Apr 2, 2025

have not been able to finish up these changes yet, not sure when I will get around to it. if someone wants to look into deprecation warnings for render_node/iter_node and update the docs/changelog, that would be helpful!

@davepeck
Copy link

davepeck commented Apr 2, 2025

have not been able to finish up these changes yet, not sure when I will get around to it. if someone wants to look into deprecation warnings for render_node/iter_node and update the docs/changelog, that would be helpful!

I took a quick first stab at this: https://github.com/davepeck/htpy/tree/pelme-zsxolror

Tried to match your house style but let me know what's most useful.

(Update: my branch has a couple small updates as of 4/3 @ 9AM Pacific)

@pelme pelme force-pushed the pelme-zsxolror branch 4 times, most recently from 7dd0abb to 99a0f89 Compare April 10, 2025 19:43
@pelme
Copy link
Owner Author

pelme commented Apr 10, 2025

I have updated the PR based on you commits @davepeck , I think it may be good to go.

I changed Renderable to be a type alias rather than a Protocol. I think that makes more sense. Then a Renderable can always be a Node.

@davepeck @jodal Can you please have another look?

@pelme pelme force-pushed the pelme-zsxolror branch 5 times, most recently from f94613d to 3fc35b1 Compare April 11, 2025 13:40
@pelme pelme force-pushed the pelme-zsxolror branch 3 times, most recently from 4f47267 to 2c96e6b Compare April 11, 2025 19:05
Copy link

@davepeck davepeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really happy where this landed!

This change provides a consistent API to render a htpy object as HTML or
iterate over it.

This commit introduces the iter_chunks() method which is identical with
`__iter__()` but with a better name.

With the introduction of Fragment, this commit makes render_node and
iter_node redundant.

This commit deprecates render_node, iter_node and direct iteration of elements.

More info: #86 (comment)
@pelme pelme merged commit 6b5702d into main Apr 12, 2025
28 checks passed
@pelme pelme deleted the pelme-zsxolror branch April 12, 2025 08:44
pelme added a commit that referenced this pull request Apr 12, 2025
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.

3 participants