-
Notifications
You must be signed in to change notification settings - Fork 125
Remove <base href /> and relative hrefs #2090
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
Comments
Tagging @kwalrath for angular, @gspencergoog for Flutter. |
Tagging @isoos for pub.dev. |
Just for clarity, could someone spell out for me why markdown does not support relative links? pub.dev serves docs from something like: https://pub.dev/documentation/flutter_redux/latest/ I think that would work poorly with absolute links.
Would specifying the empty site-root-prefix be the same as having relative links? In that way we can support both styles. I think it would be great if we went a bit further with the configurability and made a mapping of host prefixes per package. Then the docs for one package could link to the docs for another. And we could perhaps even link to api.dart.dev for the standard libraries from https://pub.dev/documentation/ . |
This used to work, but changed over time, and we have pending bugs to track it: I had an attempt to fix it a few months back, however, I'm stuck with that, don't really understand what's going on there: @jcollins-g: I think this is a separate issue, but it would be really great if you had the time to help us out here too. |
@isoos I really would like to help but unfortunately all of my time right now is committed to the NNBD migration tooling effort. I can answer questions and review code, but that's about it. I'll take a look at the above referenced bugs and answer what I can; feel free to hit me up on chat as well if you're in the thick of it. |
Relative links do work in Markdown. The part that doesn't work in Markdown is the In the example above, multiple pages will link to the Bar class, and here is a table of what the relative links to be:
In reality, Dartdoc never emits any of the links in the second column for Bar, it always emits Making Dartdoc emit complete relative links like those in the second column is far too complicated a change, unfortunately.
This is something we'd like to test out. It might be that you'd only supply
At the moment the goal is to remove relative links entirely for the reasons mentioned. Even with an empty prefix, I would still be prepending a Supporting both styles feels like it would be a maintenance burden, but if that ends up being the only path that works, we can do it. |
We had a similar issue with relative links coming from markdown contents, where a relative link inside the markdown is rewritten with an absolute base URL. We ended up writing a markdown
I believe a similar approach may work for dartdoc too, as the relative ( I have always found the |
Emitting complete relative links would be fantastic, but I don't know if that is feasible with Dartdoc's current structure. Everything that accesses a model's
I'm very open to ideas here, but that's my current assessment. |
Thanks for the explanation, I was unaware of how
But when there is a newer version available we like to serve the old one like this: https://pub.dev/documentation/flutter_redux/0.5.2/ it would need changing all the links?
Without knowing the subtleties of dartdoc:
I'm not saying it is easy - but it sounds feasible to me. |
This is dipping into a lot technical debt in dartdoc and even in my discussions with @jdkoren I feel like we've handwaved a bit why this isn't easy -- maybe it's time to dive in and explore what's needed. I think the key problem making this hard is the use of reflection in mustache template processing. Mustache has the ability to restrict template evaluation to a specified interface in your template classes (in fact, that's what the example does). You can then use lambdas as @sigurdm suggests. But dartdoc uses the alternative (and poorer performing) evaluation that uses dart:mirrors to dynamically evaluate complex expressions inside the template to point to Dart objects. This creates somewhat magical evaluations of very simple Dart-like references e.g.: <div id="dartdoc-sidebar-left" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left">
{{>search_sidebar}}
<h5>{{parent.name}} {{parent.kind}}</h5>
{{>sidebar_for_library}}
</div> The My initial thought is the correct, though slow path through this is to refactor TemplateData and friends to minimize or stop using reflection. This would be a slog, but at least nowadays mustache4dart reliably reports when template references are unresolved and @jdkoren has already extracted a lot of the rendering logic out -- so this is less of a mountain to climb than it used to be. It seems likely that some interfaces and code might be extracted out of ModelElement to some mixin or interface shared between TemplateData and ModelElement to avoid a lot of duplication of hasThingIterable, thingIterable, canonicalThingIterable, etc. If you do manage to achieve this, While we can still consider alternatives, so far it seems everything is understandably trying to avoid doing this big chunk of work. If we can find a reasonable workaround that doesn't make the current situation worse for dartdoc or our downstream users I'm for it. Other reasonable alternatives might include ditching mustache entirely for another template system that's more in line with our needs, but that doesn't exactly sound like saving effort. |
Adding to what @jcollins-g wrote, there are other properties like There is also the issue that some of the properties being accessed are computed once and the result is held by the model thereafter. Any of those containing hrefs can no longer be memo-ized this way, regardless of what we do with mustache. Taking the example above, suppose we add this documentation: class Foo {
+ /// Says hello with a [Bar].
void hello(Bar bar) { /* ... */ }
} Documentation is normally converted to an HTML string only once, with If the hrefs remained absolute, we could avoid recomputing this and other properties. |
Another way to handle that would be to have the Documentation rendering to "HTML" actually render to mustache with some kind of reference for those dynamic bits. That'd enable dynamic substitution of hrefs without forcing rerenders of all the markdown (which indeed would be expensive). |
I have a somewhat cheeky approach that lets us make complete relative paths without drastic changes to Dartdoc. The basica idea is, instead of Dartdoc emitting It adds a little extra step to the template generation process, but it's still Dartdoc doing all the work, and the result should be working hrefs, so current users shouldn't need a transition. #2096 starts the ball rolling by decoupling hrefs and filenames. |
Context
Currently DartDoc emits relative hrefs when linking to another generated page. These hrefs all start from the docs output directory. In order to make these work, each page also includes a
<base href />
in the<head>
that walks back to the docs output directory (i.e...
or../..
). For example, consider these sources:The docs tree would partially look like this:
In
a/Foo-class.html
DartDoc emits<base href=".." />
, and emits links toBar
in the form of<a href="b/Bar-class.html" />
. Such links will be resolved properly as{api/docs}/a/../b/Bar-class.html => {api/docs}/b/Bar-class.html
.Without the
<base href>
, the link would go to a nonexistent page:{api/docs}/a/b/Bar-class.html
.While this technique does make the pages quite portable, we can't use it for Markdown output (#1479). Also, there may be hosting situations where this
<base href />
isn't ideal or can't be used.Proposal: absolute hrefs from site root
The current hrefs are already relative to the site root and can be made absolute by placing a
/
in front:<a href="/b/Bar-class.html" />
. Assuming the site root is in factapi/docs/
in our example, these links will always resolve properly. #2089 implements this.Caveats and concerns
Specifying a site root
Using a different site root requires updating all the generated hrefs. DartDoc could support a site root prefix to hrefs via a new
DartdocOption
, otherwise clients are left to using a separate process to find and replace the hrefs. This option is under consideration and not yet implemented.Link validation
DartDoc tries to ensure that generated links lead to valid pages. This process needs to account for the new href format and any new options for a site root prefix.
Transitioning important DartDoc usages
Major users of DartDoc include api.dartlang.org and flutter.dev/api. These and other usages need to be transitioned smoothly.
The text was updated successfully, but these errors were encountered: