Skip to content

Commit ad65ae8

Browse files
authored
Make redirect pages for categories (#4037)
1 parent 9ab9ba0 commit ad65ae8

8 files changed

+188
-29
lines changed

lib/src/generator/generator_backend.dart

+6-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ abstract class GeneratorBackend {
8686
);
8787
}
8888
var e = data.self;
89-
writer.write(filename, content,
90-
element: e is Warnable ? e : null);
89+
writer.write(filename, content, element: e is Warnable ? e : null);
9190
}
9291

9392
/// Emits JSON describing the [categories] defined by the package.
@@ -122,6 +121,11 @@ abstract class GeneratorBackend {
122121
var data = CategoryTemplateData(options, packageGraph, category);
123122
var content = templates.renderCategory(data);
124123
write(writer, category.filePath, data, content);
124+
if (category.filePath != category.redirectFilePath) {
125+
var redirectContent = templates.renderCategoryRedirect(data);
126+
write(writer, category.redirectFilePath, data, redirectContent);
127+
}
128+
125129
runtimeStats.incrementAccumulator('writtenCategoryFileCount');
126130
}
127131

lib/src/generator/templates.aot_renderers_for_html.dart

+35
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,41 @@ String renderCategory(CategoryTemplateData context0) {
234234
return buffer.toString();
235235
}
236236

