Error executing template "Designs/Swift/Paragraph/Custom__KeystoneSingleFilePublisher.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_0b4dc5a6c4954fb08a2db01140ebb9da.Execute() in E:\Domains\Sites\portal.keystonerv.com\Files\Templates\Designs\Swift\Paragraph\Custom__KeystoneSingleFilePublisher.cshtml:line 56
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @using System.IO
3 @using System.Text
4 @functions
5 {
6 static readonly string[] SupportedImageFormats = new string[] {".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff", ".pdf"};
7 static readonly string[] SupportedDocumentFormats = new string[] {".docx", ".xlsx", ".ppt", ".pptx", ".txt", ".msg", ".zip"};
8 static readonly string[] SupportedVideoFormats = new string[] {".mp4", ".avi", ".mov", ".webm", ".ogg"};
9 static readonly string[] SupportedPlayedVideoFormats = new string[] {".mp4", ".webm", ".ogg"};
10
11 private static bool IsValidDirectory(string path)
12 {
13 if (string.IsNullOrEmpty(path)) return false;
14
15 var fullPath = Dynamicweb.Context.Current.Server.MapPath(path);
16
17 return !string.IsNullOrEmpty(fullPath) && Directory.Exists(fullPath);
18 }
19
20 private static bool IsFileSupported(string fileExtension)
21 {
22 return IsImage(fileExtension) || IsVideo(fileExtension) || IsDocument(fileExtension);
23 }
24
25 private static bool IsImage(string fileExtension)
26 {
27 return SupportedImageFormats.Contains(fileExtension);
28 }
29
30 private static bool IsVideo(string fileExtension)
31 {
32 return SupportedVideoFormats.Contains(fileExtension);
33 }
34
35 private static bool IsVideoPlayable(string fileExtension)
36 {
37 return SupportedPlayedVideoFormats.Contains(fileExtension);
38 }
39
40 private static string GetVideoType(string fileExtension)
41 {
42 return IsVideoPlayable(fileExtension) ? $"video/{SupportedPlayedVideoFormats.FirstOrDefault(s => s == fileExtension)?.Replace(".",string.Empty)}" : string.Empty;
43 }
44
45 private static bool IsDocument(string fileName)
46 {
47 return SupportedDocumentFormats.Any(s => fileName.EndsWith(s, StringComparison.OrdinalIgnoreCase));
48 }
49 }
50
51 @{
52 var queryStringParameter = Model.Item.GetString("QuerystringParameter");
53 var requestFile = Dynamicweb.Context.Current.Request.QueryString.Get(queryStringParameter);
54 var folder = Model.Item.GetString("Folder");
55
56 var isValidFilePath = !requestFile.Contains("../");
57 var combinedPath = string.Empty;
58 var fullPath = string.Empty;
59
60 if (isValidFilePath)
61 {
62 combinedPath = requestFile.StartsWith("/") ? $"{folder}{requestFile}" : Path.Combine(folder, requestFile);
63 fullPath = Dynamicweb.Context.Current.Server.MapPath(combinedPath);
64 }
65
66 var file = !string.IsNullOrEmpty(fullPath) && File.Exists(fullPath) ? new FileInfo(fullPath) : null;
67 var isFileSupported = file != null ? IsDocument(file.Extension) || IsImage(file.Extension) : false;
68 }
69
70 @if (isFileSupported)
71 {
72 var title = Model.Item.GetString("Title");
73 var hideTitle = Model.Item.GetBoolean("HideTitle");
74
75 var contentPadding = Model.Item.GetRawValueString("contentPadding", "");
76 contentPadding = contentPadding == "none" ? "p-3 px-xl-3 py-xl-4" : contentPadding;
77 contentPadding = contentPadding == "small" ? "p-3 p-xl-4" : contentPadding;
78 contentPadding = contentPadding == "large" ? "p-4 p-xl-5" : contentPadding;
79
80 var theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
81
82 var layout = Model.Item.GetString("Layout");
83 var showDownloadButton = Model.Item.GetBoolean("ShowDownloadButton");
84 var fileLength = file.Length > 0 ? $"{(file.Length / 1024):N0} KB" : $"{file.Length}";
85
86 var downloadButtonText = Model.Item.GetString("DownloadButtonText");
87 var downloadButtonIcon = Model.Item.GetRawValueString("DownloadButtonIcon");
88 var downloadButtonType = Model.Item.GetString("DownloadButtonType", "primary");
89 var downloadLink = $"/Admin/Public/download.aspx?ForceDownload=true&File={combinedPath}";
90
91 <div class="@(contentPadding) @(theme) item_@Model.Item.SystemName.ToLower()">
92
93 @if (!string.IsNullOrEmpty(title) && !hideTitle)
94 {
95 <h2 class="h5 mb-4">@title</h2>
96 }
97
98 @if (layout == "thumbnail")
99 {
100 var alignment = Model.Item.GetString("Alignment", "center");
101 var columnSize = Model.Item.GetInt32("ColumnSize");
102
103 <div class="row justify-content-@(alignment)">
104 <div class="col-@(columnSize)">
105 <a class="text-decoration-none" href="@combinedPath">
106
107 <div class="d-flex justify-content-center align-items-center position-relative w-100 p-2 mb-3" style="background-color: hsl(0, 0%, 93%);">
108
109 @if (IsImage(file.Extension))
110 {
111 var imageWidth = Model.Item.GetInt32("ImageWidth");
112 var imageRatio = Model.Item.GetString("ImageAspectRatio", "100%");
113 var imgPath = $"/Admin/Public/GetImage.ashx?image={combinedPath}&width={imageWidth}&format=webp";
114
115 <div class="ratio" style="--bs-aspect-ratio: @imageRatio;">
116 <img class="mw-100 mh-100 align-self-center" alt="@file.Name" src="@imgPath" loading="lazy">
117 </div>
118 }
119 else if (IsDocument(file.Extension))
120 {
121 var iconPath = "/Files/Templates/Designs/Swift/Assets/icons/file.svg";
122
123 <span class="icon-6">
124 @ReadFile(iconPath)
125 </span>
126 }
127
128 </div>
129
130 </a>
131
132 <div class="row d-flex justify-content-between">
133
134 <div class="flex-fill">
135 <h3 class="h6" style="word-break: break-all">@file.Name</h3>
136 </div>
137
138 <div class="fs-6 opacity-50">
139 @fileLength
140 </div>
141
142 </div>
143
144 @if (showDownloadButton && (!string.IsNullOrEmpty(downloadButtonText) || !string.IsNullOrEmpty(downloadButtonIcon)))
145 {
146 <div class="row mt-2">
147 <a class="btn btn-@downloadButtonType d-flex justify-content-center gap-1" href="@downloadLink">
148
149 @if (!string.IsNullOrEmpty(downloadButtonIcon))
150 {
151 <span class="icon-2">
152 @ReadFile(downloadButtonIcon)
153 </span>
154 }
155
156 @if (!string.IsNullOrEmpty(downloadButtonText))
157 {
158 <span>@downloadButtonText</span>
159 }
160
161 </a>
162 </div>
163 }
164 </div>
165 </div>
166 }
167 else if (layout == "text")
168 {
169 <div class="d-flex justify-content-start align-items-center gap-4">
170 <a class="text-decoration-none" href="@combinedPath">
171 <span class="">@file.Name</span>
172 <span class="fs-6 opacity-50 ms-2">@fileLength</span>
173 </a>
174
175 @if (showDownloadButton && (!string.IsNullOrEmpty(downloadButtonText) || !string.IsNullOrEmpty(downloadButtonIcon)))
176 {
177 <a class="btn btn-sm btn-@downloadButtonType d-flex justify-content-center gap-1" href="@downloadLink">
178
179 @if (!string.IsNullOrEmpty(downloadButtonIcon))
180 {
181 <span class="icon-2">
182 @ReadFile(downloadButtonIcon)
183 </span>
184 }
185
186 @if (!string.IsNullOrEmpty(downloadButtonText))
187 {
188 <span>@downloadButtonText</span>
189 }
190
191 </a>
192 }
193 </div>
194 }
195 </div>
196 }
197 else if(Pageview.IsVisualEditorMode)
198 {
199 <div class="alert alert-info" role="alert">
200 <span>@Translate("Keystone single file publisher: Edit this column to configure")</span>
201 </div>
202 }