Error executing template "Designs/Swift/Paragraph/Swift_ProductListItemRepeater.cshtml"
System.ArgumentException: Could not write parsed file: D:\dynamicweb.net\Solutions\brdklee.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\_parsed\Swift_ProductComponentEdit.parsed.cshtml System.IO.IOException: The process cannot access the file 'D:\dynamicweb.net\Solutions\brdklee.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\_parsed\Swift_ProductComponentEdit.parsed.cshtml' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding)
at Dynamicweb.Core.Helpers.TextFileHelper.WriteTextFile(String value, String path, Boolean appendToFile, Encoding encoding)
at Dynamicweb.Rendering.Designer.Parser.Parse(Layout l)
at Dynamicweb.Rendering.Designer.Parser.Parse(Layout l)
at Dynamicweb.Rendering.Designer.Layout.CheckParsed()
at Dynamicweb.Rendering.Designer.Layout.GetLayoutByLocation(String path)
at Dynamicweb.Content.Layouts.LayoutLocator.FindLayout(Page page, String layoutName)
at Dynamicweb.Frontend.Content.GetLayoutForDevice(Page page, DeviceType device)
at Dynamicweb.Frontend.Content.CreateGridContent(Int32 contentId, Boolean ignoreVisualEdit)
at Dynamicweb.Frontend.Content.RenderExternalGrid(Int32 pageId, String container)
at CompiledRazorTemplates.Dynamic.RazorEngine_5026ef4619a842f9937e4dc809ee26da.Execute() in D:\dynamicweb.net\Solutions\brdklee.cloud.dynamicweb-cms.com\files\Templates\Designs\Swift\Paragraph\Swift_ProductListItemRepeater.cshtml:line 175
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 Dynamicweb.Ecommerce.ProductCatalog
3 @using Dynamicweb.Core
4
5 @{
6 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
7 int productsCount = 0;
8 int maxProductsCounter = 0;
9
10 string productInfoFeed = "";
11 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]);
12 if (isLazyLoadingForProductInfoEnabled)
13 {
14 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
15 {
16 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
17 if (!string.IsNullOrEmpty(productInfoFeed))
18 {
19 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
20 }
21 }
22 }
23
24 ProductListViewModel productList = null;
25 if (Dynamicweb.Context.Current.Items.Contains("ProductList"))
26 {
27 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"];
28 }
29 else if (Pageview.Page.Item["DummyProductGroup"] != null && Pageview.IsVisualEditorMode)
30 {
31 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
32 ProductListViewModel groupList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
33
34 if (groupList?.Products is object)
35 {
36 productList = groupList;
37 }
38 }
39 }
40
41 @if (productList is object)
42 {
43 <div class="h-100@(theme) product-list item_@Model.Item.SystemName.ToLower()" @productInfoFeed>
44 @{
45 bool isVisualEditor = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("VisualEdit")) : false;
46
47 string groupId = productList?.Group?.Id != null ? productList.Group.Id : "";
48 string url = Dynamicweb.Context.Current.Request.RawUrl;
49
50 if (productList.TotalProductsCount > 0)
51 {
52 int pageSizeSetting = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("OriginalPageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("OriginalPageSize")) : productList.PageSize;
53 int pageNumber = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageNum")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageNum")) : productList.CurrentPage;
54 int pageSize = Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) > 0 ? Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) : productList.PageSize;
55 pageNumber = pageSize != pageSizeSetting ? (pageSize / pageSizeSetting) : pageNumber;
56 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : pageSizeSetting * pageNumber;
57 loadedProducts = loadedProducts > productList.TotalProductsCount ? productList.TotalProductsCount : loadedProducts;
58
59 pageNumber += 1;
60
61 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : string.Empty;
62 searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("q")) ? Dynamicweb.Context.Current.Request.Form.Get("q") : searchQuery;
63 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : string.Empty;
64
65 int itemSourcePageId = Convert.ToInt32(Model.Item.GetRawValueString("ListComponentSource", "0"));
66
67 var pageService = new Dynamicweb.Content.PageService();
68 itemSourcePageId = itemSourcePageId > 0 && pageService.GetPageOrLanguage(itemSourcePageId, Pageview.AreaID) != null ? pageService.GetPageOrLanguage(itemSourcePageId, Pageview.AreaID).ID : itemSourcePageId;
69
70 var page = Dynamicweb.Content.Services.Pages.GetPage(itemSourcePageId);
71
72 if (page != null)
73 {
74 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page);
75
76 string gridColumnSize = Model.Item.GetRawValueString("GridLayoutDesktop", "3-columns");
77 gridColumnSize = gridColumnSize == "2-columns" ? "g-col-lg-6" : gridColumnSize;
78 gridColumnSize = gridColumnSize == "3-columns" ? "g-col-lg-4" : gridColumnSize;
79 gridColumnSize = gridColumnSize == "4-columns" ? "g-col-lg-3" : gridColumnSize;
80 gridColumnSize = gridColumnSize == "6-columns" ? "g-col-lg-2" : gridColumnSize;
81 gridColumnSize = gridColumnSize == "list" ? "g-col-lg-12" : gridColumnSize;
82
83 string gridColumnMobileSize = Model.Item.GetRawValueString("GridLayoutMobile", "2-columns");
84 gridColumnMobileSize = gridColumnMobileSize == "list" ? "g-col-12" : gridColumnMobileSize;
85 gridColumnMobileSize = gridColumnMobileSize == "2-columns" ? "g-col-6" : gridColumnMobileSize;
86
87 string listItemTheme = " theme " + pageViewModel.Item.GetRawValueString("Theme", string.Empty).Replace(" ", "").Trim().ToLower();
88 string listItemPadding = pageViewModel.Item.GetRawValueString("ContentPadding", string.Empty);
89 string listItemPaddingClass = string.Empty;
90
91 switch (listItemPadding)
92 {
93 case "small":
94 listItemPaddingClass = " p-2 p-xl-3";
95 break;
96 case "large":
97 listItemPaddingClass = " p-3 p-xl-4";
98 break;
99 case "small-x":
100 listItemPaddingClass = " px-2 px-md-3";
101 break;
102 case "large-x":
103 listItemPaddingClass = " px-3 px-md-4";
104 break;
105 }
106
107 <div class="grid pb-3">
108 <script>
109 gtag("event", "view_item_list", {
110 item_list_id: "product_list_item_repeater",
111 item_list_name: "Product list (Item Repeater)",
112 items: [
113 @foreach (ProductViewModel product in productList.Products)
114 {
115 <text>{
116 item_id: "@product.Number",
117 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name)",
118 currency: "@product.Price.CurrencyCode",
119 price: @product.Price.ToStringInvariant(),
120 discount: @product.Discount.ToStringInvariant()
121 },</text>
122 }
123 ]
124 });
125 </script>
126
127 @foreach (ProductViewModel product in productList.Products)
128 {
129 if (maxProductsCounter == 0 || (productsCount < maxProductsCounter))
130 {
131 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false);
132
133 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
134 {
135 Dynamicweb.Context.Current.Items["ProductDetails"] = product;
136 }
137 else
138 {
139 Dynamicweb.Context.Current.Items.Add("ProductDetails", product);
140 }
141
142 if (Model.Item.GetString("ListComponentSource") != null)
143 {
144 <article class="@gridColumnMobileSize @gridColumnSize @listItemTheme @listItemPaddingClass d-flex flex-column position-relative product js-product" data-product-id="@product.Id" data-variant-id="@product.VariantId" itemscope itemtype="https://schema.org/Product">
145 @{
146 string clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @product.Price.ToStringInvariant() + "', '" + @product.Discount.ToStringInvariant() + "')\"";
147 }
148 <a href="@link" class="stretched-link" onmouseover="swift.Image.swapImage(event)" onmouseout="swift.Image.swapImage(event)" @clickProductLink>
149 <span class="visually-hidden">@product.Name</span>
150 </a>
151
152 <script>
153 function clickProductLink(productId, productName, productVariant, productCurrency, productPrice, productDiscount) {
154 if (typeof gtag !== "undefined") {
155 gtag("event", "select_item", {
156 item_list_id: "product_list_item_repeater",
157 item_list_name: "Product list (Item Repeater)",
158 items: [
159 {
160 item_id: productId,
161 item_name: productName,
162 currency: productCurrency,
163 item_list_id: "product_list_item_repeater",
164 item_list_name: "Product list (Item Repeater)",
165 item_variant: productVariant,
166 price: productPrice,
167 discount: productDiscount
168 }
169 ]
170 });
171 }
172 }
173 </script>
174
175 @RenderGrid(itemSourcePageId)
176 </article>
177 }
178
179 productsCount++;
180 }
181 }
182 </div>
183
184 <div class="my-3" id="ProductListLoadMore">
185 <div class="text-center">
186 <div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div>
187 @if (productList.PageCount != 1 && maxProductsCounter == 0 && loadedProducts < productList.TotalProductsCount)
188 {
189 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "";
190 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection;
191 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID") : "";
192
193 <form method="get" action="@url" data-response-target-element=".product-list" data-swap="afterend" class="w-100">
194 @if (productList?.FacetGroups != null)
195 {
196 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
197 {
198 foreach (FacetViewModel facetItem in facetGroup.Facets)
199 {
200 foreach (FacetOptionViewModel facetOption in facetItem.Options)
201 {
202 if (facetOption.Selected)
203 {
204 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]">
205 }
206 }
207 }
208 }
209 }
210
211 @if (!string.IsNullOrEmpty(searchQuery))
212 {
213 <input type="hidden" name="q" value="@searchQuery">
214 <input type="hidden" name="SearchLayout" value="@searchLayout">
215 }
216
217 @if (!string.IsNullOrEmpty(mainProductId))
218 {
219 <input type="hidden" name="MainProductID" value="@mainProductId">
220 }
221
222 @if (productList?.Group?.Id != null)
223 {
224 <input type="hidden" name="GroupId" value="@groupId">
225 }
226
227 <input type="hidden" name="OriginalPageSize" value="@pageSizeSetting">
228 <input type="hidden" name="PageSize" value="@(loadedProducts + pageSizeSetting)">
229 <input type="hidden" name="PageNum" value="@pageNumber">
230 <input type="hidden" name="SortBy" value="@sortBySelection">
231 <input type="hidden" name="RequestType" value="UpdateList">
232 <input type="hidden" name="ParagraphID" value="@Model.ID">
233
234 @if (productList?.FacetGroups is object)
235 {
236 string nextPageLink = $"/Default.aspx?ID={Pageview.Page.ID}&PageNum={pageNumber}&SortBy={sortBySelection}";
237
238 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
239 {
240 foreach (FacetViewModel facetItem in facetGroup.Facets)
241 {
242 foreach (FacetOptionViewModel facetOption in facetItem.Options)
243 {
244 if (facetOption.Selected)
245 {
246 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]";
247 }
248 }
249 }
250 }
251
252 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : "";
253 string disableLoadMore = isLazyLoadingForProductInfoEnabled ? "d-none" : "";
254
255 <a href="@nextPageLink" class="btn btn-primary swift_load_more_button @disableLoadMore" onclick="swift.ProductList.Update(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a>
256 }
257 </form>
258 }
259 </div>
260 </div>
261
262 <script>
263 function switchVariantProduct(id, price, imagesrc) {
264 var productImageElement = document.querySelector("#ProductImage_" + id);
265 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price");
266
267 if (productPriceElement) {
268 productPriceElement.innerText = price;
269 }
270
271 if (productImageElement) {
272 productImageElement.src = imagesrc;
273
274 var imageSrcset = productImageElement.srcset;
275 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&");
276
277 productImageElement.srcset = imageSrcset;
278 }
279 }
280 </script>
281 }
282 else if (Pageview.IsVisualEditorMode)
283 {
284 <div class="alert alert-dark m-0" role="alert">
285 <span>@Translate("The selected component does not exist anymore")</span>
286 </div>
287 }
288 }
289 else
290 {
291 string noProductsFoundMessage = !string.IsNullOrEmpty(Model.Item.GetString("NoProductsFoundMessage")) ? Model.Item.GetString("NoProductsFoundMessage") : Translate("We did not find anything matching your search result");
292 bool hasSubgroups = false;
293
294 if (productList.SubGroups != null)
295 {
296 hasSubgroups = productList.SubGroups.Any();
297 }
298
299 if (!Model.Item.GetBoolean("HideNoProductsFoundMessage"))
300 {
301 if (!isVisualEditor)
302 {
303 <div class="alert alert-dark m-0" role="alert">
304 @noProductsFoundMessage
305 </div>
306 }
307 else
308 {
309 <div class="alert alert-dark m-0" role="alert">
310 @Translate("Product list: The list will be shown here, if any")
311 </div>
312 }
313 }
314 else if (!hasSubgroups)
315 {
316 <div class="alert alert-dark m-0" role="alert">
317 @noProductsFoundMessage
318 </div>
319 }
320 }
321 }
322 </div>
323 }
324 else if (Pageview.IsVisualEditorMode)
325 {
326 <div class="alert alert-dark m-0" role="alert">
327 <span>@Translate("Product list item repeater: The repeater paragraph will be shown here, if any products are available")</span>
328 </div>
329 }
330