237+
String renderCategoryRedirect(CategoryTemplateData context0) {
238+
final buffer = StringBuffer();
239+
buffer.write('''<!DOCTYPE html>
240+
<html lang="en">
241+
<head>
242+
<link rel="canonical" href="''');
243+
if (context0.useBaseHref) {
244+
var context1 = context0.htmlBase;
245+
buffer.write(context0.htmlBase);
246+
}
247+
buffer.writeEscaped(context0.self.href);
248+
buffer.write('''" />
249+
<meta http-equiv="refresh" content="0; url=''');
250+
if (context0.useBaseHref) {
251+
var context2 = context0.htmlBase;
252+
buffer.write(context0.htmlBase);
253+
}
254+
buffer.writeEscaped(context0.self.href);
255+
buffer.write('''" />
256+
</head>
257+
<body>
258+
<p><a href="''');
259+
if (context0.useBaseHref) {
260+
var context3 = context0.htmlBase;
261+
buffer.write(context0.htmlBase);
262+
}
263+
buffer.writeEscaped(context0.self.href);
264+
buffer.write('''">New URL</a></p>
265+
</body>
266+
</html>
267+
''');
268+
269+
return buffer.toString();
270+
}
271+
237272
String renderClass(ClassTemplateData context0) {
238273
final buffer = StringBuffer();
239274
buffer.write(_renderClass_partial_head_0(context0));

lib/src/generator/templates.dart

+12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
@Renderer(#renderCategory, Context<CategoryTemplateData>(), 'category',
1414
visibleTypes: _visibleTypes)
15+
@Renderer(#renderCategoryRedirect, Context<CategoryTemplateData>(),
16+
'category_redirect',
17+
visibleTypes: _visibleTypes)
1518
@Renderer(#renderClass, Context<ClassTemplateData>(), 'class')
1619
@Renderer(#renderConstructor, Context<ConstructorTemplateData>(), 'constructor')
1720
@Renderer(#renderEnum, Context<EnumTemplateData>(), 'enum')
@@ -92,6 +95,7 @@ const _visibleTypes = {
9295
/// The collection of [Template] objects.
9396
abstract class Templates {
9497
String renderCategory(CategoryTemplateData context);
98+
String renderCategoryRedirect(CategoryTemplateData context);
9599
String renderClass<T extends Class>(ClassTemplateData context);
96100
String renderConstructor(ConstructorTemplateData context);
97101
String renderEnum(EnumTemplateData context);
@@ -141,6 +145,10 @@ class HtmlAotTemplates implements Templates {
141145
String renderCategory(CategoryTemplateData context) =>
142146
aot_renderers_for_html.renderCategory(context);
143147

148+
@override
149+
String renderCategoryRedirect(CategoryTemplateData context) =>
150+
aot_renderers_for_html.renderCategoryRedirect(context);
151+
144152
@override
145153
String renderClass<T extends Class>(ClassTemplateData context) =>
146154
aot_renderers_for_html.renderClass(context);
@@ -222,6 +230,10 @@ class RuntimeTemplates implements Templates {
222230
String renderCategory(CategoryTemplateData context) =>
223231
runtime_renderers.renderCategory(context, _categoryTemplate);
224232

233+
@override
234+
String renderCategoryRedirect(CategoryTemplateData context) =>
235+
runtime_renderers.renderCategoryRedirect(context, _categoryTemplate);
236+
225237
@override
226238
String renderClass<T extends Class>(ClassTemplateData context) =>
227239
runtime_renderers.renderClass(context, _classTemplate);

lib/src/generator/templates.runtime_renderers.dart

+80-4
Original file line numberDiff line numberDiff line change
@@ -1846,6 +1846,38 @@ class _Renderer_Category extends RendererBase<Category> {
18461846
);
18471847
},
18481848
),
1849+
'fileName': Property(
1850+
getValue: (CT_ c) => c.fileName,
1851+
renderVariable: (
1852+
CT_ c,
1853+
Property<CT_> self,
1854+
List<String> remainingNames,
1855+
) {
1856+
if (remainingNames.isEmpty) {
1857+
return self.getValue(c).toString();
1858+
}
1859+
var name = remainingNames.first;
1860+
var nextProperty = _Renderer_String.propertyMap().getValue(
1861+
name,
1862+
);
1863+
return nextProperty.renderVariable(
1864+
self.getValue(c) as String,
1865+
nextProperty,
1866+
[...remainingNames.skip(1)],
1867+
);
1868+
},
1869+
1870+
isNullValue: (CT_ c) => false,
1871+
1872+
renderValue: (
1873+
CT_ c,
1874+
RendererBase<CT_> r,
1875+
List<MustachioNode> ast,
1876+
StringSink sink,
1877+
) {
1878+
_render_String(c.fileName, ast, r.template, sink, parent: r);
1879+
},
1880+
),
18491881
'filePath': Property(
18501882
getValue: (CT_ c) => c.filePath,
18511883
renderVariable: (
@@ -2155,6 +2187,44 @@ class _Renderer_Category extends RendererBase<Category> {
21552187
);
21562188
},
21572189
),
2190+
'redirectFilePath': Property(
2191+
getValue: (CT_ c) => c.redirectFilePath,
2192+
renderVariable: (
2193+
CT_ c,
2194+
Property<CT_> self,
2195+
List<String> remainingNames,
2196+
) {
2197+
if (remainingNames.isEmpty) {
2198+
return self.getValue(c).toString();
2199+
}
2200+
var name = remainingNames.first;
2201+
var nextProperty = _Renderer_String.propertyMap().getValue(
2202+
name,
2203+
);
2204+
return nextProperty.renderVariable(
2205+
self.getValue(c) as String,
2206+
nextProperty,
2207+
[...remainingNames.skip(1)],
2208+
);
2209+
},
2210+
2211+
isNullValue: (CT_ c) => false,
2212+
2213+
renderValue: (
2214+
CT_ c,
2215+
RendererBase<CT_> r,
2216+
List<MustachioNode> ast,
2217+
StringSink sink,
2218+
) {
2219+
_render_String(
2220+
c.redirectFilePath,
2221+
ast,
2222+
r.template,
2223+
sink,
2224+
parent: r,
2225+
);
2226+
},
2227+
),
21582228
'referenceChildren': Property(
21592229
getValue: (CT_ c) => c.referenceChildren,
21602230
renderVariable:
@@ -2285,7 +2355,7 @@ class _Renderer_Category extends RendererBase<Category> {
22852355
}
22862356
}
22872357

2288-
String renderCategory(CategoryTemplateData context, Template template) {
2358+
String renderCategoryRedirect(CategoryTemplateData context, Template template) {
22892359
var buffer = StringBuffer();
22902360
_render_CategoryTemplateData(context, template.ast, template, buffer);
22912361
return buffer.toString();
@@ -2543,6 +2613,12 @@ class _Renderer_CategoryTemplateData
25432613
}
25442614
}
25452615

2616+
String renderCategory(CategoryTemplateData context, Template template) {
2617+
var buffer = StringBuffer();
2618+
_render_CategoryTemplateData(context, template.ast, template, buffer);
2619+
return buffer.toString();
2620+
}
2621+
25462622
void _render_Class(
25472623
Class context,
25482624
List<MustachioNode> ast,
@@ -19948,7 +20024,7 @@ class _Renderer_Package extends RendererBase<Package> {
1994820024
}
1994920025
}
1995020026

19951-
String renderIndex(PackageTemplateData context, Template template) {
20027+
String renderSearchPage(PackageTemplateData context, Template template) {
1995220028
var buffer = StringBuffer();
1995320029
_render_PackageTemplateData(context, template.ast, template, buffer);
1995420030
return buffer.toString();
@@ -20305,13 +20381,13 @@ class _Renderer_PackageTemplateData extends RendererBase<PackageTemplateData> {
2030520381
}
2030620382
}
2030720383

20308-
String renderError(PackageTemplateData context, Template template) {
20384+
String renderIndex(PackageTemplateData context, Template template) {
2030920385
var buffer = StringBuffer();
2031020386
_render_PackageTemplateData(context, template.ast, template, buffer);
2031120387
return buffer.toString();
2031220388
}
2031320389

20314-
String renderSearchPage(PackageTemplateData context, Template template) {
20390+
String renderError(PackageTemplateData context, Template template) {
2031520391
var buffer = StringBuffer();
2031620392
_render_PackageTemplateData(context, template.ast, template, buffer);
2031720393
return buffer.toString();

lib/src/model/category.dart

+8-2
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,17 @@ class Category
105105
late final bool isDocumented =
106106
documentedWhere != DocumentLocation.missing && documentationFile != null;
107107

108-
String get filePath {
108+
String get fileName {
109109
assert(_name != null);
110-
return 'topics/$_name-topic.html';
110+
return '$_name-topic.html';
111111
}
112112

113+
String get filePath => 'topics/$fileName';
114+
115+
/// Prior to dartdoc 8.3.4 the `displayName` was used in the file path
116+
/// for category pages. We now create a redirect file here instead.
117+
String get redirectFilePath => 'topics/$name-topic.html';
118+
113119
@override
114120
String? get href => isCanonical ? '${package.baseHref}$filePath' : null;
115121

lib/templates/category_redirect.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<link rel="canonical" href="{{ #useBaseHref }}{{ #htmlBase }}{{{ htmlBase }}}{{ /htmlBase }}{{ /useBaseHref }}{{ self.href }}" />
5+
<meta http-equiv="refresh" content="0; url={{ #useBaseHref }}{{ #htmlBase }}{{{ htmlBase }}}{{ /htmlBase }}{{ /useBaseHref }}{{ self.href }}" />
6+
</head>
7+
<body>
8+
<p><a href="{{ #useBaseHref }}{{ #htmlBase }}{{{ htmlBase }}}{{ /htmlBase }}{{ /useBaseHref }}{{ self.href }}">New URL</a></p>
9+
</body>
10+
</html>

test/end2end/model_test.dart

+5
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,11 @@ void main() async {
730730
});
731731
});
732732

733+
test('Verify redirectFilePath set', () {
734+
var category = packageGraph.publicPackages.first.categories.first;
735+
expect(category.redirectFilePath, 'topics/Superb-topic.html');
736+
});
737+
733738
group('LibraryContainer', () {
734739
late final TestLibraryContainer topLevel;
735740
var sortOrderBasic = ['theFirst', 'second', 'fruit'];

0 commit comments

Comments
 (0)