Error executing template "Designs/Swift/Swift_Email/Paragraph/Swift_EmailProductCatalog.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_a73701e25d4c4d2896a0e77823991421.ExecuteAsync()
at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) in /_/src/Application/Providers/Dynamicweb.Rendering.Providers.NetCore/Razor/RazorTemplateRenderingProvider.cs:line 99
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\TemplateRenderingService.cs:line 21
at Dynamicweb.Rendering.Template.RenderRazorTemplate() in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\Template.cs:line 749
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @using Dynamicweb.Ecommerce.ProductCatalog
3
4 @functions {
5 private string GetFontStack()
6 {
7 return "font-family:initial,Arial,Helvetica Neue,Helvetica,sans-serif;";
8 }
9
10 private string GetTableReset()
11 {
12 return "border:0;margin:0;outline:0;padding:0;";
13 }
14
15 public Dynamicweb.Frontend.ColorViewModel GetMutedColor(string hex, int percent, double threshold = 0.5)
16 {
17 /// <summary>
18 /// Return a color in either lighter or darker contrast based on the original color luminance.
19 /// </summary>
20 /// <param name="percent">The percent (1-100) to darken or light the color with - higher percentage will give higher contrast</param>
21 /// <param name="threshold">The luminance threshold (0-1). Default is 0.5. 0 is black, 1 is white. Luminance threshold is used to decide wether the returned contrast color should be darker or lighter than the base color</param>
22 /// <returns>A new color viewmodel with the contrasted color in either darker or lighter luminance compared to base color</returns>
23 ///
24 if (threshold > 1)
25 threshold = 1;
26 if (threshold < 0)
27 threshold = 0;
28
29 var color = Dynamicweb.Imaging.Colors.Color.FromHex(hex);
30 var luminance = (0.2126 * color.BaseColor.R) + (0.7152 * color.BaseColor.G) + (0.0722 * color.BaseColor.B);
31 /// == luminance = 0 is black, luminance = 1 is white == //
32 luminance = color.Brightness / 255;
33 if (luminance < threshold)
34 {
35 return new Dynamicweb.Frontend.ColorViewModel() { Hex = color.Lighten(percent).ToHex() };
36 }
37 else
38 {
39 return new Dynamicweb.Frontend.ColorViewModel() { Hex = color.Darken(percent).ToHex() };
40 }
41 }
42 }
43
44 @{
45 string blockType = "productcatalog_block";
46
47 var page = Dynamicweb.Content.Services.Pages.GetPage(Model.PageID);
48 var settings = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page?.Parent).Item;
49 var blockId = Model.ID;
50 var block = Model.Item;
51
52 var emailContentThemeId = settings.GetRawValueString("EmailContentTheme");
53 var emailContentThemeParagraph = emailContentThemeId != null && emailContentThemeId != string.Empty ? Dynamicweb.Content.Services.Paragraphs.GetParagraph(Dynamicweb.Core.Converter.ToInt32(emailContentThemeId)) : null;
54 var emailContentTheme = emailContentThemeParagraph != null && Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(emailContentThemeParagraph).Item.GetString("CssClassName") != string.Empty ? Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(emailContentThemeParagraph)?.Item : null;
55
56 var rowId = Dynamicweb.Content.Services.Paragraphs.GetParagraph(blockId).GridRowId;
57 var row = Dynamicweb.Content.Services.Grids.GetGridRowById(rowId);
58 var rowItem = Dynamicweb.Content.Services.Items.GetItem(row.ItemType, row.ItemId);
59 var rowThemeId = Dynamicweb.Core.Converter.ToString(rowItem["ColumnBackground"]);
60 var rowThemeParagraph = rowThemeId != null && rowThemeId != string.Empty ? Dynamicweb.Content.Services.Paragraphs.GetParagraph(Dynamicweb.Core.Converter.ToInt32(rowThemeId)) : null;
61 var rowTheme = rowThemeParagraph != null && Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(rowThemeParagraph).Item.GetString("CssClassName") != string.Empty ? Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(rowThemeParagraph)?.Item : null;
62
63 var blockThemeId = block.GetRawValueString("Theme");
64 var blockThemeParagraph = blockThemeId != null && blockThemeId != string.Empty ? Dynamicweb.Content.Services.Paragraphs.GetParagraph(Dynamicweb.Core.Converter.ToInt32(blockThemeId)) : null;
65 var blockTheme = blockThemeParagraph != null && Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(blockThemeParagraph).Item.GetString("CssClassName") != string.Empty ? Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(blockThemeParagraph)?.Item : rowTheme is object ? rowTheme : emailContentTheme;
66
67 string backgroundColor = blockTheme != null ? "background-color: " + blockTheme.GetString("BackgroundColor") + ";" : string.Empty;
68 string foregroundColor = blockTheme != null ? "color:" + blockTheme.GetString("ForegroundColor", "inherit") + ";" : string.Empty;
69
70 string title = block.GetString("Title", string.Empty);
71 int padding = Dynamicweb.Core.Converter.ToInt32(block.GetRawValueString("Padding", "0"));
72 int cellSpacing = 8;
73 string align = block.GetRawValueString("Align", "left");
74 string text = block.GetString("Text", string.Empty);
75 var layoutColumns = Dynamicweb.Core.Converter.ToInt32(block.GetRawValueString("Layout", "2"));
76
77 int layout = Dynamicweb.Core.Converter.ToInt32(Model.Item.GetRawValueString("Layout", "2"));
78 var imageRatio = Model.Item.GetRawValueString("ImageAspectRatio", "4-3").ToLower();
79
80 var imageParms = new Dictionary<string, object>();
81 imageParms.Add("alt", "");
82 imageParms.Add("columns", layout);
83 imageParms.Add("gridColumns", Model.GridRowColumnCount);
84 imageParms.Add("nested", Model.GridRowColumnCount > 1);
85 imageParms.Add("padding", (padding * 2) + (8 * (layout - 1)));
86 imageParms.Add("imageRatio", imageRatio);
87
88 ProductListViewModel selectedProducts = block?.GetValue("Products") as ProductListViewModel;
89 IList<ProductViewModel> products = selectedProducts?.Products;
90 }
91
92 <table id="@blockId" class="@blockType" align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="mso-table-lspace:0pt;mso-table-rspace:0pt;@GetTableReset()color:inherit;width:100%;@(backgroundColor)">
93 <tbody>
94 <tr style="@GetTableReset()">
95 <td style="@GetTableReset()padding:@(padding)px">
96 <table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="mso-table-lspace:0pt;mso-table-rspace:0pt;@GetTableReset()color:inherit;width:100%;">
97 <tbody>
98 @if (products is object && products.Any())
99 {
100 @:<tr style="@GetTableReset()">
101
102 int index = 1;
103 int totalProducts = products.Count();
104 foreach (var product in products)
105 {
106 var cellForegroundColor = blockTheme?.GetColor("ForegroundColor");
107
108 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false);
109
110 var uri = Dynamicweb.Context.Current.Request.Url;
111 var hostname = uri.Scheme + Uri.SchemeDelimiter + uri.Host;
112
113 bool hideProductPrice = Model.Item?.GetBoolean("HideProductPrice") ?? false;
114 bool hideProductNumber = Model.Item?.GetBoolean("HideProductNumber") ?? false;
115
116 <td valign="top" style="@GetTableReset()@GetFontStack()">
117 <table style="border-collapse:collapse;table-layout:fixed;@GetTableReset()" cellpadding="0" cellspacing="0" width="100%" role="presentation">
118 <tbody>
119 <tr style="@GetTableReset()">
120 <td style="@GetTableReset()">
121
122 <div align="center" style="font-size:2px;">
123 <a style="text-decoration:none;" href="@link" target="_blank">
124 @if (product.DefaultImage is object)
125 {
126 imageParms["alt"] = product.Name;
127 @RenderPartial("Swift_Email/Components/Image.cshtml", new Dynamicweb.Frontend.FileViewModel() { Name = product.Name, Path = product.DefaultImage.Value }, imageParms);
128 }
129 </a>
130 </div>
131
132 <table style="border-collapse:collapse;table-layout:fixed;@GetTableReset()" cellpadding="0" cellspacing="0" width="100%" role="presentation">
133 <tbody>
134 <tr style="@GetTableReset()">
135 <td style="@GetTableReset()padding-top:8px;text-align:@align;line-height:18px;font-size:13px;text-decoration:none;color:@cellForegroundColor;">
136 <a style="text-decoration:none;color:@cellForegroundColor;@GetTableReset()@GetFontStack()" href="@link" target="_blank">
137 @product.Name
138 </a>
139 </td>
140 </tr>
141
142 @if (!hideProductNumber)
143 {
144 <tr>
145 <td style="@GetTableReset()@GetFontStack()padding-top:8px;text-align:@align;line-height:18px;font-size:11px;color:@(GetMutedColor(cellForegroundColor.Hex, 20));">
146 @product.Number
147 </td>
148 </tr>
149 }
150
151 @if (!hideProductPrice)
152 {
153 <tr>
154 <td style="@GetTableReset()@GetFontStack()padding-top:8px;text-align:@align;line-height:13px;font-size:13px;break-inside:avoid;word-break:keep-all;white-space:nowrap;color:@(cellForegroundColor);">
155 @product.Price.PriceFormatted
156
157 @if (product.Discount.Price > 0)
158 {
159 <span style="line-height:13px;font-size:13px;text-decoration:line-through;break-inside:avoid;word-break:keep-all;white-space:nowrap;color:@(GetMutedColor(cellForegroundColor.Hex, 20));">@product.PriceBeforeDiscount.PriceFormatted</span>
160 }
161 </td>
162 </tr>
163 }
164 <tr><td height="24" style="padding-top:24px;"></td></tr>
165 </tbody>
166 </table>
167 </td>
168 </tr>
169 </tbody>
170 </table>
171 </td>
172
173 if (index % layoutColumns == 0 && !(index == totalProducts))
174 {
175 @:</tr>
176 @:<tr style="@GetTableReset()">
177 @:<td style="@GetTableReset()" colspan="100%" height="@(cellSpacing * 4)"> </td>
178 @:</tr>
179 @:<tr style="@GetTableReset()">
180 }
181 else
182 {
183 if(!(index == totalProducts))
184 {
185 @:<td width="@(cellSpacing)" style="@GetTableReset()"> </td>
186 }
187 }
188
189 index++;
190 }
191 @:</tr>
192 }
193 else
194 {
195 if (Pageview.IsVisualEditorMode)
196 {
197 <tr style="@GetTableReset()@GetFontStack()">
198 <td style="@(foregroundColor)">@Translate("No products selected")</td>
199 </tr>
200 }
201 }
202 </tbody>
203 </table>
204 <!--[if mso]><br/><![endif]-->
205 </td>
206 </tr>
207 </tbody>
208 </table>
209
|