Skip to content

rustdoc: use a templating engine to generate HTML #84419

Closed
@jsha

Description

@jsha
Contributor

Right now rustdoc generates HTML with a series of writes embedded in the Rust code. This means the Rust code needs to process the elements of a page in the same order that they will be emitted in HTML. It makes it hard to get a holistic view of the page structure. It means we need to take care to make sure tags are balanced, which can be particularly hard when a function has multiple return points. It means in order to make any changes to the HTML, you need a good understanding of the Rust code.

If we use a templating engine, we can separate the templates from the Rust code, improving those problems. It would also mean we could have a mode for rustdoc to read templates at runtime instead of using its compiled-in templates. That would make iterating on HTML improvements easier, because we wouldn't have to wait for a compile cycle for each change.

There are a variety of templating engines out there, but I think mustache is quite good. In particular the choice to have no logic in templates is important, because otherwise it is tempting to put some logic in templates and some in the driving code, which becomes confusing. In Rust, the handlebars crate looks mature and actively maintained. It implements the handlebars template language, which is evidently different from mustache but pretty close.

Activity

added
T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
A-rustdoc-uiArea: Rustdoc UI (generated HTML)
on Apr 22, 2021
ghost

ghost commented on Apr 22, 2021

@ghost

https://github.com/Keats/tera
Tera is a good engine too.
It's similar the Django template engine, which the best and friendly engine .
https://docs.djangoproject.com/en/3.1/topics/templates/
I like Rust, and like Python.

GuillaumeGomez

GuillaumeGomez commented on Apr 22, 2021

@GuillaumeGomez
Member

If we use a templating engine, we can separate the templates from the Rust code, improving those problems. It would also mean we could have a mode for rustdoc to read templates at runtime instead of using its compiled-in templates. That would make iterating on HTML improvements easier, because we wouldn't have to wait for a compile cycle for each change.

No, we don't want anything at runtime because it requires running a server, which we definitely don't want. Closing this issue then.

Swatinem

Swatinem commented on Apr 22, 2021

@Swatinem
Contributor

we don't want anything at runtime because it requires running a server, which we definitely don't want.

I think you misinterpreted this. Its rather "at documentation generation time". So it would be more like a static site generator. No need to run a server.

I could imagine an unstable --template-dir switch as well to control the templates being used, for maximizing iteration time on this.

GuillaumeGomez

GuillaumeGomez commented on Apr 22, 2021

@GuillaumeGomez
Member

Oh, my bad. I'm still not a big fan of the idea of depending on an external template engine though...

EDIT: to add a bit more on my comment: rustdoc can generate up to thousands of files for one crate. I'm afraid that using a template engine might have a big (negative) impact on performance. But that's just a hunch, we need actual number before saying such things and I don't have them. And I'm afraid that if someone makes the implementation and the numbers are bad, it might just end up in a lot of work for nothing. Not really a great experience...

jyn514

jyn514 commented on Apr 22, 2021

@jyn514
Member

In particular the choice to have no logic in templates is important, because otherwise it is tempting to put some logic in templates and some in the driving code, which becomes confusing.

FYI almost all template languages have at least if conditions/for loops, including handlebars. Maybe that's not what you meant though?

jyn514

jyn514 commented on Apr 22, 2021

@jyn514
Member

And yes, I would prefer tera if possible for consistency with docs.rs.

jsha

jsha commented on Apr 22, 2021

@jsha
ContributorAuthor

I hear you, @GuillaumeGomez, about introducing extra dependencies, particularly in something that's such a core, critical tool. I think the benefit in maintainability is likely to be worth it.

rustdoc can generate up to thousands of files for one crate. I'm afraid that using a template engine might have a big (negative) impact on performance. But that's just a hunch, we need actual number before saying such things and I don't have them. And I'm afraid that if someone makes the implementation and the numbers are bad, it might just end up in a lot of work for nothing.

These are definite risks. I suspect the performance will be good. Templating engines are often used as part of the live request path in web servers, so they have to be fast. They might even do a better job of optimizing string handling than our current series of write! does.

almost all template languages have at least if conditions/for loops, including handlebars. Maybe that's not what you meant though?

Mustache describes itself as logic-less:

We call it "logic-less" because there are no if statements, else clauses, or for loops. Instead there are only tags. Some tags are replaced with a value, some nothing, and others a series of values. This document explains the different types of Mustache tags.

And Handlebars has some discussion about what it means by logic-less.

But I'm not too picky. I think we would benefit from any templating engine, and if we go that route, one that is familiar to some team members already would of course be great.

GuillaumeGomez

GuillaumeGomez commented on Apr 22, 2021

@GuillaumeGomez
Member

As long as it doesn't require external libraries to be installed to work and doesn't kill performance, I think I can live with it. :)

workingjubilee

workingjubilee commented on Apr 22, 2021

@workingjubilee
Member

https://github.com/Keats/tera
Tera is a good engine too.
It's similar the Django template engine, which the best and friendly engine .
https://docs.djangoproject.com/en/3.1/topics/templates/
I like Rust, and like Python.

Tera, as a Jinja dialect, admits a fairly "large language" compared to handlebars.
If we were to use a Jinja dialect, askama is similar and mostly compiled.
This leads to some considerable performance benefits, which @djc, the creator of askama (and notable Rust contributor) has investigated: https://github.com/djc/template-benchmarks-rs
These benchmarks show that as far as beating std, most template engines do not, they mostly compete, though interestingly maud and markup do, and both have the distinction of still being mostly Rust (they're basically just macros).

djc

djc commented on Apr 22, 2021

@djc
Contributor

I'll try not to shill for Askama too much, but to some extent I actually consider the type safety of Askama (and Askama-like engines) to be more interesting/useful than its performance (though both are, of course, valuable).

In any case, happy to answer any questions that come up.

55 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-rustdoc-uiArea: Rustdoc UI (generated HTML)C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @djc@jsha@Swatinem@Manishearth@GuillaumeGomez

        Issue actions

          rustdoc: use a templating engine to generate HTML · Issue #84419 · rust-lang/rust