Skip to content
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

Guidance on nested layouts and renderers #1899

Closed
bruceharrison1984 opened this issue Jan 4, 2024 · 6 comments
Closed

Guidance on nested layouts and renderers #1899

bruceharrison1984 opened this issue Jan 4, 2024 · 6 comments
Labels
enhancement New feature or request.

Comments

@bruceharrison1984
Copy link
Contributor

bruceharrison1984 commented Jan 4, 2024

What is the feature you are proposing?

It'd be helpful if some documentation around nested layouts was available.

Currently doing something like the following doesn't work:

const app = new Hono();
app.use('*', renderer); 
app.get('/signin', signinRoute); // <- use root renderer

const secureRoute = new Hono();
secureRoute.use('*', secureRenderer);
secureRoute.get('/test', (ctx) => ctx.render(<>SOME TEST</>)); // <- use secure renderer, the root renderer doesn't get used

app.route('/secure', secureRoute );

Currently, which ever renderer is located closest to the route is the one that will be used. Simply using JSX components to wrap a layout around pages works well enough, but a best practice would be helpful.

SonikJS supports nested layouts in this fashion (at least via __layout) so it would seem that Hono could also support this.

@bruceharrison1984 bruceharrison1984 added the enhancement New feature or request. label Jan 4, 2024
@yusukebe
Copy link
Member

yusukebe commented Jan 9, 2024

Hi @bruceharrison1984 !

Actually, I didn't take c.render() into consideration for nested layouts. However, as you may know, what c.render() does is simple as follows.

private renderer: Renderer = (content: string | Promise<string>) => this.html(content)

// ...

render: Renderer = (...args: any[]) => this.renderer(...args)

I'm thinking about it, but if you come up with a good way to nest layouts, please share!

By the way, Sonik's __layout mechanism will be deprecated and replaced "renderer" based. So it is great to be able to use c.render() for nested layouts in a smart way.

@bruceharrison1984
Copy link
Contributor Author

I'm thinking about it, but if you come up with a good way to nest layouts, please share!

By the way, Sonik's __layout mechanism will be deprecated and replaced "renderer" based. So it is great to be able to use c.render() for nested layouts in a smart way.

Yeah, that's a tough one. I presume Sonik works via Vite scanning for layouts higher in the tree and merging them, while Hono doesn't have that same mechanism.

You'd need some way to reference a parent Hono instance from the child to check if a Renderer has been registered.

@bruceharrison1984
Copy link
Contributor Author

After thinking about this a bit, it seems like at a minimum you'd need to make the renderer visible outside of the the Context object to facilitate messing around with it.

private renderer: Renderer = (content: string | Promise<string>) => this.html(content)

Simply adding a getRenderer function would make it possible to query to context for the current renderer, and essentially invoke it from there, while adding a child layout within it. A very naive approach, but seems feasible with some refinement

@yusukebe
Copy link
Member

@bruceharrison1984

Great!

If you can, please create a PR that does this and write the specific usage in the description section of that PR.

I want this to be a feature of the next major version of v4, so please make a PR based on this v4 branch:

https://github.com/honojs/hono/tree/v4

Thanks.

@bruceharrison1984
Copy link
Contributor Author

@yusukebe I'll give it a crack! No promises though 😆

@yusukebe
Copy link
Member

Resolved by #1945

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request.
Projects
None yet
Development

No branches or pull requests

2 participants