Skip to content

Commit 9c673fe

Browse files
committed
Ensures feed title and description fallback to the site title and description if a feed-specific one was not provided (#1012)
1 parent 1be9ede commit 9c673fe

File tree

4 files changed

+117
-5
lines changed

4 files changed

+117
-5
lines changed

RELEASE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 1.0.0-beta.58
2+
3+
- Ensures feed title and description fallback to the site title and description if a feed-specific one was not provided (#1012).
4+
- Updated Statiq Framework reference to version [1.0.0-beta.70](https://github.com/statiqdev/Statiq.Framework/releases/tag/v1.0.0-beta.70).
5+
16
# 1.0.0-beta.57
27

38
- Updated Statiq Framework reference to version [1.0.0-beta.69](https://github.com/statiqdev/Statiq.Framework/releases/tag/v1.0.0-beta.69).

src/Statiq.Web/Pipelines/Feeds.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,45 @@ public Feeds()
6565
.WithAtomPath(TryGetFeedPath(feedDoc, WebKeys.FeedAtom, "atom", out feedPath) ? feedPath : null)
6666
.WithRdfPath(TryGetFeedPath(feedDoc, WebKeys.FeedRdf, "rdf", out feedPath) ? feedPath : null)
6767
.WithFeedId(feedDoc.GetString(WebKeys.FeedId))
68-
.WithFeedTitle(feedDoc.GetString(WebKeys.FeedTitle))
69-
.WithFeedDescription(feedDoc.GetString(WebKeys.FeedDescription))
7068
.WithFeedAuthor(feedDoc.GetString(WebKeys.FeedAuthor))
7169
.WithFeedPublished(feedDoc.ContainsKey(WebKeys.FeedPublished) ? feedDoc.GetDateTime(WebKeys.FeedPublished) : (DateTime?)null)
7270
.WithFeedUpdated(feedDoc.ContainsKey(WebKeys.FeedUpdated) ? feedDoc.GetDateTime(WebKeys.FeedUpdated) : (DateTime?)null)
7371
.WithFeedLink(feedDoc.Get<Uri>(WebKeys.FeedLink))
7472
.WithFeedImageLink(feedDoc.Get<Uri>(WebKeys.FeedImageLink))
7573
.WithFeedCopyright(feedDoc.GetString(WebKeys.Copyright));
7674

75+
// Set the title to FeedTitle first, then Title, then SiteTitle
76+
string feedTitle = null;
77+
if (feedDoc.ContainsKey(WebKeys.FeedTitle))
78+
{
79+
feedTitle = feedDoc.GetString(WebKeys.FeedTitle);
80+
}
81+
if (feedTitle.IsNullOrWhiteSpace() && feedDoc.ContainsKey(WebKeys.Title))
82+
{
83+
feedTitle = feedDoc.GetString(WebKeys.Title);
84+
}
85+
if (feedTitle.IsNullOrWhiteSpace() && feedDoc.ContainsKey(WebKeys.SiteTitle))
86+
{
87+
feedTitle = feedDoc.GetString(WebKeys.SiteTitle);
88+
}
89+
generateFeeds = generateFeeds.WithFeedTitle(feedTitle);
90+
91+
// Set the description to FeedDescription first, then Description, then SiteDescription
92+
string feedDescription = null;
93+
if (feedDoc.ContainsKey(WebKeys.FeedDescription))
94+
{
95+
feedDescription = feedDoc.GetString(WebKeys.FeedDescription);
96+
}
97+
if (feedDescription.IsNullOrWhiteSpace() && feedDoc.ContainsKey(WebKeys.Description))
98+
{
99+
feedDescription = feedDoc.GetString(WebKeys.Description);
100+
}
101+
if (feedDescription.IsNullOrWhiteSpace() && feedDoc.ContainsKey(WebKeys.SiteDescription))
102+
{
103+
feedDescription = feedDoc.GetString(WebKeys.SiteDescription);
104+
}
105+
generateFeeds = generateFeeds.WithFeedDescription(feedDescription);
106+
77107
// Set the per-item delegates (these would have been copied down to each document from the feed document in the MergeMetadata up above)
78108
if (feedDoc.ContainsKey(WebKeys.FeedItemId))
79109
{
@@ -154,4 +184,4 @@ private static bool TryGetFeedPath(IDocument feedDoc, string key, string default
154184
return false;
155185
}
156186
}
157-
}
187+
}

src/Statiq.Web/WebKeys.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ public static class WebKeys
88
{
99
////////// Global
1010

11+
/// <summary>
12+
/// The title of the site, often used by themes.
13+
/// </summary>
14+
public const string SiteTitle = nameof(SiteTitle);
15+
16+
/// <summary>
17+
/// The description of the site, often used by themes.
18+
/// </summary>
19+
public const string SiteDescription = nameof(SiteDescription);
20+
1121
/// <summary>
1222
/// The globbing pattern(s) used to read input files.
1323
/// </summary>
@@ -559,9 +569,9 @@ public static class WebKeys
559569

560570
public const string FeedId = nameof(FeedId); // A Uri, links to the root of the site by default
561571

562-
public const string FeedTitle = nameof(FeedTitle); // Defaults to WebKeys.Title
572+
public const string FeedTitle = nameof(FeedTitle); // If not specified, defaults to "Title" and then "SiteTitle"
563573

564-
public const string FeedDescription = nameof(FeedDescription); // Defaults to WebKeys.Description
574+
public const string FeedDescription = nameof(FeedDescription); // If not specified, defaults to "Description" and then "SiteDescription"
565575

566576
public const string FeedAuthor = nameof(FeedAuthor); // Defaults to WebKeys.Author
567577

tests/Statiq.Web.Tests/Pipelines/FeedsFixture.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,73 @@ public async Task ToggleFeedWithPath()
8686
IDocument document = result.Outputs[nameof(Web.Pipelines.Feeds)][Phase.Process].ShouldHaveSingleItem();
8787
document.Destination.ShouldBe("rss/custom-feed.xml");
8888
}
89+
90+
[TestCase("a", "b", "c", "a")]
91+
[TestCase(null, "b", "c", "b")]
92+
[TestCase(null, null, "c", "c")]
93+
[TestCase(null, null, null, "Feed")]
94+
public async Task ShouldSetCorrectFeedTitle(
95+
string feedTitle, string title, string siteTitle, string expected)
96+
{
97+
// Given
98+
App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateWeb(Array.Empty<string>());
99+
if (siteTitle is object)
100+
{
101+
bootstrapper.AddSetting(WebKeys.SiteTitle, siteTitle);
102+
}
103+
TestFileProvider fileProvider = new TestFileProvider
104+
{
105+
{ "/input/foo.md", "Hi!" },
106+
{
107+
"/input/feed.yml",
108+
@"FeedItemId: => ""Bar""
109+
FeedRss: true" + (feedTitle is null ? string.Empty : $@"
110+
FeedTitle: {feedTitle}") + (title is null ? string.Empty : $@"
111+
Title: {title}")
112+
}
113+
};
114+
115+
// When
116+
BootstrapperTestResult result = await bootstrapper.RunTestAsync(fileProvider);
117+
118+
// Then
119+
result.ExitCode.ShouldBe((int)ExitCode.Normal);
120+
IDocument document = result.Outputs[nameof(Web.Pipelines.Feeds)][Phase.Process].ShouldHaveSingleItem();
121+
(await document.GetContentStringAsync()).ShouldContain($"<title>{expected}</title>");
122+
}
123+
124+
[TestCase("a", "b", "c", "a")]
125+
[TestCase(null, "b", "c", "b")]
126+
[TestCase(null, null, "c", "c")]
127+
public async Task ShouldSetCorrectFeedDescription(
128+
string feedDescription, string description, string siteDescription, string expected)
129+
{
130+
// Given
131+
App.Bootstrapper bootstrapper = App.Bootstrapper.Factory.CreateWeb(Array.Empty<string>());
132+
if (siteDescription is object)
133+
{
134+
bootstrapper.AddSetting(WebKeys.SiteDescription, siteDescription);
135+
}
136+
TestFileProvider fileProvider = new TestFileProvider
137+
{
138+
{ "/input/foo.md", "Hi!" },
139+
{
140+
"/input/feed.yml",
141+
@"FeedItemId: => ""Bar""
142+
FeedRss: true" + (feedDescription is null ? string.Empty : $@"
143+
FeedDescription: {feedDescription}") + (description is null ? string.Empty : $@"
144+
Description: {description}")
145+
}
146+
};
147+
148+
// When
149+
BootstrapperTestResult result = await bootstrapper.RunTestAsync(fileProvider);
150+
151+
// Then
152+
result.ExitCode.ShouldBe((int)ExitCode.Normal);
153+
IDocument document = result.Outputs[nameof(Web.Pipelines.Feeds)][Phase.Process].ShouldHaveSingleItem();
154+
(await document.GetContentStringAsync()).ShouldContain($"<description>{expected}</description>");
155+
}
89156
}
90157
}
91158
}

0 commit comments

Comments
 (0)