Skip to content
This repository was archived by the owner on Feb 10, 2024. It is now read-only.

Commit ad3b326

Browse files
authored
Merge pull request #105 from kows/feature/preview-unpublished
Rework preview mechanism based on StackedContent implementation
2 parents 3b319a2 + a18179b commit ad3b326

File tree

12 files changed

+277
-52
lines changed

12 files changed

+277
-52
lines changed

src/Our.Umbraco.DocTypeGridEditor/Bootstrap.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
2-
using System.Web.Mvc;
32
using Newtonsoft.Json;
4-
using Our.Umbraco.DocTypeGridEditor.Web.Attributes;
53
using Our.Umbraco.DocTypeGridEditor.Web.Mvc;
64
using Umbraco.Core;
75
using Umbraco.Core.Sync;
@@ -14,8 +12,6 @@ internal class Bootstrap : ApplicationEventHandler
1412
{
1513
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
1614
{
17-
GlobalFilters.Filters.Add(new DocTypeGridEditorPreviewAttribute());
18-
1915
if (DefaultDocTypeGridEditorSurfaceControllerResolver.HasCurrent == false)
2016
{
2117
DefaultDocTypeGridEditorSurfaceControllerResolver.Current = new DefaultDocTypeGridEditorSurfaceControllerResolver();
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Umbraco.Core;
5+
using Umbraco.Core.Models;
6+
using Umbraco.Core.Models.PublishedContent;
7+
using Umbraco.Core.PropertyEditors;
8+
using Umbraco.Core.Services;
9+
using Umbraco.Web.Models;
10+
11+
namespace Our.Umbraco.DocTypeGridEditor.Models
12+
{
13+
internal class UnpublishedContent : PublishedContentWithKeyBase
14+
{
15+
private readonly IContent content;
16+
17+
private readonly Lazy<IEnumerable<IPublishedContent>> children;
18+
private readonly Lazy<PublishedContentType> contentType;
19+
private readonly Lazy<string> creatorName;
20+
private readonly Lazy<IPublishedContent> parent;
21+
private readonly Lazy<Dictionary<string, IPublishedProperty>> properties;
22+
private readonly Lazy<string> urlName;
23+
private readonly Lazy<string> writerName;
24+
25+
public UnpublishedContent(int id, ServiceContext serviceContext)
26+
: this(serviceContext.ContentService.GetById(id), serviceContext)
27+
{ }
28+
29+
public UnpublishedContent(IContent content, ServiceContext serviceContext)
30+
: base()
31+
{
32+
Mandate.ParameterNotNull(content, nameof(content));
33+
Mandate.ParameterNotNull(serviceContext, nameof(serviceContext));
34+
35+
var userService = new Lazy<IUserService>(() => serviceContext.UserService);
36+
37+
this.content = content;
38+
39+
this.children = new Lazy<IEnumerable<IPublishedContent>>(() => this.content.Children().Select(x => new UnpublishedContent(x, serviceContext)).ToList());
40+
this.contentType = new Lazy<PublishedContentType>(() => PublishedContentType.Get(this.ItemType, this.DocumentTypeAlias));
41+
this.creatorName = new Lazy<string>(() => this.content.GetCreatorProfile(userService.Value).Name);
42+
this.parent = new Lazy<IPublishedContent>(() => new UnpublishedContent(this.content.Parent(), serviceContext));
43+
this.properties = new Lazy<Dictionary<string, IPublishedProperty>>(() => MapProperties(PropertyEditorResolver.Current, serviceContext));
44+
this.urlName = new Lazy<string>(() => this.content.Name.ToUrlSegment());
45+
this.writerName = new Lazy<string>(() => this.content.GetWriterProfile(userService.Value).Name);
46+
}
47+
48+
public override Guid Key => this.content.Key;
49+
50+
public override PublishedItemType ItemType => PublishedItemType.Content;
51+
52+
public override int Id => this.content.Id;
53+
54+
public override int TemplateId => this.content.Template?.Id ?? default(int);
55+
56+
public override int SortOrder => this.content.SortOrder;
57+
58+
public override string Name => this.content.Name;
59+
60+
public override string UrlName => this.urlName.Value;
61+
62+
public override string DocumentTypeAlias => this.content.ContentType?.Alias;
63+
64+
public override int DocumentTypeId => this.content.ContentType?.Id ?? default(int);
65+
66+
public override string WriterName => this.writerName.Value;
67+
68+
public override string CreatorName => this.creatorName.Value;
69+
70+
public override int WriterId => this.content.WriterId;
71+
72+
public override int CreatorId => this.content.CreatorId;
73+
74+
public override string Path => this.content.Path;
75+
76+
public override DateTime CreateDate => this.content.CreateDate;
77+
78+
public override DateTime UpdateDate => this.content.UpdateDate;
79+
80+
public override Guid Version => this.content.Version;
81+
82+
public override int Level => this.content.Level;
83+
84+
public override bool IsDraft => true;
85+
86+
public override IPublishedContent Parent => this.parent.Value;
87+
88+
public override IEnumerable<IPublishedContent> Children => this.children.Value;
89+
90+
public override PublishedContentType ContentType => this.contentType.Value;
91+
92+
public override ICollection<IPublishedProperty> Properties => this.properties.Value.Values;
93+
94+
public override IPublishedProperty GetProperty(string alias)
95+
{
96+
return this.properties.Value.TryGetValue(alias, out IPublishedProperty property) ? property : null;
97+
}
98+
99+
private Dictionary<string, IPublishedProperty> MapProperties(PropertyEditorResolver resolver, ServiceContext services)
100+
{
101+
var contentType = this.contentType.Value;
102+
var properties = this.content.Properties;
103+
104+
var items = new Dictionary<string, IPublishedProperty>(StringComparer.InvariantCultureIgnoreCase);
105+
106+
foreach (var propertyType in contentType.PropertyTypes)
107+
{
108+
var property = properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyType.PropertyTypeAlias));
109+
var value = property?.Value;
110+
if (value != null)
111+
{
112+
var propertyEditor = resolver.GetByAlias(propertyType.PropertyEditorAlias);
113+
if (propertyEditor != null)
114+
{
115+
value = propertyEditor.ValueEditor.ConvertDbToString(property, property.PropertyType, services.DataTypeService);
116+
}
117+
}
118+
119+
items.Add(propertyType.PropertyTypeAlias, new UnpublishedProperty(propertyType, value));
120+
}
121+
122+
return items;
123+
}
124+
}
125+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using Umbraco.Core.Models;
3+
using Umbraco.Core.Models.PublishedContent;
4+
5+
namespace Our.Umbraco.DocTypeGridEditor.Models
6+
{
7+
internal class UnpublishedProperty : IPublishedProperty
8+
{
9+
private readonly PublishedPropertyType propertyType;
10+
private readonly object dataValue;
11+
private readonly Lazy<bool> hasValue;
12+
private readonly Lazy<object> sourceValue;
13+
private readonly Lazy<object> objectValue;
14+
private readonly Lazy<object> xpathValue;
15+
16+
public UnpublishedProperty(PublishedPropertyType propertyType, object value)
17+
{
18+
this.propertyType = propertyType;
19+
20+
this.dataValue = value;
21+
this.hasValue = new Lazy<bool>(() => value != null && value.ToString().Trim().Length > 0);
22+
23+
this.sourceValue = new Lazy<object>(() => this.propertyType.ConvertDataToSource(this.dataValue, true));
24+
this.objectValue = new Lazy<object>(() => this.propertyType.ConvertSourceToObject(this.sourceValue.Value, true));
25+
this.xpathValue = new Lazy<object>(() => this.propertyType.ConvertSourceToXPath(this.sourceValue.Value, true));
26+
}
27+
28+
public string PropertyTypeAlias => this.propertyType.PropertyTypeAlias;
29+
30+
public bool HasValue => this.hasValue.Value;
31+
32+
public object DataValue => this.dataValue;
33+
34+
public object Value => this.objectValue.Value;
35+
36+
public object XPathValue => this.xpathValue.Value;
37+
}
38+
}

src/Our.Umbraco.DocTypeGridEditor/Our.Umbraco.DocTypeGridEditor.csproj

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@
7070
</Reference>
7171
<Reference Include="System" />
7272
<Reference Include="System.Core" />
73+
<Reference Include="System.Net.Http" />
74+
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
75+
<SpecificVersion>False</SpecificVersion>
76+
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
77+
<Private>False</Private>
78+
</Reference>
7379
<Reference Include="System.Web" />
7480
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
7581
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
@@ -100,16 +106,19 @@
100106
<Compile Include="Models\DetachedPublishedContent.cs" />
101107
<Compile Include="Models\DetachedPublishedProperty.cs" />
102108
<Compile Include="Models\JsonDbRow.cs" />
109+
<Compile Include="Models\UnpublishedContent.cs" />
110+
<Compile Include="Models\UnpublishedProperty.cs" />
103111
<Compile Include="PackageActions\AddObjectToJsonArray.cs" />
104112
<Compile Include="Properties\AssemblyInfo.cs" />
105113
<Compile Include="Properties\VersionInfo.cs" />
106-
<Compile Include="Web\Attributes\DocTypeGridEditorPreviewAttribute.cs" />
107114
<Compile Include="Web\Controllers\DocTypeGridEditorApiController.cs" />
108115
<Compile Include="Extensions\ContentTypeServiceExtensions.cs" />
109116
<Compile Include="Web\Controllers\DocTypeGridEditorSurfaceController.cs" />
110117
<Compile Include="Web\Extensions\HtmlHelperExtensions.cs" />
111118
<Compile Include="Web\Helpers\SurfaceControllerHelper.cs" />
119+
<Compile Include="Web\Helpers\ViewHelper.cs" />
112120
<Compile Include="Web\Mvc\DefaultDocTypeGridEditorSurfaceControllerResolver.cs" />
121+
<Compile Include="Web\PreviewModel.cs" />
113122
</ItemGroup>
114123
<ItemGroup>
115124
<None Include="app.config" />

src/Our.Umbraco.DocTypeGridEditor/Web/Attributes/DocTypeGridEditorPreviewAttribute.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/Our.Umbraco.DocTypeGridEditor/Web/Controllers/DocTypeGridEditorApiController.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Net.Http;
5+
using System.Net.Http.Formatting;
6+
using System.Net.Http.Headers;
7+
using System.Net.Mime;
48
using System.Text.RegularExpressions;
59
using System.Web.Http;
610
using System.Web.Http.ModelBinding;
711
using Our.Umbraco.DocTypeGridEditor.Extensions;
12+
using Our.Umbraco.DocTypeGridEditor.Models;
813
using Umbraco.Core.Models;
914
using Umbraco.Core.PropertyEditors;
1015
using Umbraco.Web.Editors;
16+
using Umbraco.Web.Models;
1117
using Umbraco.Web.Mvc;
1218

1319
namespace Our.Umbraco.DocTypeGridEditor.Web.Controllers
@@ -86,5 +92,43 @@ public object GetDataTypePreValues(string dtdId)
8692
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
8793
return propEditor.PreValueEditor.ConvertDbToEditor(propEditor.DefaultPreValues, preValue);
8894
}
95+
96+
[HttpPost]
97+
public HttpResponseMessage GetPreviewMarkup([FromBody] FormDataCollection item, [FromUri] int pageId)
98+
{
99+
var page = default(IPublishedContent);
100+
101+
// If the page is new, then the ID will be zero
102+
if (pageId > 0)
103+
{
104+
// Get page container node
105+
page = UmbracoContext.ContentCache.GetById(pageId);
106+
if (page == null)
107+
{
108+
// If unpublished, then fake PublishedContent (with IContent object)
109+
page = new UnpublishedContent(pageId, Services);
110+
}
111+
}
112+
113+
var culture = UmbracoContext.Application.Services.ContentService.GetById(pageId).GetCulture();
114+
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
115+
System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
116+
117+
// Construct preview model
118+
var model = new PreviewModel { Page = page, Values = item };
119+
120+
// Render view
121+
var markup = Helpers.ViewHelper.RenderPartial("~/App_Plugins/DocTypeGridEditor/Render/DocTypeGridEditorPreviewer.cshtml", model);
122+
123+
// Return response
124+
var response = new HttpResponseMessage
125+
{
126+
Content = new StringContent(markup ?? string.Empty)
127+
};
128+
129+
response.Content.Headers.ContentType = new MediaTypeHeaderValue(MediaTypeNames.Text.Html);
130+
131+
return response;
132+
}
89133
}
90134
}

