Skip to content

Commit 7dab28d

Browse files
authored
Render help pages with a single rendering method. (#8050)
1 parent ccadaa1 commit 7dab28d

File tree

6 files changed

+55
-162
lines changed

6 files changed

+55
-162
lines changed

app/lib/frontend/handlers/misc.dart

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,16 @@ import 'cache_control.dart';
3232
final _log = Logger('pub.handlers.misc');
3333

3434
/// Handles requests for /help
35-
Future<shelf.Response> helpPageHandler(shelf.Request request) async {
36-
return htmlResponse(renderHelpPage());
37-
}
38-
39-
/// Handles requests for /help/api
40-
Future<shelf.Response> helpApiPageHandler(shelf.Request request) async {
41-
return htmlResponse(renderHelpApiPage());
42-
}
43-
44-
/// Handles requests for /help/scoring
45-
Future<shelf.Response> helpPageScoringHandler(shelf.Request request) async {
46-
return htmlResponse(renderHelpScoringPage());
47-
}
48-
49-
/// Handles requests for /help/content-moderation
50-
Future<shelf.Response> helpPageContentModerationHandler(
51-
shelf.Request request,
52-
) async {
53-
return htmlResponse(renderHelpContentModerationPage());
54-
}
55-
56-
/// Handles requests for /help/search
57-
Future<shelf.Response> helpPageSearchHandler(shelf.Request request) async {
58-
return htmlResponse(renderHelpSearchPage());
59-
}
60-
61-
/// Handles requests for /help/publishing
62-
Future<shelf.Response> helpPagePublishingHandler(shelf.Request request) async {
63-
return htmlResponse(renderHelpPublishingPage());
35+
/// Handles requests for /help/<article>
36+
Future<shelf.Response> helpPageHandler(
37+
shelf.Request request, {
38+
String? article,
39+
}) async {
40+
final html = renderHelpPage(article: article);
41+
if (html == null) {
42+
return notFoundHandler(request);
43+
}
44+
return htmlResponse(html);
6445
}
6546

6647
/// Handles requests for /policy

app/lib/frontend/handlers/routes.dart

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -263,33 +263,14 @@ class PubSiteService {
263263
@Route.get('/feed.atom')
264264
Future<Response> atomFeed(Request request) => atomFeedHandler(request);
265265

266-
/// Renders the help page
266+
/// Renders the main help page
267267
@Route.get('/help')
268-
Future<Response> helpPage(Request request) => helpPageHandler(request);
269-
270-
/// Renders the help page for API
271-
@Route.get('/help/api')
272-
Future<Response> helpApiPage(Request request) => helpApiPageHandler(request);
273-
274-
/// Renders the help page for scoring
275-
@Route.get('/help/scoring')
276-
Future<Response> helpPageScoring(Request request) =>
277-
helpPageScoringHandler(request);
278-
279-
/// Renders the help page for scoring
280-
@Route.get('/help/content-moderation')
281-
Future<Response> helpPageContentModeration(Request request) =>
282-
helpPageContentModerationHandler(request);
283-
284-
/// Renders the help page for search
285-
@Route.get('/help/search')
286-
Future<Response> helpPageSearch(Request request) =>
287-
helpPageSearchHandler(request);
288-
289-
/// Renders the help page for publishing
290-
@Route.get('/help/publishing')
291-
Future<Response> helpPagePublishing(Request request) =>
292-
helpPagePublishingHandler(request);
268+
Future<Response> helpPageMain(Request request) => helpPageHandler(request);
269+
270+
/// Renders a help article page
271+
@Route.get('/help/<article>')
272+
Future<Response> helpPageArticle(Request request, String article) =>
273+
helpPageHandler(request, article: article);
293274

294275
/// Renders the policy page
295276
@Route.get('/policy')

app/lib/frontend/handlers/routes.g.dart

Lines changed: 3 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/lib/frontend/templates/misc.dart

Lines changed: 34 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,36 @@ import 'views/account/unauthorized.dart';
1616
import 'views/page/error.dart';
1717
import 'views/page/standalone.dart';
1818

19-
/// The content of `/doc/api.md`
20-
final _apiMarkdown = _readDocContent('api.md');
21-
2219
/// The content of `/doc/policy.md`
2320
final _policyMarkdown = _readDocContent('policy.md');
2421

2522
/// The content of `/doc/security.md`
2623
final _securityMarkdown = _readDocContent('security.md');
2724

28-
/// The content of `/doc/help.md`
29-
final _helpMarkdown = _readDocContent('help.md');
30-
31-
/// The content of `/doc/help-*.md`
32-
final _helpScoringMarkdown = _readDocContent('help-scoring.md');
33-
final _helpSearchMarkdown = _readDocContent('help-search.md');
34-
final _helpPublishingMarkdown = _readDocContent('help-publishing.md');
35-
final _helpContentModerationMarkdown = _readDocContent(
36-
'help-content-moderation.md',
37-
);
25+
/// Loads help articles and stores them as a map with their
26+
/// basename as a key, e.g.:
27+
/// - `help.md` -> (title: 'Help', content: ...)
28+
/// - `help-search.md` -> (title: 'Search', content: ...)
29+
late final _helpArticles = () {
30+
final docDir = io.Directory(static_files.resolveDocDirPath());
31+
final files = docDir
32+
.listSync()
33+
.whereType<io.File>()
34+
.where((f) => f.path.endsWith('.md'));
35+
final results = <String, ({String? title, d.Node content})>{};
36+
for (final file in files) {
37+
final basename = p.basename(file.path);
38+
if (basename == 'help.md' || basename.startsWith('help-')) {
39+
final content = file.readAsStringSync();
40+
final firstLine = content.split('\n').first.trim();
41+
final title = firstLine.startsWith('# ')
42+
? firstLine.substring(2).trim().replaceAll('`', '')
43+
: null;
44+
results[basename] = (title: title, content: _readDocContent(basename));
45+
}
46+
}
47+
return results;
48+
}();
3849

3950
late final _sideImage = d.Image.decorative(
4051
src: static_files.staticUrls.packagesSideImage,
@@ -62,81 +73,21 @@ String renderUnauthorizedPage() {
6273
);
6374
}
6475

65-
/// Renders the `doc/api.md`.
66-
String renderHelpApiPage() {
67-
return renderLayoutPage(
68-
PageType.standalone,
69-
standalonePageNode(
70-
_apiMarkdown,
71-
sideImage: _sideImage,
72-
),
73-
title: 'pub.dev API',
74-
canonicalUrl: '/help/api',
75-
);
76-
}
77-
78-
/// Renders the `doc/help.md`.
79-
String renderHelpPage() {
80-
return renderLayoutPage(
81-
PageType.standalone,
82-
standalonePageNode(
83-
_helpMarkdown,
84-
sideImage: _sideImage,
85-
),
86-
title: 'Help | Dart packages',
87-
canonicalUrl: '/help',
88-
);
89-
}
90-
91-
/// Renders the `doc/help-scoring.md`.
92-
String renderHelpScoringPage() {
93-
return renderLayoutPage(
94-
PageType.standalone,
95-
standalonePageNode(
96-
_helpScoringMarkdown,
97-
sideImage: _sideImage,
98-
),
99-
title: 'Scoring | Dart packages',
100-
canonicalUrl: '/help/scoring',
101-
);
102-
}
103-
104-
/// Renders the `doc/help-content-moderation.md`.
105-
String renderHelpContentModerationPage() {
106-
return renderLayoutPage(
107-
PageType.standalone,
108-
standalonePageNode(
109-
_helpContentModerationMarkdown,
110-
sideImage: _sideImage,
111-
),
112-
title: 'Content Moderation | Pub site',
113-
canonicalUrl: '/help/content-moderation',
114-
);
115-
}
116-
117-
/// Renders the `doc/help-search.md`.
118-
String renderHelpSearchPage() {
119-
return renderLayoutPage(
120-
PageType.standalone,
121-
standalonePageNode(
122-
_helpSearchMarkdown,
123-
sideImage: _sideImage,
124-
),
125-
title: 'Search | Dart packages',
126-
canonicalUrl: '/help/search',
127-
);
128-
}
129-
130-
/// Renders the `doc/help-publishing.md`.
131-
String renderHelpPublishingPage() {
76+
/// Renders the `doc/help[<-article>].md`.
77+
String? renderHelpPage({String? article}) {
78+
final basename = article == null ? 'help.md' : 'help-$article.md';
79+
final page = _helpArticles[basename];
80+
if (page == null) {
81+
return null;
82+
}
13283
return renderLayoutPage(
13384
PageType.standalone,
13485
standalonePageNode(
135-
_helpPublishingMarkdown,
86+
page.content,
13687
sideImage: _sideImage,
13788
),
138-
title: 'Publishing | Dart packages',
139-
canonicalUrl: '/help/publishing',
89+
title: [page.title, 'Help', 'Dart packages'].nonNulls.toSet().join(' | '),
90+
canonicalUrl: article == null ? '/help' : '/help/$article',
14091
);
14192
}
14293

app/test/frontend/templates_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ void main() {
786786

787787
testWithProfile('help page', fn: () async {
788788
final html = renderHelpPage();
789-
expectGoldenFile(html, 'help_page.html');
789+
expectGoldenFile(html!, 'help_page.html');
790790
});
791791

792792
testWithProfile('topics page', fn: () async {
File renamed without changes.

0 commit comments

Comments
 (0)