This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy under /_llms/. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation

RedirectContentService Pennington.Content

Holds the unified redirect map used by PenningtonRedirectMiddleware at dev time and by the static build crawler's 301 handling at publish time. The map is the union of two sources:

  • A _redirects.yml file at the top of ContentRootPath.
  • Every page whose front matter sets redirectUrl: (see IRedirectable). DiscoverAsync emits those as RedirectSource items; this service collects them by scanning registered IContentServices on first access.

Both sources flow through one middleware so dev and static build behave identically — a request to the redirect source URL returns HTTP 301 with a meta-refresh body, and OutputGenerationService writes that body to disk.

Properties

DefaultSectionLabel string
Default section label applied to discovered items that do not supply one via front matter.
SearchPriority int
Relative priority for ordering results in the search index (higher values rank first).

Constructors

RedirectContentService

#
public RedirectContentService(IServiceProvider serviceProvider, PenningtonOptions pennOptions, IFileSystem fileSystem, IFileWatcher fileWatcher)

Initializes the service and prepares lazy loading of the unified redirect map.

Parameters

serviceProvider IServiceProvider
pennOptions PenningtonOptions
fileSystem IFileSystem
fileWatcher IFileWatcher

Methods

DiscoverAsync

#
public IAsyncEnumerable<DiscoveredItem> DiscoverAsync()

Yields one DiscoveredItem per _redirects.yml entry so the static build crawler hits the source URL, gets the middleware's 301 response, and writes a meta-refresh HTML file at that path. Per-page redirects already appear via their owning content service's DiscoverAsync, so they are not re-emitted here.

Returns

IAsyncEnumerable<DiscoveredItem>

GetContentTocEntriesAsync

#
public Task<ImmutableList<ContentTocItem>> GetContentTocEntriesAsync()

Navigation entries for table of contents.

Returns

Task<ImmutableList<ContentTocItem>>

GetContentToCopyAsync

#
public Task<ImmutableList<ContentToCopy>> GetContentToCopyAsync()

Static files to copy to output (images, downloads, etc.)

Returns

Task<ImmutableList<ContentToCopy>>

GetCrossReferencesAsync

#
public Task<ImmutableList<CrossReference>> GetCrossReferencesAsync()

Cross-references for xref resolution.

Returns

Task<ImmutableList<CrossReference>>

GetRedirectMappingsAsync

#
public Task<ImmutableDictionary<string, string>> GetRedirectMappingsAsync()

Returns the merged source-URL → target-URL map (_redirects.yml entries plus front-matter redirects). First call is eager — it enumerates every registered content service's DiscoverAsync() to pick up RedirectSource items.

Returns

Task<ImmutableDictionary<string, string>>

Pennington.Content.RedirectContentService

namespace Pennington.Content;

/// Holds the unified redirect map used by PenningtonRedirectMiddleware at dev time and by the static build crawler's 301 handling at publish time. The map is the union of two sources: 
  • A _redirects.yml file at the top of ContentRootPath.
  • Every page whose front matter sets redirectUrl: (see IRedirectable). DiscoverAsync emits those as RedirectSource items; this service collects them by scanning registered IContentServices on first access.
Both sources flow through one middleware so dev and static build behave identically — a request to the redirect source URL returns HTTP 301 with a meta-refresh body, and OutputGenerationService writes that body to disk. public class RedirectContentService { /// Default section label applied to discovered items that do not supply one via front matter.
public string DefaultSectionLabel { get; }
/// Yields one DiscoveredItem per _redirects.yml entry so the static build crawler hits the source URL, gets the middleware's 301 response, and writes a meta-refresh HTML file at that path. Per-page redirects already appear via their owning content service's DiscoverAsync, so they are not re-emitted here.
public IAsyncEnumerable<DiscoveredItem> DiscoverAsync()
; /// Navigation entries for table of contents.
public Task<ImmutableList<ContentTocItem>> GetContentTocEntriesAsync()
; /// Static files to copy to output (images, downloads, etc.)
public Task<ImmutableList<ContentToCopy>> GetContentToCopyAsync()
; /// Cross-references for xref resolution.
public Task<ImmutableList<CrossReference>> GetCrossReferencesAsync()
; /// Returns the merged source-URL → target-URL map (_redirects.yml entries plus front-matter redirects). First call is eager — it enumerates every registered content service's DiscoverAsync() to pick up RedirectSource items.
public Task<ImmutableDictionary<string, string>> GetRedirectMappingsAsync()
; /// Initializes the service and prepares lazy loading of the unified redirect map.
public RedirectContentService(IServiceProvider serviceProvider, PenningtonOptions pennOptions, IFileSystem fileSystem, IFileWatcher fileWatcher)
; /// Relative priority for ordering results in the search index (higher values rank first).
public int SearchPriority { get; }
}