src/Our.Umbraco.DocTypeGridEditor/Web/Extensions/HtmlHelperExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Our.Umbraco.DocTypeGridEditor.Web.Mvc;
77
using Umbraco.Core;
88
using Umbraco.Core.Models;
9-
using Umbraco.Web;
109

1110
namespace Our.Umbraco.DocTypeGridEditor.Web.Extensions
1211
{
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.IO;
2+
using System.Web;
3+
using System.Web.Mvc;
4+
using System.Web.Routing;
5+
using Umbraco.Core.Logging;
6+
7+
namespace Our.Umbraco.DocTypeGridEditor.Web.Helpers
8+
{
9+
public static class ViewHelper
10+
{
11+
private class DummyController : Controller { }
12+
13+
internal static string RenderPartial(string partialName, object model)
14+
{
15+
using (var sw = new StringWriter())
16+
{
17+
var httpContext = new HttpContextWrapper(HttpContext.Current);
18+
19+
var routeData = new RouteData();
20+
routeData.Values.Add("controller", "DummyController");
21+
22+
var controllerContext = new ControllerContext(new RequestContext(httpContext, routeData), new DummyController());
23+
24+
var viewResult = ViewEngines.Engines.FindPartialView(controllerContext, partialName);
25+
if (viewResult.View == null)
26+
{
27+
LogHelper.Warn(typeof(ViewHelper), $"No view found for partial '{partialName}'");
28+
return null;
29+
}
30+
31+
viewResult.View.Render(new ViewContext(controllerContext, viewResult.View, new ViewDataDictionary { Model = model }, new TempDataDictionary(), sw), sw);
32+
33+
return sw.ToString();
34+
}
35+
}
36+
}
37+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Net.Http.Formatting;
2+
using Umbraco.Core.Models;
3+
4+
namespace Our.Umbraco.DocTypeGridEditor.Web
5+
{
6+
public class PreviewModel
7+
{
8+
public IPublishedContent Page { get; set; }
9+
10+
public FormDataCollection Values { get; set; }
11+
}
12+
}

src/Our.Umbraco.DocTypeGridEditor/Web/UI/App_Plugins/DocTypeGridEditor/Js/doctypegrideditor.controllers.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@
116116
dtgeResources.getEditorMarkupForDocTypePartial(editorState.current.id, model.id,
117117
$scope.control.editor.alias, model.dtgeContentTypeAlias, model.value,
118118
$scope.control.editor.config.viewPath,
119-
$scope.control.editor.config.previewViewPath,
120-
!!editorState.current.publishDate)
119+
$scope.control.editor.config.previewViewPath)
121120
.success(function (htmlResult) {
122121
if (htmlResult.trim().length > 0) {
123122
$scope.preview = htmlResult;

src/Our.Umbraco.DocTypeGridEditor/Web/UI/App_Plugins/DocTypeGridEditor/Js/doctypegrideditor.resources.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
'Failed to retrieve datatypes'
3535
);
3636
},
37-
getEditorMarkupForDocTypePartial: function (nodeId, id, editorAlias, contentTypeAlias, value, viewPath, previewViewPath, published) {
38-
var url = umbRequestHelper.convertVirtualToAbsolutePath("~/" + (published ? nodeId : "") + "?dtgePreview=1" + (published ? "" : "&nodeId=" + nodeId));
37+
getEditorMarkupForDocTypePartial: function (pageId, id, editorAlias, contentTypeAlias, value, viewPath, previewViewPath) {
38+
var url = umbRequestHelper.convertVirtualToAbsolutePath("~/umbraco/backoffice/DocTypeGridEditorApi/DocTypeGridEditorApi/GetPreviewMarkup?dtgePreview=1&pageId=" + pageId);
3939
return $http({
4040
method: 'POST',
4141
url: url,

0 commit comments

Comments
 (0)