public IEnumerable <DataListItem> GetItems(Dictionary <string, object> config) { var xpath = config.GetValueAs("xpath", string.Empty); if (string.IsNullOrWhiteSpace(xpath) == false) { var umbracoContext = _accessor.UmbracoContext; var nodeContextId = int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("id"), out var currentId) ? currentId : default(int?); IEnumerable <string> getPath(int id) => umbracoContext.Content.GetById(id).Path.ToDelimitedList().Reverse(); bool publishedContentExists(int id) => umbracoContext.Content.GetById(id) != null; var parsed = UmbracoXPathPathSyntaxParser.ParseXPathQuery(xpath, nodeContextId, getPath, publishedContentExists); if (string.IsNullOrWhiteSpace(parsed) == false) { return(umbracoContext .Content .GetByXPath(parsed) .Select(x => new DataListItem { Name = x.Name, Value = Udi.Create(UmbConstants.UdiEntityType.Document, x.Key).ToString(), Icon = UmbConstants.Icons.Content, Description = x.Url })); } } return(Enumerable.Empty <DataListItem>()); }
/// <summary> /// Returns the content id based on the configured ContentErrorPage section. /// </summary> internal static int?GetContentIdFromErrorPageConfig( ContentErrorPage errorPage, IEntityService entityService, IPublishedContentQuery publishedContentQuery, int?domainContentId) { if (errorPage.HasContentId) { return(errorPage.ContentId); } if (errorPage.HasContentKey) { // need to get the Id for the GUID // TODO: When we start storing GUIDs into the IPublishedContent, then we won't have to look this up // but until then we need to look it up in the db. For now we've implemented a cached service for // converting Int -> Guid and vice versa. Attempt <int> found = entityService.GetId(errorPage.ContentKey, UmbracoObjectTypes.Document); if (found) { return(found.Result); } return(null); } if (errorPage.ContentXPath.IsNullOrWhiteSpace() == false) { try { // we have an xpath statement to execute var xpathResult = UmbracoXPathPathSyntaxParser.ParseXPathQuery( xpathExpression: errorPage.ContentXPath, nodeContextId: domainContentId, getPath: nodeid => { IEntitySlim ent = entityService.Get(nodeid); return(ent.Path.Split(',').Reverse()); }, publishedContentExists: i => publishedContentQuery.Content(i) != null); // now we'll try to execute the expression IPublishedContent nodeResult = publishedContentQuery.ContentSingleAtXPath(xpathResult); if (nodeResult != null) { return(nodeResult.Id); } } catch (Exception ex) { StaticApplicationLogging.Logger.LogError(ex, "Could not parse xpath expression: {ContentXPath}", errorPage.ContentXPath); return(null); } } return(null); }
// PP: Work in progress on the query parser private string ParseXPathQuery(string query, int id) { return(UmbracoXPathPathSyntaxParser.ParseXPathQuery( xpathExpression: query, nodeContextId: id, getPath: nodeid => { var ent = Services.EntityService.Get(nodeid); return ent.Path.Split(',').Reverse(); }, publishedContentExists: i => Umbraco.Content(i) != null)); }
public IEnumerable <DataListItem> GetItems(Dictionary <string, object> config) { var preview = true; var parentNode = config.GetValueAs("parentNode", string.Empty); var startNode = default(IPublishedContent); if (parentNode.InvariantStartsWith("umb://document/") == false) { var nodeContextId = default(int?); var umbracoContext = _umbracoContextAccessor.UmbracoContext; // NOTE: First we check for "id" (if on a content page), then "parentId" (if editing an element). if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("id"), out var currentId) == true) { nodeContextId = currentId; } else if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("parentId"), out var parentId) == true) { nodeContextId = parentId; } if (nodeContextId == -20) { // TODO: [UP-FOR-GRABS] If the ID = -20, then we can assume that it's come from Nested Content. What to do? ¯\_(ツ)_/¯ } IEnumerable <string> getPath(int id) => umbracoContext.Content.GetById(preview, id)?.Path.ToDelimitedList().Reverse(); bool publishedContentExists(int id) => umbracoContext.Content.GetById(preview, id) != null; var parsed = UmbracoXPathPathSyntaxParser.ParseXPathQuery(parentNode, nodeContextId, getPath, publishedContentExists); if (string.IsNullOrWhiteSpace(parsed) == false && parsed.StartsWith("$") == false) { startNode = umbracoContext.Content.GetSingleByXPath(preview, parsed); } } else if (GuidUdi.TryParse(parentNode, out var udi) == true && udi.Guid != Guid.Empty) { startNode = _umbracoContextAccessor.UmbracoContext.Content.GetById(preview, udi.Guid); } if (startNode != null) { return(startNode.Children.Select(x => new DataListItem { // TODO: [LK:2020-12-03] If multi-lingual is enabled, should the `.Name` take the culture into account? Name = x.Name, Value = Udi.Create(UmbConstants.UdiEntityType.Document, x.Key).ToString(), Icon = ContentTypeCacheHelper.TryGetIcon(x.ContentType.Alias, out var icon, _contentTypeService) == true ? icon : UmbConstants.Icons.Content, Description = x.TemplateId > 0 ? x.Url() : string.Empty, Disabled = x.IsPublished() == false, }));
public IEnumerable <DataListItem> GetItems(Dictionary <string, object> config) { var xpath = config.GetValueAs("xpath", string.Empty); if (string.IsNullOrWhiteSpace(xpath) == false) { var nodeContextId = default(int?); var preview = true; var umbracoContext = _umbracoContextAccessor.UmbracoContext; // NOTE: First we check for "id" (if on a content page), then "parentId" (if editing an element). if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("id"), out var currentId) == true) { nodeContextId = currentId; } else if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("parentId"), out var parentId) == true) { nodeContextId = parentId; } IEnumerable <string> getPath(int id) => umbracoContext.Content.GetById(preview, id)?.Path.ToDelimitedList().Reverse(); bool publishedContentExists(int id) => umbracoContext.Content.GetById(preview, id) != null; var parsed = UmbracoXPathPathSyntaxParser.ParseXPathQuery(xpath, nodeContextId, getPath, publishedContentExists); if (string.IsNullOrWhiteSpace(parsed) == false && parsed.StartsWith("$") == false) { return(umbracoContext.Content.GetByXPath(preview, parsed) .Select(x => new DataListItem { Name = x.Name, Value = Udi.Create(UmbConstants.UdiEntityType.Document, x.Key).ToString(), Icon = ContentTypeCacheHelper.TryGetIcon(x.ContentType.Alias, out var icon, _contentTypeService) == true ? icon : UmbConstants.Icons.Content, Description = x.TemplateId > 0 ? x.Url() : string.Empty, Disabled = x.IsPublished() == false, }));