using System.Data; using Examine; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Services.Navigation; using Umbraco.Cms.Core.Web; namespace Umbraco.Extensions; public static class FriendlyPublishedContentExtensions { private static IVariationContextAccessor VariationContextAccessor { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IDomainCache DomainCache { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IPublishedContentCache PublishedContentCache { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IDocumentNavigationQueryService DocumentNavigationQueryService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IMediaNavigationQueryService MediaNavigationQueryService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IPublishedModelFactory PublishedModelFactory { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IPublishedUrlProvider PublishedUrlProvider { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IUserService UserService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IUmbracoContextAccessor UmbracoContextAccessor { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static ISiteDomainMapper SiteDomainHelper { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IExamineManager ExamineManager { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IFileService FileService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IOptions WebRoutingSettings { get; } = StaticServiceProvider.Instance.GetRequiredService>(); private static IContentTypeService ContentTypeService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IPublishedValueFallback PublishedValueFallback { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IMediaTypeService MediaTypeService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static IMemberTypeService MemberTypeService { get; } = StaticServiceProvider.Instance.GetRequiredService(); private static INavigationQueryService GetNavigationQueryService(IPublishedContent content) { switch (content.ContentType.ItemType) { case PublishedItemType.Content: return DocumentNavigationQueryService; case PublishedItemType.Media: return MediaNavigationQueryService; default: throw new NotSupportedException("Unsupported content type."); } } private static IPublishedStatusFilteringService GetPublishedStatusFilteringService(IPublishedContent content) { switch (content.ContentType.ItemType) { case PublishedItemType.Content: return StaticServiceProvider.Instance.GetRequiredService(); case PublishedItemType.Media: return StaticServiceProvider.Instance.GetRequiredService(); default: throw new NotSupportedException("Unsupported content type."); } } /// /// Creates a strongly typed published content model for an internal published content. /// /// The internal published content. /// The strongly typed published content model. public static IPublishedContent? CreateModel( this IPublishedContent content) => content.CreateModel(PublishedModelFactory); /// /// Gets the name of the content item. /// /// The content item. /// /// The specific culture to get the name for. If null is used the current culture is used (Default is /// null). /// public static string? Name( this IPublishedContent content, string? culture = null) => content.Name(VariationContextAccessor, culture); /// /// Gets the URL segment of the content item. /// /// The content item. /// /// The specific culture to get the URL segment for. If null is used the current culture is used /// (Default is null). /// public static string? UrlSegment( this IPublishedContent content, string? culture = null) => content.UrlSegment(VariationContextAccessor, culture); /// /// Gets the culture date of the content item. /// /// The content item. /// /// The specific culture to get the name for. If null is used the current culture is used (Default is /// null). /// public static DateTime CultureDate( this IPublishedContent content, string? culture = null) => content.CultureDate(VariationContextAccessor, culture); /// /// Returns the current template Alias /// /// Empty string if none is set. public static string GetTemplateAlias(this IPublishedContent content) => content.GetTemplateAlias(FileService); public static bool IsAllowedTemplate(this IPublishedContent content, int templateId) => content.IsAllowedTemplate(ContentTypeService, WebRoutingSettings.Value, templateId); public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) => content.IsAllowedTemplate( WebRoutingSettings.Value.DisableAlternativeTemplates, WebRoutingSettings.Value.ValidateAlternativeTemplates, templateAlias); public static bool IsAllowedTemplate( this IPublishedContent content, bool disableAlternativeTemplates, bool validateAlternativeTemplates, int templateId) => content.IsAllowedTemplate( ContentTypeService, disableAlternativeTemplates, validateAlternativeTemplates, templateId); public static bool IsAllowedTemplate( this IPublishedContent content, bool disableAlternativeTemplates, bool validateAlternativeTemplates, string templateAlias) => content.IsAllowedTemplate( FileService, ContentTypeService, disableAlternativeTemplates, validateAlternativeTemplates, templateAlias); /// /// Gets a value indicating whether the content has a value for a property identified by its alias. /// /// The content. /// The property alias. /// The variation language. /// The variation segment. /// Optional fallback strategy. /// A value indicating whether the content has a value for the property identified by the alias. /// Returns true if HasValue is true, or a fallback strategy can provide a value. public static bool HasValue( this IPublishedContent content, string alias, string? culture = null, string? segment = null, Fallback fallback = default) => content.HasValue(PublishedValueFallback, alias, culture, segment, fallback); /// /// Gets the value of a content's property identified by its alias, if it exists, otherwise a default value. /// /// The content. /// The property alias. /// The variation language. /// The variation segment. /// Optional fallback strategy. /// The default value. /// The value of the content's property identified by the alias, if it exists, otherwise a default value. public static object? Value(this IPublishedContent content, string alias, string? culture = null, string? segment = null, Fallback fallback = default, object? defaultValue = default) => content.Value(PublishedValueFallback, alias, culture, segment, fallback, defaultValue); /// /// Gets the value of a content's property identified by its alias, converted to a specified type. /// /// The target property type. /// The content. /// The property alias. /// The variation language. /// The variation segment. /// Optional fallback strategy. /// The default value. /// The value of the content's property identified by the alias, converted to the specified type. public static T? Value(this IPublishedContent content, string alias, string? culture = null, string? segment = null, Fallback fallback = default, T? defaultValue = default) => content.Value(PublishedValueFallback, alias, culture, segment, fallback, defaultValue); /// /// Gets the root content (ancestor or self at level 1) for the specified . /// /// The content. /// /// The root content (ancestor or self at level 1) for the specified . /// /// /// This is the same as calling /// with maxLevel /// set to 1. /// public static IPublishedContent Root(this IPublishedContent content) => content.Root(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the root content (ancestor or self at level 1) for the specified if it's of the /// specified content type . /// /// The content type. /// The content. /// /// The root content (ancestor or self at level 1) for the specified of content type /// . /// /// /// This is the same as calling /// with /// maxLevel set to 1. /// public static T? Root(this IPublishedContent content) where T : class, IPublishedContent => content.Root(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the parent of the content item. /// /// The content. /// The content type. /// The parent of content of the specified content type or null. public static T? Parent(this IPublishedContent content) where T : class, IPublishedContent => content.Parent(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the parent of the content item. /// /// The content. /// The parent of content or null. public static IPublishedContent? Parent(this IPublishedContent content) => content.Parent(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the ancestors of the content. /// /// The content. /// The ancestors of the content, in down-top order. /// Does not consider the content itself. public static IEnumerable Ancestors(this IPublishedContent content) => content.Ancestors(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the content and its ancestors. /// /// The content. /// The content and its ancestors, in down-top order. public static IEnumerable AncestorsOrSelf(this IPublishedContent content) => content.AncestorsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the content and its ancestors, of a specified content type. /// /// The content type. /// The content. /// The content and its ancestors, of the specified content type, in down-top order. /// May or may not begin with the content itself, depending on its content type. public static IEnumerable AncestorsOrSelf(this IPublishedContent content) where T : class, IPublishedContent => content.AncestorsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the ancestor of the content, i.e. its parent. /// /// The content. /// The ancestor of the content. public static IPublishedContent? Ancestor(this IPublishedContent content) => content.Ancestor(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the nearest ancestor of the content, of a specified content type. /// /// The content type. /// The content. /// The nearest (in down-top order) ancestor of the content, of the specified content type. /// Does not consider the content itself. May return null. public static T? Ancestor(this IPublishedContent content) where T : class, IPublishedContent => content.Ancestor(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Gets the content or its nearest ancestor, of a specified content type. /// /// The content type. /// The content. /// The content or its nearest (in down-top order) ancestor, of the specified content type. /// May or may not return the content itself depending on its content type. May return null. public static T? AncestorOrSelf(this IPublishedContent content) where T : class, IPublishedContent => content.AncestorOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content)); /// /// Returns all DescendantsOrSelf of all content referenced /// /// /// /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// /// /// This can be useful in order to return all nodes in an entire site by a type when combined with TypedContentAtRoot /// public static IEnumerable DescendantsOrSelfOfType( this IEnumerable parentNodes, string docTypeAlias, string? culture = null) { IPublishedContent[] parentNodesAsArray = parentNodes as IPublishedContent[] ?? parentNodes.ToArray(); if (parentNodesAsArray.Length == 0) { return []; } return parentNodesAsArray.DescendantsOrSelfOfType( GetNavigationQueryService(parentNodesAsArray.First()), GetPublishedStatusFilteringService(parentNodesAsArray.First()), docTypeAlias, culture); } /// /// Returns all DescendantsOrSelf of all content referenced /// /// /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// /// /// This can be useful in order to return all nodes in an entire site by a type when combined with TypedContentAtRoot /// public static IEnumerable DescendantsOrSelf( this IEnumerable parentNodes, string? culture = null) where T : class, IPublishedContent { IPublishedContent[] parentNodesAsArray = parentNodes as IPublishedContent[] ?? parentNodes.ToArray(); if (parentNodesAsArray.Length == 0) { return []; } return parentNodesAsArray.DescendantsOrSelf( GetNavigationQueryService(parentNodesAsArray.First()), GetPublishedStatusFilteringService(parentNodesAsArray.First()), culture); } public static IEnumerable Descendants(this IPublishedContent content, string? culture = null) => content.Descendants(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IEnumerable Descendants(this IPublishedContent content, int level, string? culture = null) => content.Descendants(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IEnumerable DescendantsOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.DescendantsOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); public static IEnumerable Descendants(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.Descendants(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IEnumerable Descendants(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent => content.Descendants(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IEnumerable DescendantsOrSelf( this IPublishedContent content, string? culture = null) => content.DescendantsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string? culture = null) => content.DescendantsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IEnumerable DescendantsOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.DescendantsOrSelfOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.DescendantsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent => content.DescendantsOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IPublishedContent? Descendant(this IPublishedContent content, string? culture = null) => content.Descendant(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IPublishedContent? Descendant(this IPublishedContent content, int level, string? culture = null) => content.Descendant(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IPublishedContent? DescendantOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.DescendantOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); public static T? Descendant(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.Descendant(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static T? Descendant(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent => content.Descendant(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IPublishedContent DescendantOrSelf(this IPublishedContent content, string? culture = null) => content.DescendantOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IPublishedContent? DescendantOrSelf(this IPublishedContent content, int level, string? culture = null) => content.DescendantOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); public static IPublishedContent? DescendantOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.DescendantOrSelfOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); public static T? DescendantOrSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.DescendantOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static T? DescendantOrSelf(this IPublishedContent content, int level, string? culture = null) where T : class, IPublishedContent => content.DescendantOrSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), level, culture); /// /// Gets the children of the content item. /// /// The content item. /// /// The specific culture to get the URL children for. Default is null which will use the current culture in /// /// /// /// Gets children that are available for the specified culture. /// Children are sorted by their sortOrder. /// /// For culture, /// if null is used the current culture is used. /// If an empty string is used only invariant children are returned. /// If "*" is used all children are returned. /// /// /// If a variant culture is specified or there is a current culture in the then the /// Children returned /// will include both the variant children matching the culture AND the invariant children because the invariant /// children flow with the current culture. /// However, if an empty string is specified only invariant children are returned. /// /// public static IEnumerable Children(this IPublishedContent content, string? culture = null) => content.Children(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the children of the content, filtered by a predicate. /// /// The content. /// The predicate. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The children of the content, filtered by the predicate. /// /// Children are sorted by their sortOrder. /// public static IEnumerable? Children( this IPublishedContent content, Func predicate, string? culture = null) => content.Children(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), predicate, culture); /// /// Gets the children of the content, of any of the specified types. /// /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The content type alias. /// The children of the content, of any of the specified types. public static IEnumerable? ChildrenOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.ChildrenOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); /// /// Gets the children of the content, of a given content type. /// /// The content type. /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The children of content, of the given content type. /// /// Children are sorted by their sortOrder. /// public static IEnumerable? Children(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.Children(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static IPublishedContent? FirstChild(this IPublishedContent content, string? culture = null) => content.FirstChild(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the first child of the content, of a given content type. /// public static IPublishedContent? FirstChildOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.FirstChildOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); public static IPublishedContent? FirstChild(this IPublishedContent content, Func predicate, string? culture = null) => content.FirstChild(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), predicate, culture); public static IPublishedContent? FirstChild(this IPublishedContent content, Guid uniqueId, string? culture = null) => content.FirstChild(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), uniqueId, culture); public static T? FirstChild(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.FirstChild(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); public static T? FirstChild(this IPublishedContent content, Func predicate, string? culture = null) where T : class, IPublishedContent => content.FirstChild(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), predicate, culture); /// /// Gets the siblings of the content. /// /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The siblings of the content. /// /// Note that in V7 this method also return the content node self. /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) => content.Siblings(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the siblings of the content, of a given content type. /// /// The content. /// The content type alias. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The siblings of the content, of the given content type. /// /// Note that in V7 this method also return the content node self. /// public static IEnumerable? SiblingsOfType(this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.SiblingsOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); /// /// Gets the siblings of the content, of a given content type. /// /// The content type. /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The siblings of the content, of the given content type. /// /// Note that in V7 this method also return the content node self. /// public static IEnumerable? Siblings(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.Siblings(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the siblings of the content including the node itself to indicate the position. /// /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The siblings of the content including the node itself. public static IEnumerable? SiblingsAndSelf( this IPublishedContent content, string? culture = null) => content.SiblingsAndSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. /// /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The content type alias. /// The siblings of the content including the node itself, of the given content type. public static IEnumerable? SiblingsAndSelfOfType( this IPublishedContent content, string contentTypeAlias, string? culture = null) => content.SiblingsAndSelfOfType(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), contentTypeAlias, culture); /// /// Gets the siblings of the content including the node itself to indicate the position, of a given content type. /// /// The content type. /// The content. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The siblings of the content including the node itself, of the given content type. public static IEnumerable? SiblingsAndSelf(this IPublishedContent content, string? culture = null) where T : class, IPublishedContent => content.SiblingsAndSelf(GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), culture); /// /// Gets the url of the content item. /// /// /// /// If the content item is a document, then this method returns the url of the /// document. If it is a media, then this methods return the media url for the /// 'umbracoFile' property. Use the MediaUrl() method to get the media url for other /// properties. /// /// /// The value of this property is contextual. It depends on the 'current' request uri, /// if any. In addition, when the content type is multi-lingual, this is the url for the /// specified culture. Otherwise, it is the invariant url. /// /// public static string Url(this IPublishedContent content, string? culture = null, UrlMode mode = UrlMode.Default) => content.Url(PublishedUrlProvider, culture, mode); /// /// Gets the children of the content in a DataTable. /// /// The content. /// An optional content type alias. /// /// The specific culture to filter for. If null is used the current culture is used. (Default is /// null) /// /// The children of the content. [Obsolete("This method is no longer used in Umbraco. The method will be removed in Umbraco 17.")] public static DataTable ChildrenAsTable(this IPublishedContent content, string contentTypeAliasFilter = "", string? culture = null) => content.ChildrenAsTable( GetNavigationQueryService(content), GetPublishedStatusFilteringService(content), ContentTypeService, MediaTypeService, MemberTypeService, PublishedUrlProvider, contentTypeAliasFilter, culture); /// /// Gets the url for a media. /// /// The content item. /// The culture (use current culture by default). /// The url mode (use site configuration by default). /// The alias of the property (use 'umbracoFile' by default). /// The url for the media. /// /// /// The value of this property is contextual. It depends on the 'current' request uri, /// if any. In addition, when the content type is multi-lingual, this is the url for the /// specified culture. Otherwise, it is the invariant url. /// /// public static string MediaUrl( this IPublishedContent content, string? culture = null, UrlMode mode = UrlMode.Default, string propertyAlias = Constants.Conventions.Media.File) => content.MediaUrl(PublishedUrlProvider, culture, mode, propertyAlias); /// /// Gets the name of the content item creator. /// /// The content item. public static string? CreatorName(this IPublishedContent content) => content.CreatorName(UserService); /// /// Gets the name of the content item writer. /// /// The content item. public static string? WriterName(this IPublishedContent content) => content.WriterName(UserService); /// /// Gets the culture assigned to a document by domains, in the context of a current Uri. /// /// The document. /// An optional current Uri. /// The culture assigned to the document by domains. /// /// /// In 1:1 multilingual setup, a document contains several cultures (there is not /// one document per culture), and domains, withing the context of a current Uri, assign /// a culture to that document. /// /// public static string? GetCultureFromDomains( this IPublishedContent content, Uri? current = null) => content.GetCultureFromDomains(UmbracoContextAccessor, SiteDomainHelper, DomainCache, PublishedContentCache, DocumentNavigationQueryService, current); public static IEnumerable SearchDescendants( this IPublishedContent content, string term, string? indexName = null) => content.SearchDescendants(ExamineManager, UmbracoContextAccessor, term, indexName); public static IEnumerable SearchChildren( this IPublishedContent content, string term, string? indexName = null) => content.SearchChildren(ExamineManager, UmbracoContextAccessor, term, indexName); }