-
Notifications
You must be signed in to change notification settings - Fork 363
Expand file tree
/
Copy pathdoc_layout.dart
More file actions
129 lines (115 loc) · 3.92 KB
/
Copy pathdoc_layout.dart
File metadata and controls
129 lines (115 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2025 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:jaspr/dom.dart';
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_content/jaspr_content.dart';
import '../components/common/flutter_cn/ai_translation_notice.dart';
import '../components/common/page_header.dart';
import '../components/common/prev_next.dart';
import '../components/layout/banner.dart';
import '../components/layout/toc.dart';
import '../components/layout/trailing_content.dart';
import '../models/page_navigation_model.dart';
import 'dash_layout.dart';
/// The Jaspr Content layout to use for normal docs pages,
/// adding elements such as breadcrumbs, TOC, and prev/next cards.
class DocLayout extends FlutterDocsLayout {
const DocLayout();
@override
String get name => 'docs';
bool get allowBreadcrumbs => true;
@override
({Set<String> prerender, Set<String> prefetch}) speculationUrls(Page page) {
// On the homepage, prefetch pages commonly navigated to,
// such as entries from the top navigation menu.
if (page.path == 'index.md') {
return (
prerender: const {},
prefetch: const {
'/learn/pathway',
'/ai/create-with-ai',
},
);
}
final pageData = page.data.page;
return (
prerender: {?_pathFromPageInfo(pageData['next'])},
prefetch: {?_pathFromPageInfo(pageData['prev'])},
);
}
@override
Component buildBody(Page page, Component child) {
final pageData = page.data.page;
final siteData = page.data.site;
final pageTitle = pageData['title'] as String;
final pageDescription = (pageData['description'] as String?)?.trim();
final aiTranslated =
(pageData['ai-translated'] as bool?) ??
(pageData['aiTranslated'] as bool?) ??
false;
final showBanner =
(pageData['showBanner'] as bool?) ??
(siteData['showBanner'] as bool?) ??
false;
final navigationData = page.navigationData;
return super.buildBody(
page,
.fragment(
[
if (navigationData
case null || PageNavigationData(toc: null, pageEntries: []))
const Document.body(attributes: {'data-toc': 'false'})
else
div(
id: 'site-subheader',
classes: navigationData.pageEntries.isNotEmpty
? 'show-always'
: null,
[
PageNavBar(navigationData),
],
),
if (showBanner)
if (siteData['bannerHtml'] case final String bannerHtml
when bannerHtml.trim().isNotEmpty)
DashBanner(bannerHtml),
div(classes: 'after-leading-content', [
if (navigationData case PageNavigationData(
toc: final toc?,
pageEntries: [],
))
aside(id: 'side-menu', [
DashTableOfContents(toc),
]),
article([
PageHeader(
title: pageTitle,
description: pageDescription,
showBreadcrumbs:
allowBreadcrumbs &&
(pageData['showBreadcrumbs'] as bool? ?? true),
),
/// flutter.cn
if (aiTranslated) const AiTranslationNotice(),
child,
PrevNext(
previousPage: PageNavigationEntry.fromData(pageData['prev']),
nextPage: PageNavigationEntry.fromData(pageData['next']),
),
const TrailingContent(),
]),
]),
],
),
);
}
}
/// Extracts and returns the `path` value from a page info map,
/// or `null` if [data] is not a map or has no `path` entry.
String? _pathFromPageInfo(Object? data) {
if (data case {'path': final String path}) {
return path;
}
return null;
}