diff --git a/src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs b/src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs new file mode 100644 index 0000000000..c73685b41d --- /dev/null +++ b/src/Umbraco.Web.Common/DependencyInjection/StaticServiceProvider.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; + +namespace Umbraco.Cms.Web.Common.DependencyInjection +{ + /// + /// INTERNAL Service locator. Should only be used if no other ways exist. + /// + /// + /// It is created with only two goals in mind + /// 1) Continue to have the same extension methods on IPublishedContent and IPublishedElement as in V8. To make migration easier. + /// 2) To have a tool to avoid breaking changes in minor versions. All methods using this should in theory be obsolete. + /// + /// Keep in mind, every time this is used, the code becomes basically untestable. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class StaticServiceProvider + { + /// + /// The service locator. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static IServiceProvider Instance { get; set; } + } +} diff --git a/src/Umbraco.Web.Common/DependencyInjection/UmbracoStartupFilter.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoStartupFilter.cs index d843bfb4aa..f8ca73e283 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/UmbracoStartupFilter.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/UmbracoStartupFilter.cs @@ -19,6 +19,7 @@ namespace Umbraco.Cms.Web.Common.DependencyInjection public Action Configure(Action next) => app => { + StaticServiceProvider.Instance = app.ApplicationServices; _options.Value.PreUmbracoPipeline(app); app.UseUmbraco(); diff --git a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs new file mode 100644 index 0000000000..b9cdddfdeb --- /dev/null +++ b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs @@ -0,0 +1,537 @@ +using System; +using System.Collections.Generic; +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.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Web; +using Umbraco.Cms.Web.Common.DependencyInjection; + +namespace Umbraco.Extensions +{ + public static class FriendlyPublishedContentExtensions + { + private static IVariationContextAccessor VariationContextAccessor { 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 ISiteDomainHelper 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 IPublishedSnapshot PublishedSnapshot => UmbracoContextAccessor.UmbracoContext?.PublishedSnapshot; + + private static IMediaTypeService MediaTypeService { get; } = + StaticServiceProvider.Instance.GetRequiredService(); + + + private static IMemberTypeService MemberTypeService { get; } = + StaticServiceProvider.Instance.GetRequiredService(); + + + /// + /// 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, + 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); + + /// + /// 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) + => parentNodes.DescendantsOrSelfOfType(VariationContextAccessor, docTypeAlias, culture); + + /// + /// Returns all DescendantsOrSelf of all content referenced + /// + /// + /// Variation context accessor. + /// 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 + => parentNodes.DescendantsOrSelf(VariationContextAccessor, culture); + + public static IEnumerable Descendants(this IPublishedContent content, string culture = null) + => content.Descendants(VariationContextAccessor, culture); + + public static IEnumerable Descendants(this IPublishedContent content, int level, string culture = null) + => content.Descendants(VariationContextAccessor, level, culture); + + public static IEnumerable DescendantsOfType(this IPublishedContent content, + string contentTypeAlias, string culture = null) + => content.DescendantsOfType(VariationContextAccessor, contentTypeAlias, culture); + + public static IEnumerable Descendants(this IPublishedContent content, string culture = null) + where T : class, IPublishedContent + => content.Descendants(VariationContextAccessor, culture); + + public static IEnumerable Descendants(this IPublishedContent content, int level, string culture = null) + where T : class, IPublishedContent + => content.Descendants(VariationContextAccessor, level, culture); + + public static IEnumerable DescendantsOrSelf(this IPublishedContent content, string culture = null) + => content.DescendantsOrSelf(VariationContextAccessor, culture); + + + public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string culture = null) + => content.DescendantsOrSelf(VariationContextAccessor, level, culture); + + public static IEnumerable DescendantsOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string culture = null) + => content.DescendantsOrSelfOfType(VariationContextAccessor, contentTypeAlias, culture); + + public static IEnumerable DescendantsOrSelf(this IPublishedContent content, string culture = null) + where T : class, IPublishedContent + => content.DescendantsOrSelf(VariationContextAccessor, culture); + + public static IEnumerable DescendantsOrSelf(this IPublishedContent content, int level, string culture = null) + where T : class, IPublishedContent + => content.DescendantsOrSelf(VariationContextAccessor, level, culture); + + public static IPublishedContent Descendant(this IPublishedContent content, string culture = null) + => content.Descendant(VariationContextAccessor, culture); + + public static IPublishedContent Descendant(this IPublishedContent content, int level, string culture = null) + => content.Descendant(VariationContextAccessor, level, culture); + + + public static IPublishedContent DescendantOfType(this IPublishedContent content, string contentTypeAlias, string culture = null) + => content.DescendantOfType(VariationContextAccessor, contentTypeAlias, culture); + + public static T Descendant(this IPublishedContent content, string culture = null) + where T : class, IPublishedContent + => content.Descendant(VariationContextAccessor, culture); + + + public static T Descendant(this IPublishedContent content, int level, string culture = null) + where T : class, IPublishedContent + => content.Descendant(VariationContextAccessor, level, culture); + + public static IPublishedContent DescendantOrSelf(this IPublishedContent content, string culture = null) + => content.DescendantOrSelf(VariationContextAccessor, culture); + + public static IPublishedContent DescendantOrSelf(this IPublishedContent content, int level, string culture = null) + => content.DescendantOrSelf(VariationContextAccessor, level, culture); + + public static IPublishedContent DescendantOrSelfOfType(this IPublishedContent content, string contentTypeAlias, string culture = null) + => content.DescendantOrSelfOfType(VariationContextAccessor, contentTypeAlias, culture); + + public static T DescendantOrSelf(this IPublishedContent content, string culture = null) + where T : class, IPublishedContent + => content.DescendantOrSelf(VariationContextAccessor, culture); + + public static T DescendantOrSelf(this IPublishedContent content, int level, string culture = null) + where T : class, IPublishedContent + => content.DescendantOrSelf(VariationContextAccessor, 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(VariationContextAccessor, 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(VariationContextAccessor, 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(VariationContextAccessor, 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(VariationContextAccessor, culture); + + public static IPublishedContent FirstChild(this IPublishedContent content, string culture = null) + => content.FirstChild(VariationContextAccessor, 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(VariationContextAccessor, contentTypeAlias, culture); + + public static IPublishedContent FirstChild(this IPublishedContent content, Func predicate, string culture = null) + => content.FirstChild(VariationContextAccessor, predicate, culture); + + public static IPublishedContent FirstChild(this IPublishedContent content, Guid uniqueId, string culture = null) + => content.FirstChild(VariationContextAccessor, uniqueId, culture); + + + public static T FirstChild(this IPublishedContent content, string culture = null) + where T : class, IPublishedContent + => content.FirstChild(VariationContextAccessor, culture); + + public static T FirstChild(this IPublishedContent content, Func predicate, string culture = null) + where T : class, IPublishedContent + => content.FirstChild(VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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(PublishedSnapshot, VariationContextAccessor, 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. + /// Variation context accessor. + /// The content type service. + /// The media type service. + /// The member type service. + /// The published url provider. + /// 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. + public static DataTable ChildrenAsTable(this IPublishedContent content, string contentTypeAliasFilter = "", string culture = null) + => content.ChildrenAsTable(VariationContextAccessor, 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, 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); + + + } +} diff --git a/src/Umbraco.Web.Common/Extensions/FriendlyPublishedElementExtensions.cs b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedElementExtensions.cs new file mode 100644 index 0000000000..bbb896fe8b --- /dev/null +++ b/src/Umbraco.Web.Common/Extensions/FriendlyPublishedElementExtensions.cs @@ -0,0 +1,74 @@ +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Web.Common.DependencyInjection; + +namespace Umbraco.Extensions +{ + public static class FriendlyPublishedElementExtensions + { + private static IPublishedValueFallback PublishedValueFallback { get; } = + StaticServiceProvider.Instance.GetRequiredService(); + + /// + /// Gets the value of a content's property identified by its alias. + /// + /// 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. + /// + /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content. + /// If no property with the specified alias exists, or if the property has no value, returns . + /// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter. + /// The alias is case-insensitive. + /// + public static object Value( + this IPublishedElement 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. + /// + /// The value comes from IPublishedProperty field Value ie it is suitable for use when rendering content. + /// If no property with the specified alias exists, or if the property has no value, or if it could not be converted, returns default(T). + /// If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter. + /// The alias is case-insensitive. + /// + public static T Value( + this IPublishedElement content, + string alias, + string culture = null, + string segment = null, + Fallback fallback = default, + T defaultValue = default) + => content.Value(PublishedValueFallback, alias, culture, segment, fallback, defaultValue); + + /// + /// Gets a value indicating whether the content is visible. + /// + /// The content. + /// A value indicating whether the content is visible. + /// A content is not visible if it has an umbracoNaviHide property with a value of "1". Otherwise, + /// the content is visible. + public static bool IsVisible(this IPublishedElement content) => content.IsVisible(PublishedValueFallback); + + + } +} diff --git a/src/Umbraco.Web.Website/Extensions/PublishedContentExtensions.cs b/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs similarity index 99% rename from src/Umbraco.Web.Website/Extensions/PublishedContentExtensions.cs rename to src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs index c33d5e6ef3..c02e609372 100644 --- a/src/Umbraco.Web.Website/Extensions/PublishedContentExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; using System.Web; using Examine; using Microsoft.AspNetCore.Html; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Web; using Umbraco.Cms.Infrastructure.Examine; -using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Extensions { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js index 2e71ef0bf5..1a2f0735ce 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js @@ -25,7 +25,7 @@ "\t@foreach (var item in selection)\n" + "\t{\n" + "\t\t
  • \n" + - "\t\t\t@item.Name\n" + + "\t\t\t@item.Name()\n" + "\t\t
  • \n" + "\t}\n" + "\n\n"; @@ -43,11 +43,11 @@ function getAddSectionSnippet(sectionName) { return "@section " + sectionName + "\r\n{\r\n\r\n\t{0}\r\n\r\n}\r\n"; } - + function getGeneralShortcuts(){ var keys = [ - "shortcuts_generalHeader", - "buttons_undo", + "shortcuts_generalHeader", + "buttons_undo", "buttons_redo", "buttons_save" ]; @@ -61,7 +61,7 @@ labels.save = data[3]; return { - "name": labels.header, + "name": labels.header, "shortcuts": [ { "description": labels.undo, @@ -77,14 +77,14 @@ } ] }; - }); + }); } function getEditorShortcuts(){ var keys = [ - "shortcuts_editorHeader", - "shortcuts_commentLine", + "shortcuts_editorHeader", + "shortcuts_commentLine", "shortcuts_removeLine", "shortcuts_copyLineUp", "shortcuts_copyLineDown", @@ -126,7 +126,7 @@ "keys": { "win": [{ "key": "alt" }, { "key": "shift" }, { "key": "down" }], "mac": [{ "key": "cmd" }, { "key": "alt" }, { "key": "down" }] - } + } }, { "description": labels.movelineup, @@ -138,13 +138,13 @@ } ] }; - }); + }); } function getTemplateEditorShortcuts(){ var keys = [ - "template_insert", - "template_insertPageField", + "template_insert", + "template_insertPageField", "template_insertPartialView", "template_insertDictionaryItem", "template_insertMacro", @@ -198,13 +198,13 @@ } ] }; - }); + }); } function getPartialViewEditorShortcuts(){ var keys = [ - "template_insert", - "template_insertPageField", + "template_insert", + "template_insertPageField", "template_insertDictionaryItem", "template_insertMacro", "template_queryBuilder" @@ -242,7 +242,7 @@ }; }); - + } //////////// diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js index 08a69b7e80..316cfa7c59 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/template-helper.spec.js @@ -50,7 +50,7 @@ describe('service: templateHelper', function () { var snippet = '@Html.Partial("Folder with spaces/Footer")'; expect(templateHelper.getInsertPartialSnippet(parentId, nodeName)).toBe(snippet); }); - + }); describe('getQuerySnippet', function () { @@ -62,14 +62,14 @@ describe('service: templateHelper', function () { "\t@foreach (var item in selection)\n" + "\t{\n" + "\t\t
  • \n" + - "\t\t\t@item.Name\n" + + "\t\t\t@item.Name()\n" + "\t\t
  • \n" + "\t}\n" + "\n\n"; expect(templateHelper.getQuerySnippet(queryExpression)).toBe(snippet); }); - + }); describe('getRenderBodySnippet', function () { @@ -78,7 +78,7 @@ describe('service: templateHelper', function () { var snippet = '@RenderBody()'; expect(templateHelper.getRenderBodySnippet()).toBe(snippet); }); - + }); describe('getRenderSectionSnippet', function () { @@ -92,7 +92,7 @@ describe('service: templateHelper', function () { var snippet = '@RenderSection("sectionName", true)'; expect(templateHelper.getRenderSectionSnippet("sectionName", true)).toBe(snippet); }); - + }); describe('getAddSectionSnippet', function () { @@ -102,7 +102,7 @@ describe('service: templateHelper', function () { var snippet = "@section " + sectionName + "\r\n{\r\n\r\n\t{0}\r\n\r\n}\r\n"; expect(templateHelper.getAddSectionSnippet(sectionName)).toEqual(snippet); }); - + }); -}); \ No newline at end of file +});