Skip to content

Commit 0684097

Browse files
authored
Update and correct mustachio README (#3885)
1 parent 526dbd5 commit 0684097

File tree

1 file changed

+22
-23
lines changed

1 file changed

+22
-23
lines changed

tool/mustachio/README.md

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ The two popular Mustache packages for Dart ([mustache][] and [mustache4dart][])
3535
each use [mirrors][], which is slow, and whose future is unknown. The
3636
[mustache_template][] package avoids mirrors by restricting context objects to
3737
just Maps and Lists of values. Neither of these existing solutions were optimal
38-
for Dartdoc. For a time, dartdoc used the mustache package. When dartdoc creates
39-
documentation for a package, the majority of the time is spent generating the
40-
HTML output from package metadata. Benchmarking shows that much time is spent
41-
using mirrors.
38+
for Dartdoc. For a time, dartdoc used the mustache package. At that time, the
39+
majority of dartdoc's execution time was spent generating the HTML output from
40+
package metadata. Benchmarking showed that much time was spent using mirrors.
4241

4342
[Mustache templating]: https://mustache.github.io/
4443
[mustache]: https://pub.dev/packages/mustache
@@ -49,12 +48,8 @@ using mirrors.
4948
## Motivation
5049

5150
The primary motivation to design a new template rendering solution is to reduce
52-
the time to generate package documentation. In mid-2020, on a current MacBook
53-
Pro, it took 12 minutes to generate the Flutter documentation. A solution which
54-
uses static dispatch instead of mirrors's runtime reflection will be much
55-
faster. A prototype demonstrated that a new system which parses templates
56-
ahead-of-time against known context types could render the Flutter documentation
57-
in 3 minutes.
51+
the time to generate package documentation. A system that uses static dispatch
52+
in lieu of mirror-based dispatch is faster on the Dart VM.
5853

5954
There are several secondary benefits:
6055

@@ -647,18 +642,22 @@ keys at the time of code generation. For example, given the following template:
647642

648643
```html
649644
<h1>{{ name }}</h1>
650-
{{ #isFeatured }}<strong>Featured</strong>{{ /isFeatured }}
651645
<div class="posts">
652646
{{ #featuredPost }}<h2>{{ title }}</h2>{{ /featuredPost }}
653-
{{ #posts }}<h2>{{ title }}</h2>{{ /posts }}
647+
{{ #posts }}
648+
{{ #isPublished }}
649+
<h2>{{ title }}</h2>
650+
{{ /isPublished }}
651+
{{ /posts }}
654652
</div>
655653
```
656654

657-
The code generator resolves `name` to a String getter on User, `posts` to a
658-
`List<Post>` getter on User, `isPublished` to a `bool` getter on `Post`, and
659-
`title` to a String getter on `Post`. It has all of the information it needs to
660-
write out the logic of the template as a simple state machine. This state
661-
machine is written out as the render function and helper functions for partials:
655+
The code generator resolves `name` to a String getter on User, `featuredPost` to
656+
a Post getter on User, `posts` to a `List<Post>` getter on User, `isPublished`
657+
to a `bool` getter on `Post`, and `title` to a String getter on `Post`. It has
658+
all of the information it needs to write out the logic of the template as a
659+
simple state machine. This state machine is written out as the render function
660+
and helper functions for partials:
662661

663662
```dart
664663
String renderUser(User context0) {
@@ -668,7 +667,7 @@ String renderUser(User context0) {
668667
}
669668
```
670669

671-
The `renderFoo` function takes a `Foo` object, the context object, as
670+
The `renderUser` function takes a `User` object, the context object, as
672671
`context0`. Since the context objects exist in a stack and can each be accessed,
673672
we must enumerate them. We write various text to the buffer, according to the
674673
template, and then return the rendered output.
@@ -693,7 +692,7 @@ that provide each getter.
693692
buffer.write(htmlEscape.convert(context0.name.toString()));
694693
```
695694

696-
This code calls the `name` getter on `conext0`, and then `toString()`. Since
695+
This code calls the `name` getter on `context0`, and then `toString()`. Since
697696
`{{ name }}` uses two brackets, the output must be HTML-escaped. If it were
698697
written `{{{ name }}}`, then the HTML-escaping call would not be made.
699698

@@ -708,14 +707,14 @@ the renderer.
708707
`{{ #isFeatured }}<strong>Featured</strong>{{ /isFeatured }}` compiles to:
709708

710709
```dart
711-
if (context0.b1 == true) {
710+
if (context0.isFeatured) {
712711
buffer.write('''<strong>Featured</strong>''');
713712
}
714713
```
715714

716-
The text is written only if `b1` is `true` (not `false` or `null`). If the
717-
section were inverted (starting with `{{ ^isFeatured }}`), this would be a
718-
`!= true` check.
715+
The text is written only if `isFeatured` is `true`. If the section were
716+
inverted (starting with `{{ ^isFeatured }}`), then the condition would be
717+
`!context0.isFeatured`.
719718

720719
#### Rendering a repeated section
721720

0 commit comments

Comments
 (0)