Error executing template "Designs/Swift/Paragraph/Swift_ProductListItemRepeater.cshtml"
System.IO.IOException: The process cannot access the file 'D:\dynamicweb.net\Solutions\Sublime\essveprod.dw10.dynamicweb-cms.com\wwwroot\Files\Templates\Designs\Swift\Translations.xml' because it is being used by another process.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at Dynamicweb.Rendering.Translation.Source.WriteDocument(XmlDocument document)
at Dynamicweb.Rendering.Translation.Source.Save()
at Dynamicweb.Rendering.Translation.Source.UpdateTranslationSource(Source source, IEnumerable`1 newKeys, String designName, IEnumerable`1 cultures)
at Dynamicweb.Rendering.Template.TranslateText(String text, String defaultValue, String cultureName)
at CompiledRazorTemplates.Dynamic.RazorEngine_35854d3886cd4d7eba211059d12b9168.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)
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: @PriceViewModelExtensions.ToStringInvariant(product.Price)
120 },</text>
121 }
122 ]
123 });
124 </script>
125
126 @foreach (ProductViewModel product in productList.Products)
127 {
128 if (maxProductsCounter == 0 || (productsCount < maxProductsCounter))
129 {
130 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false);
131
132 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
133 {
134 Dynamicweb.Context.Current.Items["ProductDetails"] = product;
135 }
136 else
137 {
138 Dynamicweb.Context.Current.Items.Add("ProductDetails", product);
139 }
140
141 if (Model.Item.GetString("ListComponentSource") != null)
142 {
143 <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">
144 @{
145 string clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @product.Name + "', '" + @product.VariantName + "', '" + @product.Price.CurrencyCode + "', '" + @PriceViewModelExtensions.ToStringInvariant(product.Price) + "')\"";
146 }
147 <a href="@link" class="stretched-link" onmouseover="swift.Image.swapImage(event)" onmouseout="swift.Image.swapImage(event)" @clickProductLink>
148 <span class="visually-hidden">@product.Name</span>
149 </a>
150
151 <script>
152 function clickProductLink(productId, productName, productVariant, productCurrency, productPrice) {
153 if (typeof gtag !== "undefined") {
154 gtag("event", "select_item", {
155 item_list_id: "product_list_item_repeater",
156 item_list_name: "Product list (Item Repeater)",
157 items: [
158 {
159 item_id: productId,
160 item_name: productName,
161 currency: productCurrency,
162 item_list_id: "product_list_item_repeater",
163 item_list_name: "Product list (Item Repeater)",
164 item_variant: productVariant,
165 price: productPrice
166 }
167 ]
168 });
169 }
170 }
171 </script>
172
173 @RenderGrid(itemSourcePageId)
174 </article>
175 }
176
177 productsCount++;
178 }
179 }
180 </div>
181
182 <div class="my-3" id="ProductListLoadMore">
183 <div class="text-center">
184 <div class="opacity-85 mb-3">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div>
185 @if (productList.PageCount != 1 && maxProductsCounter == 0 && loadedProducts < productList.TotalProductsCount)
186 {
187 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "";
188 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection;
189 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID") : "";
190
191 <form method="get" action="@url" data-response-target-element=".product-list" data-swap="afterend" class="w-100">
192 @if (productList?.FacetGroups != null)
193 {
194 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
195 {
196 foreach (FacetViewModel facetItem in facetGroup.Facets)
197 {
198 foreach (FacetOptionViewModel facetOption in facetItem.Options)
199 {
200 if (facetOption.Selected)
201 {
202 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]">
203 }
204 }
205 }
206 }
207 }
208
209 @if (!string.IsNullOrEmpty(searchQuery))
210 {
211 <input type="hidden" name="q" value="@searchQuery">
212 <input type="hidden" name="SearchLayout" value="@searchLayout">
213 }
214
215 @if (!string.IsNullOrEmpty(mainProductId))
216 {
217 <input type="hidden" name="MainProductID" value="@mainProductId">
218 }
219
220 @if (productList?.Group?.Id != null)
221 {
222 <input type="hidden" name="GroupId" value="@groupId">
223 }
224
225 <input type="hidden" name="OriginalPageSize" value="@pageSizeSetting">
226 <input type="hidden" name="PageSize" value="@(loadedProducts + pageSizeSetting)">
227 <input type="hidden" name="PageNum" value="@pageNumber">
228 <input type="hidden" name="SortBy" value="@sortBySelection">
229 <input type="hidden" name="RequestType" value="UpdateList">
230 <input type="hidden" name="ParagraphID" value="@Model.ID">
231
232 @if (productList?.FacetGroups is object)
233 {
234 string nextPageLink = $"/Default.aspx?ID={Pageview.Page.ID}&PageNum={pageNumber}&SortBy={sortBySelection}";
235
236 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
237 {
238 foreach (FacetViewModel facetItem in facetGroup.Facets)
239 {
240 foreach (FacetOptionViewModel facetOption in facetItem.Options)
241 {
242 if (facetOption.Selected)
243 {
244 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]";
245 }
246 }
247 }
248 }
249
250 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : "";
251 string disableLoadMore = isLazyLoadingForProductInfoEnabled ? "d-none" : "";
252
253 <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>
254 }
255 </form>
256 }
257 </div>
258 </div>
259
260 <script>
261 function switchVariantProduct(id, price, imagesrc) {
262 var productImageElement = document.querySelector("#ProductImage_" + id);
263 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price");
264
265 if (productPriceElement) {
266 productPriceElement.innerText = price;
267 }
268
269 if (productImageElement) {
270 productImageElement.src = imagesrc;
271
272 var imageSrcset = productImageElement.srcset;
273 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&");
274
275 productImageElement.srcset = imageSrcset;
276 }
277 }
278 </script>
279 }
280 else if (Pageview.IsVisualEditorMode)
281 {
282 <div class="alert alert-dark m-0" role="alert">
283 <span>@Translate("The selected component does not exist anymore")</span>
284 </div>
285 }
286 }
287 else
288 {
289 string noProductsFoundMessage = !string.IsNullOrEmpty(Model.Item.GetString("NoProductsFoundMessage")) ? Model.Item.GetString("NoProductsFoundMessage") : Translate("We did not find anything matching your search result");
290 bool hasSubgroups = false;
291
292 if (productList.SubGroups != null)
293 {
294 hasSubgroups = productList.SubGroups.Any();
295 }
296
297 if (!Model.Item.GetBoolean("HideNoProductsFoundMessage"))
298 {
299 if (!isVisualEditor)
300 {
301 <div class="alert alert-dark m-0" role="alert">
302 @noProductsFoundMessage
303 </div>
304 }
305 else
306 {
307 <div class="alert alert-dark m-0" role="alert">
308 @Translate("Product list: The list will be shown here, if any")
309 </div>
310 }
311 }
312 else if (!hasSubgroups)
313 {
314 <div class="alert alert-dark m-0" role="alert">
315 @noProductsFoundMessage
316 </div>
317 }
318 }
319 }
320 </div>
321 }
322 else if (Pageview.IsVisualEditorMode)
323 {
324 <div class="alert alert-dark m-0" role="alert">
325 <span>@Translate("Product list item repeater: The repeater paragraph will be shown here, if any products are available")</span>
326 </div>
327 }
328