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, }));
public HttpResponseMessage GetPreviewMarkup([FromBody] JObject item, int elementIndex, Guid elementKey, int contentId) { var preview = true; var content = UmbracoContext.Content.GetById(true, contentId); if (content == null) { _logger.Debug <ContentBlocksApiController>($"Unable to retrieve content for ID '{contentId}', it is most likely a new unsaved page."); } var element = default(IPublishedElement); var block = item.ToObject <ContentBlock>(); if (block != null && block.ElementType.Equals(Guid.Empty) == false) { if (ContentTypeCacheHelper.TryGetAlias(block.ElementType, out var alias, Services.ContentTypeService) == true) { var contentType = UmbracoContext.PublishedSnapshot.Content.GetContentType(alias); if (contentType != null && contentType.IsElement == true) { var properties = new List <IPublishedProperty>(); foreach (var thing in block.Value) { var propType = contentType.GetPropertyType(thing.Key); if (propType != null) { properties.Add(new DetachedPublishedProperty(propType, null, thing.Value, preview)); } } element = _publishedModelFactory.CreateModel(new DetachedPublishedElement(block.Key, contentType, properties)); } } } var viewData = new System.Web.Mvc.ViewDataDictionary(element) { { nameof(content), content }, { nameof(element), element }, { nameof(elementIndex), elementIndex }, }; if (ContentTypeCacheHelper.TryGetIcon(content.ContentType.Alias, out var contentIcon, Services.ContentTypeService) == true) { viewData.Add(nameof(contentIcon), contentIcon); } if (ContentTypeCacheHelper.TryGetIcon(element.ContentType.Alias, out var elementIcon, Services.ContentTypeService) == true) { viewData.Add(nameof(elementIcon), elementIcon); } var markup = default(string); try { markup = ContentBlocksViewHelper.RenderPartial(element.ContentType.Alias, viewData); } catch (InvalidCastException icex) { // NOTE: This type of exception happens on a new (unsaved) page, when the context becomes the parent page, // and the preview view is strongly typed to the current page's model type. markup = "<p class=\"text-center mt4\">Unable to render the preview until the page has been saved.</p>"; _logger.Error <ContentBlocksApiController>(icex, "Error rendering preview view."); } catch (Exception ex) { markup = $"<pre class=\"error\"><code>{ex}</code></pre>"; _logger.Error <ContentBlocksApiController>(ex, "Error rendering preview view."); } return(Request.CreateResponse(HttpStatusCode.OK, new { elementKey, markup })); }