Contact

MST 450 - Masking tape coral 110° 50mm x 50m 24p.

MST 450

Key features

    • Excellent adhesion on all surfaces, also on plastic and rubber
    • Perfect ‘tape on tape’ adhesion
    • Easy application on curved profiles and irregular surfaces
    • Entirely saturated, compatible with solvent- and water-based paints 
    • Suited for IR and UV drying
    • Easily removable, no residue
    • Temperature resistant: 10 minutes at 110°C, 30 minutes at 90°C, 1 hour at 80°C
    • Thickness: 132 micron
    • Adhesive strength on steel: 4,6 N/25mm

Product details

Width (mm)

Colour
coral
Dry storage
yes
Freezing resistant
yes
Adhesive type
natural rubber resin
Application surfaces
steel E-coating galvanized steel aluminum aluminium RIMS fiberglass hard plastic soft plastic chrome rubber new paint good paint neglected paint matt paint gelcoat putty primer/filler OEM paint refinish paint wood zinc enamel ceramic copper lead stainless steel high-pressure laminate stone polyethylene polypropylene polycarbonate polymethyl methacrylate polytetrafluoroethylene chlorides thermosetting composites carbon fiber thermoplastics coated metals
Backing material
crêpe paper
Backing weight
62 g/m²
Elongation
10 %
Heat resistance - 10 min
110 °C
Heat resistance - 30 min
100 °C
Heat resistance - 60 min
80 °C
Length
50 m
Peel adhesion
4.6 N/25mm
Saturated
yes
Thickness
132 µm
Type
roll
Use on surface form
flat curved strongly curved
Use with paint type
water-based solvent-based
Waterproof
yes
Width
50 mm
Workable surface state
dry
Material
crepe paper
Number
MST 450
Storing condition
dark
Sales unit
1
Units for outer box
1
Units for pallet
36
Tensile Strength (N)
105 N/25mm
Shelf life
24 months
DETAIL28792 https://www.youtube.com/embed/UQnWNREr_pQ?origin=https://plyr.io&iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1 https://www.youtube.com/embed/UQnWNREr_pQ?origin=https://plyr.io&iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1
Error compiling template "Designs/Swift/Paragraph/Finixa_ProductDetailsMediaTable.cshtml"
Line 354: The name 'RenderAsset' does not exist in the current context
Line 541: The name 'helper' does not exist in the current context
Line 549: The name 'theme' does not exist in the current context
Line 555: The name 'assetValue' does not exist in the current context
Line 557: The name 'RenderDocument' does not exist in the current context
Line 557: The name 'asset' does not exist in the current context
Line 562: The name 'helper' does not exist in the current context
Line 577: The name 'imageLinkPath' does not exist in the current context
Line 581: The name 'ratioSettings' does not exist in the current context
Line 582: The name 'ratioSettings' does not exist in the current context
Line 585: The name 'ratioSettings' does not exist in the current context
Line 589: The name 'productName' does not exist in the current context
Line 592: The name 'asset' does not exist in the current context
Line 596: The name 'imagePath' does not exist in the current context
Line 600: The name 'productName' does not exist in the current context
Line 603: The name 'assetTitle' does not exist in the current context
Line 609: The name 'iconPath' does not exist in the current context
Line 178: The variable 'iconPath' is assigned but its value is never used

1 // <auto-generated/> 2 #pragma warning disable 1591 3 namespace CompiledRazorTemplates.Dynamic 4 { 5 #line hidden 6 using System.Threading.Tasks; 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Dynamicweb.Ecommerce.ProductCatalog; 11 using System.Text.RegularExpressions; 12 using System.IO; 13 internal class RazorEngine_1b7af4df0a9b4bdda6e4e3716b4bcc83 : Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 14 { 15 #pragma warning disable 1998 16 public async override global::System.Threading.Tasks.Task ExecuteAsync() 17 { 18 WriteLiteral("\r\n"); 19 20 ProductViewModel product = null; 21 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 22 { 23 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 24 } 25 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 26 { 27 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 28 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 29 if (productList?.Products is object) 30 { 31 product = productList.Products[0]; 32 } 33 } 34 string siteLanguage = Pageview.Area.CultureInfo.Name; 35 36 37 int pageId = Dynamicweb.Context.Current.Request["CurrentPageID"] != null ? Convert.ToInt32(Dynamicweb.Context.Current.Request["CurrentPageID"]) : Pageview.ID; 38 var currentPage = Dynamicweb.Content.Services.Pages.GetPage(pageId); 39 List<Dynamicweb.Content.Page> websiteLanguages = new List<Dynamicweb.Content.Page>(); 40 if (currentPage.Area.IsMaster) 41 { 42 websiteLanguages.Add(currentPage); // Add master language 43 if (currentPage.Languages != null) 44 { 45 foreach (var lang in currentPage.Languages) 46 { 47 if (lang.Area.Active == true) // Filter active languages 48 { 49 websiteLanguages.Add(lang); 50 } 51 } 52 } 53 } 54 else 55 { 56 websiteLanguages.Add(currentPage.MasterPage); // Add master page 57 if (currentPage.MasterPage != null && currentPage.MasterPage.Languages != null) 58 { 59 foreach (var lang in currentPage.MasterPage.Languages) 60 { 61 if (lang.Area.Active == true) 62 { 63 websiteLanguages.Add(lang); 64 } 65 } 66 } 67 } 68 69 70 var ecomLanguages = Dynamicweb.Ecommerce.Services.Languages.GetLanguages(); 71 List<Dynamicweb.Ecommerce.International.Language> activeLanguages = new List<Dynamicweb.Ecommerce.International.Language>(); 72 73 74 foreach (var websiteLanguage in websiteLanguages) 75 { 76 var matchingEcomLanguage = ecomLanguages.FirstOrDefault(ecomLang => 77 string.Equals(ecomLang.Culture, websiteLanguage.Area.CultureInfo.Name, StringComparison.OrdinalIgnoreCase) || 78 string.Equals(ecomLang.Code, websiteLanguage.Area.CultureInfo.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase)); 79 80 if (matchingEcomLanguage != null && !activeLanguages.Contains(matchingEcomLanguage)) 81 { 82 activeLanguages.Add(matchingEcomLanguage); 83 } 84 } 85 86 if (activeLanguages.Count == 0) 87 { 88 activeLanguages = ecomLanguages.ToList(); 89 } 90 if (product is object) 91 { 92 93 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 94 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 95 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", ".pptx", ".igs", ".ipt", ".sat", ".stp", ".dwg", ".dxf", ".dwf" }; 96 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 97 98 99 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 100 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 101 102 103 Dynamicweb.Ecommerce.Products.ProductService ps = new Dynamicweb.Ecommerce.Products.ProductService(); 104 Dynamicweb.Ecommerce.Products.DetailsGroupService dgs = new Dynamicweb.Ecommerce.Products.DetailsGroupService(); 105 106 List<ewiMediaViewModel> productAssets = new List<ewiMediaViewModel>(); 107 List<Dynamicweb.Ecommerce.Products.Product> products = new List<Dynamicweb.Ecommerce.Products.Product>(); 108 foreach (var language in ecomLanguages) 109 { 110 var productitem = ps.GetProductById(product.Id, product.VariantId, language.LanguageId); 111 if (productitem is object) 112 { 113 Dynamicweb.Ecommerce.Products.DetailService detailService = new Dynamicweb.Ecommerce.Products.DetailService(); 114 115 foreach (var detail in detailService.GetDetails(productitem)) 116 { 117 if (detail.LanguageId == language.LanguageId) 118 { 119 Dynamicweb.Ecommerce.Products.DetailsGroup detailsGroup = dgs.GetById(detail.GroupId); 120 121 if (selectedAssetCategories.Contains(detailsGroup.SystemName)) 122 { 123 // Check if this language is already in activeLanguages before adding 124 if (!activeLanguages.Any(al => al.LanguageId == language.LanguageId)) 125 { 126 activeLanguages.Add(language); 127 } 128 129 ewiMediaViewModel productAsset = new ewiMediaViewModel(); 130 productAsset.Value = detail.Value; 131 productAsset.AssetSystemName = detailsGroup.SystemName; 132 productAsset.LanguageId = detail.LanguageId; 133 productAsset.LanguageName = language.NativeName; 134 productAsset.DisplayName = detail.Name; 135 productAssets.Add(productAsset); 136 } 137 } 138 } 139 } 140 } 141 142 143 144 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 145 IEnumerable<MediaViewModel> assetsImages = selectedAssetCategories != null ? 146 product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets) : 147 product.AssetCategories.SelectMany(x => x.Assets); 148 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 149 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 150 assetsList = productAssets.Cast<MediaViewModel>(); 151 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 152 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 153 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 154 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 155 int totalAssets = 0; 156 if (showOnlyPrimaryImage == false) { 157 foreach (MediaViewModel asset in assetsList) { 158 var assetValue = asset.Value; 159 foreach (string format in allSupportedFormats) { 160 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 161 totalAssets++; 162 } 163 } 164 } 165 } 166 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories?.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null)) 167 { 168 assetsList = new List<MediaViewModel>(){ product.DefaultImage }; 169 totalAssets = 1; 170 } 171 172 string spacing = Model.Item.GetRawValueString("Spacing", "p-0"); 173 spacing = spacing == "none" ? "p-0" : spacing; 174 spacing = spacing == "small" ? "p-3" : spacing; 175 spacing = spacing == "large" ? "p-5" : spacing; 176 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 177 bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails"); 178 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 179 int modalVideoNumber = 0; 180 181 if (totalAssets != 0 && assetsList.Any()) 182 { 183 WriteLiteral(" <div"); 184 BeginWriteAttribute("class", " class=\"", 11880, "\"", 11942, 4); 185 WriteAttributeValue("", 11888, spacing, 11888, 8, false); 186 WriteAttributeValue("", 11896, theme, 11896, 8, false); 187 WriteAttributeValue(" ", 11904, "item_", 11905, 6, true); 188 WriteAttributeValue("", 11910, Model.Item.SystemName.ToLower(), 11910, 32, false); 189 EndWriteAttribute(); 190 WriteLiteral(">\r\n"); 191 if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 192 { 193 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 194 WriteLiteral(" <h3"); 195 BeginWriteAttribute("class", " class=\"", 12184, "\"", 12211, 2); 196 WriteAttributeValue("", 12192, titleFontSize, 12192, 14, false); 197 WriteAttributeValue(" ", 12206, "mb-3", 12207, 5, true); 198 EndWriteAttribute(); 199 WriteLiteral(">\r\n "); 200 Write(Model.Item.GetString("Title")); 201 WriteLiteral("\r\n </h3>\r\n"); 202 } 203 if (activeLanguages.Count > 1) 204 { 205 206 // Filter activeLanguages als deze taal assets bevat 207 var languagesWithAssets = new List<Dynamicweb.Ecommerce.International.Language>(); 208 209 foreach (var lang in activeLanguages) 210 { 211 bool hasAssets = false; 212 foreach (MediaViewModel asset in assetsList) 213 { 214 try { 215 if (asset.GetType().GetProperty("LanguageId") != null) 216 { 217 var assetLangId = asset.GetType().GetProperty("LanguageId").GetValue(asset)?.ToString() ?? ""; 218 if (assetLangId == lang.LanguageId) 219 { 220 hasAssets = true; 221 break; 222 } 223 } 224 } catch { } 225 } 226 227 if (hasAssets) 228 { 229 languagesWithAssets.Add(lang); 230 } 231 } 232 233 Dynamicweb.Ecommerce.International.Language currentLanguage = null; 234 string currentLanguageValue = "ALL"; 235 236 // Toon enkel de taal dropdown als er meer dan 1 taal is met assets 237 if (languagesWithAssets.Count > 1) 238 { 239 240 currentLanguage = languagesWithAssets.FirstOrDefault(lang => 241 string.Equals(lang.Culture, siteLanguage, StringComparison.OrdinalIgnoreCase)) ?? 242 languagesWithAssets.FirstOrDefault(lang => 243 string.Equals(lang.NativeName, "English", StringComparison.OrdinalIgnoreCase)) ?? 244 languagesWithAssets.FirstOrDefault(); 245 246 // Map English naar LANG1 247 currentLanguageValue = currentLanguage != null && 248 string.Equals(currentLanguage.NativeName, "English", StringComparison.OrdinalIgnoreCase) 249 ? "LANG1" : currentLanguage?.LanguageId ?? "ALL"; 250 } 251 if (languagesWithAssets.Count > 1) 252 { 253 WriteLiteral(" <div class=\"mb-3\">\r\n <div class=\"mb-1\">"); 254 Write(Translate("Language")); 255 WriteLiteral(@"</div> 256 <div class=""dropdown js-dropdown""> 257 <button class=""form-select text-start w-100 js-dropdown-btn"" type=""button"" data-bs-toggle=""dropdown"" data-bs-auto-close=""outside"" aria-expanded=""false""> 258 "); 259 Write(currentLanguage?.NativeName ?? "All"); 260 WriteLiteral(@" 261 </button> 262 <div class=""dropdown-menu w-100 p-3""> 263 <div class=""form-check""> 264 <input class=""form-check-input"" type=""checkbox"" name=""LanguageId"" value=""ALL"" id=""LanguageCheckAll"" onchange=""filterResults('ALL', event);""> 265 <label class=""form-check-label"" for=""LanguageCheckAll""> 266 "); 267 Write(Translate("All")); 268 WriteLiteral("\r\n </label>\r\n </div>\r\n"); 269 foreach (var language in languagesWithAssets.GroupBy(l => l.NativeName).Select(g => g.First())) 270 { 271 string languageValue = string.Equals(language.NativeName, "English", StringComparison.OrdinalIgnoreCase) 272 ? "LANG1" : language.LanguageId; 273 bool isCurrentLanguage = language == currentLanguage; 274 WriteLiteral(" <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" name=\"LanguageId\" data-short-name=\""); 275 Write(language.NativeName); 276 WriteLiteral("\""); 277 BeginWriteAttribute("value", " value=\"", 16671, "\"", 16693, 1); 278 WriteAttributeValue("", 16679, languageValue, 16679, 14, false); 279 EndWriteAttribute(); 280 BeginWriteAttribute("id", " id=\"", 16694, "\"", 16719, 2); 281 WriteAttributeValue("", 16699, "Check_", 16699, 6, true); 282 WriteAttributeValue("", 16705, languageValue, 16705, 14, false); 283 EndWriteAttribute(); 284 WriteLiteral(" "); 285 Write(isCurrentLanguage ? "checked" : ""); 286 WriteLiteral(" onchange=\"filterResults(\'"); 287 Write(languageValue); 288 WriteLiteral("\', event);\">\r\n <label class=\"form-check-label\""); 289 BeginWriteAttribute("for", " for=\"", 16883, "\"", 16909, 2); 290 WriteAttributeValue("", 16889, "Check_", 16889, 6, true); 291 WriteAttributeValue("", 16895, languageValue, 16895, 14, false); 292 EndWriteAttribute(); 293 WriteLiteral(">\r\n "); 294 Write(language.NativeName); 295 WriteLiteral("\r\n </label>\r\n </div>\r\n"); 296 } 297 WriteLiteral(" </div>\r\n </div>\r\n </div>\r\n"); 298 } 299 } 300 WriteLiteral(" <div class=\"table-responsive\">\r\n <table class=\"table table-hover align-middle mb-0\" style=\"table-layout: fixed;\" id=\"assets-table\">\r\n <thead>\r\n <tr>\r\n"); 301 if (!hideThumbnails) 302 { 303 WriteLiteral(" <th style=\"width:60px\">&nbsp;</th>\r\n"); 304 } 305 WriteLiteral(" <th>"); 306 Write(Translate("Name")); 307 WriteLiteral("</th>\r\n <th>"); 308 Write(Translate("Asset type")); 309 WriteLiteral("</th>\r\n <th>"); 310 Write(Translate("Language")); 311 WriteLiteral("</th>\r\n <th class=\"text-end\" style=\"width:100px\">"); 312 Write(Translate("File type")); 313 WriteLiteral("</th>\r\n <th class=\"text-end d-none d-lg-table-cell\">"); 314 Write(Translate("Download")); 315 WriteLiteral("</th>\r\n </tr>\r\n </thead>\r\n <tbody class=\"border-top-0\">\r\n"); 316 foreach (ewiMediaViewModel asset in productAssets) 317 { 318 var assetValue = asset.Value; 319 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); 320 321 // Skip videos 322 bool isVideo = false; 323 foreach (string format in supportedVideoFormats) 324 { 325 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 326 { 327 isVideo = true; 328 } 329 } 330 331 // Only process non-video files 332 if (!isVideo) 333 { 334 // Check if file exists 335 string filePath = Dynamicweb.Context.Current.Server.MapPath(assetValue); 336 if (File.Exists(filePath)) 337 { 338 // Check if it's a supported format 339 if (allSupportedFormats.Any(format => assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)) 340 { 341 // Get file extension 342 string fileExtension = Path.GetExtension(assetValue).ToLower(); 343 344 // Map English to LANG1 for filtering 345 string languageId = string.Equals(asset.LanguageName, "English", StringComparison.OrdinalIgnoreCase) ? "LANG1" : asset.LanguageId; 346 347 WriteLiteral(" <tr data-language-ids=\""); 348 Write(languageId); 349 WriteLiteral("\" data-language-name=\""); 350 Write(asset.LanguageName); 351 WriteLiteral("\">\r\n"); 352 if (!hideThumbnails) 353 { 354 Write(RenderAsset(asset)); 355 356 } 357 WriteLiteral(" <td>\r\n <a"); 358 BeginWriteAttribute("href", " href=\"", 20587, "\"", 20605, 1); 359 WriteAttributeValue("", 20594, assetValue, 20594, 11, false); 360 EndWriteAttribute(); 361 WriteLiteral(" class=\"text-decoration-none text-break\""); 362 BeginWriteAttribute("download", " download=\"", 20646, "\"", 20667, 1); 363 WriteAttributeValue("", 20657, assetName, 20657, 10, false); 364 EndWriteAttribute(); 365 BeginWriteAttribute("title", " title=\"", 20668, "\"", 20686, 1); 366 WriteAttributeValue("", 20676, assetName, 20676, 10, false); 367 EndWriteAttribute(); 368 WriteLiteral(">\r\n "); 369 Write(assetName); 370 WriteLiteral("\r\n </a>\r\n </td>\r\n <td>"); 371 Write(asset.AssetSystemName); 372 WriteLiteral("</td>\r\n <td>"); 373 Write(asset.LanguageName); 374 WriteLiteral("</td>\r\n <td class=\"text-end\">"); 375 Write(fileExtension); 376 WriteLiteral("</td>\r\n <td class=\"text-end d-none d-lg-table-cell\">\r\n <a"); 377 BeginWriteAttribute("href", " href=\"", 21236, "\"", 21254, 1); 378 WriteAttributeValue("", 21243, assetValue, 21243, 11, false); 379 EndWriteAttribute(); 380 WriteLiteral(" class=\"download-button\""); 381 BeginWriteAttribute("download", " download=\"", 21279, "\"", 21300, 1); 382 WriteAttributeValue("", 21290, assetName, 21290, 10, false); 383 EndWriteAttribute(); 384 BeginWriteAttribute("title", " title=\"", 21301, "\"", 21319, 1); 385 WriteAttributeValue("", 21309, assetName, 21309, 10, false); 386 EndWriteAttribute(); 387 WriteLiteral(">\r\n "); 388 Write(Translate("Download")); 389 WriteLiteral("\r\n </a>\r\n </td>\r\n </tr>\r\n"); 390 } 391 } 392 } 393 } 394 WriteLiteral(@" </tbody> 395 </table> 396 </div> 397 <script> 398 function filterResults(selectedLang, event) { 399 console.log('Filtering by language:', selectedLang); 400 401 // Prevent event bubbling 402 if (event) { 403 event.stopPropagation(); 404 } 405 406 const table = document.getElementById('assets-table'); 407 const rows = table.querySelectorAll('tbody tr'); 408 const button = document.querySelector('.js-dropdown-btn'); 409 410 const checkedBoxes = document.querySelectorAll('input[name=""LanguageId""]:checked'); 411 const checkedLanguages = Array.from(checkedBoxes).map(cb => cb.value); 412 413 // Handle ""All"" checkbox behavior - if ""All"" is checked, uncheck others 414 if (selecte"); 415 WriteLiteral(@"dLang === 'ALL') { 416 const allCheckbox = document.querySelector('input[value=""ALL""]'); 417 if (allCheckbox && allCheckbox.checked) { 418 // Uncheck all other checkboxes 419 document.querySelectorAll('input[name=""LanguageId""]:not([value=""ALL""])').forEach(cb => { 420 cb.checked = false; 421 }); 422 } 423 } else { 424 // If any specific language is checked, uncheck ""All"" 425 const allCheckbox = document.querySelector('input[value=""ALL""]'); 426 if (allCheckbox) { 427 allCheckbox.checked = false; 428 } 429 } 430 431 // Re-get checked languages after potential changes 432 const finalCheckedBoxes = document.querySelectorAll('input[name=""LanguageId""]:checked')"); 433 WriteLiteral(@"; 434 const finalCheckedLanguages = Array.from(finalCheckedBoxes).map(cb => cb.value); 435 436 // Update button text based on selected languages 437 if (finalCheckedLanguages.length === 0) { 438 button.textContent = '"); 439 Write(Translate("All")); 440 WriteLiteral("\';\r\n } else if (finalCheckedLanguages.includes(\'ALL\')) {\r\n button.textContent = \'"); 441 Write(Translate("All")); 442 WriteLiteral(@"'; 443 } else if (finalCheckedLanguages.length === 1) { 444 const selectedCheckbox = document.querySelector(`input[value=""${finalCheckedLanguages[0]}""]`); 445 button.textContent = selectedCheckbox ? selectedCheckbox.getAttribute('data-short-name') : 'All'; 446 } else { 447 button.textContent = `${finalCheckedLanguages.length} languages selected`; 448 } 449 450 // Filter table rows 451 rows.forEach(row => { 452 const rowLanguageIds = row.getAttribute('data-language-ids'); 453 const rowLanguageName = row.getAttribute('data-language-name'); 454 455 if (finalCheckedLanguages.length === 0 || finalCheckedLanguages.includes('ALL')) { 456 row.style.display = ''; 457 } else { 458 const shouldShow = ro"); 459 WriteLiteral(@"wLanguageIds && finalCheckedLanguages.some(lang => 460 rowLanguageIds === lang || 461 rowLanguageIds === 'ALL' 462 ); 463 464 row.style.display = shouldShow ? '' : 'none'; 465 } 466 }); 467 468 } 469 document.addEventListener('DOMContentLoaded', function() { 470 // Set initial state - apply filter for pre-checked language 471 const currentLangCheckbox = document.querySelector('input[name=""LanguageId""]:checked'); 472 if (currentLangCheckbox) { 473 filterResults(currentLangCheckbox.value); 474 } else { 475 // Default to show all if nothing is checked 476 const table = document.getElementById('assets-table'); 477 const rows = table.querySelectorAll('"); 478 WriteLiteral("tbody tr\');\r\n rows.forEach(row => {\r\n row.style.display = \'\';\r\n });\r\n }\r\n });\r\n </script>\r\n"); 479 foreach (MediaViewModel asset in assetsList) 480 { 481 var assetName = asset.Value.ToLower(); 482 foreach (string videoFormat in supportedVideoFormats) 483 { //Videos 484 if (assetName.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 485 { 486 WriteLiteral(" <div class=\"modal fade js-video-modal\""); 487 BeginWriteAttribute("id", " id=\"", 26864, "\"", 26904, 4); 488 WriteAttributeValue("", 26869, "modal_", 26869, 6, true); 489 WriteAttributeValue("", 26875, Model.ID, 26875, 11, false); 490 WriteAttributeValue("", 26886, "_", 26886, 1, true); 491 WriteAttributeValue("", 26887, modalVideoNumber, 26887, 17, false); 492 EndWriteAttribute(); 493 WriteLiteral(" tabindex=\"-1\""); 494 BeginWriteAttribute("aria-labelledby", " aria-labelledby=\"", 26919, "\"", 26996, 4); 495 WriteAttributeValue("", 26937, "productDetailsTableModalTitle_", 26937, 30, true); 496 WriteAttributeValue("", 26967, Model.ID, 26967, 11, false); 497 WriteAttributeValue("", 26978, "_", 26978, 1, true); 498 WriteAttributeValue("", 26979, modalVideoNumber, 26979, 17, false); 499 EndWriteAttribute(); 500 WriteLiteral(@" aria-hidden=""true""> 501 <div class=""modal-dialog modal-dialog-centered modal-xl""> 502 <div class=""modal-content""> 503 <div class=""modal-header visually-hidden""> 504 <h5 class=""modal-title"""); 505 BeginWriteAttribute("id", " id=\"", 27310, "\"", 27374, 4); 506 WriteAttributeValue("", 27315, "productDetailsTableModalTitle_", 27315, 30, true); 507 WriteAttributeValue("", 27345, Model.ID, 27345, 11, false); 508 WriteAttributeValue("", 27356, "_", 27356, 1, true); 509 WriteAttributeValue("", 27357, modalVideoNumber, 27357, 17, false); 510 EndWriteAttribute(); 511 WriteLiteral(">"); 512 Write(product.Title); 513 WriteLiteral(@"</h5> 514 <button type=""button"" class=""btn-close"" data-bs-dismiss=""modal"" aria-label=""Close""></button> 515 </div> 516 <div class=""modal-body p-2 p-lg-3 h-100""> 517 "); 518 519 var videoParams = GetVideoParams(asset, "modal"); 520 Write(RenderPartial("Components/VideoPlayer.cshtml", new Dynamicweb.Frontend.FileViewModel { Path = asset.Value }, videoParams)); 521 WriteLiteral(" </div>\r\n </div>\r\n </div>\r\n </div>\r\n"); 522 modalVideoNumber++; 523 } 524 } 525 } 526 WriteLiteral(" </div>\r\n"); 527 } 528 else if (Pageview.IsVisualEditorMode) 529 { 530 WriteLiteral(" <div"); 531 BeginWriteAttribute("class", " class=\"", 28344, "\"", 28364, 2); 532 WriteAttributeValue("", 28352, "h-100", 28352, 5, true); 533 WriteAttributeValue(" ", 28357, theme, 28358, 6, false); 534 EndWriteAttribute(); 535 WriteLiteral(">\r\n <div class=\"alert alert-dark m-0\">\r\n "); 536 Write(Translate("No assets are available")); 537 WriteLiteral("\r\n </div>\r\n </div>\r\n"); 538 } 539 } 540 WriteLiteral("\r\n"); 541 Write(helper); 542 WriteLiteral(@" RenderAsset(ewiMediaViewModel asset) 543 { 544 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString(""ImageTheme"")) ? "" theme "" + Model.Item.GetRawValueString(""ImageTheme"").Replace("" "", """").Trim().ToLower() : """"; 545 string assetValue = asset.Value; 546 547 <td"); 548 BeginWriteAttribute("class", " class=\"", 28803, "\"", 28824, 2); 549 WriteAttributeValue("", 28811, theme, 28811, 8, false); 550 WriteAttributeValue(" ", 28819, "px-0", 28820, 5, true); 551 EndWriteAttribute(); 552 WriteLiteral(">\r\n"); 553 foreach (string format in supportedDocumentFormats) 554 { //Documents 555 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 556 { 557 Write(RenderDocument(asset)); 558 559 } 560 } 561 WriteLiteral(" </td>\r\n}\r\n\r\n"); 562 Write(helper); 563 WriteLiteral(@" RenderDocument(ewiMediaViewModel asset) 564 { 565 string iconPath = ""/Files/Templates/Designs/Swift/Assets/icons/""; 566 string productName = product.Name; 567 productName += !string.IsNullOrEmpty(asset.DisplayName) ? "" "" + asset.DisplayName : """"; 568 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 569 string imageLinkPath = imagePath; 570 imagePath = $""/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp""; 571 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? ""title=\"""" + asset.DisplayName + ""\"""" : """"; 572 573 RatioSettings ratioSettings = GetRatioSettings(); 574 575 <a"); 576 BeginWriteAttribute("href", " href=\"", 29759, "\"", 29780, 1); 577 WriteAttributeValue("", 29766, imageLinkPath, 29766, 14, false); 578 EndWriteAttribute(); 579 BeginWriteAttribute("class", " class=\"", 29781, "\"", 29843, 3); 580 WriteAttributeValue("", 29789, "d-block", 29789, 7, true); 581 WriteAttributeValue(" ", 29796, ratioSettings.CssClass, 29797, 25, false); 582 WriteAttributeValue("", 29822, ratioSettings.Fill, 29822, 21, false); 583 EndWriteAttribute(); 584 BeginWriteAttribute("style", " style=\"", 29844, "\"", 29880, 1); 585 WriteAttributeValue("", 29852, ratioSettings.CssVariable, 29852, 28, false); 586 EndWriteAttribute(); 587 WriteLiteral(" download"); 588 BeginWriteAttribute("alt", " alt=\"", 29890, "\"", 29908, 1); 589 WriteAttributeValue("", 29896, productName, 29896, 12, false); 590 EndWriteAttribute(); 591 WriteLiteral(">\r\n"); 592 if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 593 { 594 WriteLiteral(" <div class=\"d-flex align-items-center justify-content-center overflow-hidden h-100\">\r\n <img loading=\"lazy\""); 595 BeginWriteAttribute("src", " src=\"", 30140, "\"", 30156, 1); 596 WriteAttributeValue("", 30146, imagePath, 30146, 10, false); 597 EndWriteAttribute(); 598 WriteLiteral(" class=\"mw-100 mh-100\""); 599 BeginWriteAttribute("alt", " alt=\"", 30179, "\"", 30197, 1); 600 WriteAttributeValue("", 30185, productName, 30185, 12, false); 601 EndWriteAttribute(); 602 WriteLiteral(" "); 603 Write(assetTitle); 604 WriteLiteral(" />\r\n </div>\r\n"); 605 } 606 else 607 { 608 WriteLiteral(" <div class=\"d-flex align-items-center justify-content-center overflow-hidden h-100\">\r\n <div class=\"icon-3 position-absolute\" style=\"z-index: 1\">"); 609 Write(ReadFile(iconPath + "file-text.svg")); 610 WriteLiteral("</div>\r\n </div>\r\n"); 611 } 612 WriteLiteral(" </a>\r\n}\r\n"); 613 } 614 #pragma warning restore 1998 615 616 public ProductViewModel product { get; set; } = new ProductViewModel(); 617 public string[] supportedImageFormats { get; set; } 618 public string[] supportedVideoFormats { get; set; } 619 public string[] supportedDocumentFormats { get; set; } 620 public string[] allSupportedFormats { get; set; } 621 public class RatioSettings 622 { 623 public string Ratio { get; set; } 624 public string CssClass { get; set; } 625 public string CssVariable { get; set; } 626 public string Fill { get; set; } 627 } 628 public RatioSettings GetRatioSettings() 629 { 630 var ratioSettings = new RatioSettings(); 631 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 632 ratio = ratio != "0" ? ratio : ""; 633 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 634 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 635 ratioSettings.Ratio = ratio; 636 ratioSettings.CssClass = cssClass; 637 ratioSettings.CssVariable = cssVariable; 638 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 639 return ratioSettings; 640 } 641 // PDB: eWings MediaViewModel extender 642 public class ewiMediaViewModel : MediaViewModel 643 { 644 public string LanguageId { get; set; } 645 public string LanguageName { get; set; } 646 public string AssetSystemName { get; set; } 647 } 648 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) 649 { 650 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 651 string type = GetVideoType(asset.Value); 652 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; 653 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 654 var videoParams = new Dictionary<string, object>(); 655 videoParams.Add("AssetName", asset.Name); 656 videoParams.Add("AssetVideoType", type); 657 videoParams.Add("AssetDisplayName", asset.DisplayName); 658 videoParams.Add("OpenVideoInModal", openInModal); 659 videoParams.Add("VideoAutoPlay", autoPlay); 660 videoParams.Add("Size", size); 661 videoParams.Add("Id", Model.ID); 662 return videoParams; 663 } 664 public string GetVideoType(string assetValue) 665 { 666 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; 667 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 668 type = string.IsNullOrEmpty(type) ? "selfhosted" : type; 669 return type; 670 } 671 public string GetYoutubeScreenDump(string assetValue) 672 { 673 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?"); 674 Match match = regex.Match(assetValue); 675 string videoId = match.Success ? match.Groups[1].Value : string.Empty; 676 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/mqdefault.jpg"; 677 return youtubeThumbnail; 678 } 679 } 680 } 681 #pragma warning restore 1591 682

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using System.Text.RegularExpressions; 4 @using System.IO 5 @functions { 6 public ProductViewModel product { get; set; } = new ProductViewModel(); 7 public string[] supportedImageFormats { get; set; } 8 public string[] supportedVideoFormats { get; set; } 9 public string[] supportedDocumentFormats { get; set; } 10 public string[] allSupportedFormats { get; set; } 11 public class RatioSettings 12 { 13 public string Ratio { get; set; } 14 public string CssClass { get; set; } 15 public string CssVariable { get; set; } 16 public string Fill { get; set; } 17 } 18 public RatioSettings GetRatioSettings() 19 { 20 var ratioSettings = new RatioSettings(); 21 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 22 ratio = ratio != "0" ? ratio : ""; 23 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 24 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 25 ratioSettings.Ratio = ratio; 26 ratioSettings.CssClass = cssClass; 27 ratioSettings.CssVariable = cssVariable; 28 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 29 return ratioSettings; 30 } 31 // PDB: eWings MediaViewModel extender 32 public class ewiMediaViewModel : MediaViewModel 33 { 34 public string LanguageId { get; set; } 35 public string LanguageName { get; set; } 36 public string AssetSystemName { get; set; } 37 } 38 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) 39 { 40 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 41 string type = GetVideoType(asset.Value); 42 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; 43 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 44 var videoParams = new Dictionary<string, object>(); 45 videoParams.Add("AssetName", asset.Name); 46 videoParams.Add("AssetVideoType", type); 47 videoParams.Add("AssetDisplayName", asset.DisplayName); 48 videoParams.Add("OpenVideoInModal", openInModal); 49 videoParams.Add("VideoAutoPlay", autoPlay); 50 videoParams.Add("Size", size); 51 videoParams.Add("Id", Model.ID); 52 return videoParams; 53 } 54 public string GetVideoType(string assetValue) 55 { 56 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; 57 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 58 type = string.IsNullOrEmpty(type) ? "selfhosted" : type; 59 return type; 60 } 61 public string GetYoutubeScreenDump(string assetValue) 62 { 63 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?"); 64 Match match = regex.Match(assetValue); 65 string videoId = match.Success ? match.Groups[1].Value : string.Empty; 66 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/mqdefault.jpg"; 67 return youtubeThumbnail; 68 } 69 } 70 71 @{ 72 @* Get the product data *@ 73 ProductViewModel product = null; 74 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 75 { 76 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 77 } 78 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 79 { 80 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 81 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 82 if (productList?.Products is object) 83 { 84 product = productList.Products[0]; 85 } 86 } 87 string siteLanguage = Pageview.Area.CultureInfo.Name; 88 89 @* Get active website languages first *@ 90 int pageId = Dynamicweb.Context.Current.Request["CurrentPageID"] != null ? Convert.ToInt32(Dynamicweb.Context.Current.Request["CurrentPageID"]) : Pageview.ID; 91 var currentPage = Dynamicweb.Content.Services.Pages.GetPage(pageId); 92 List<Dynamicweb.Content.Page> websiteLanguages = new List<Dynamicweb.Content.Page>(); 93 if (currentPage.Area.IsMaster) 94 { 95 websiteLanguages.Add(currentPage); // Add master language 96 if (currentPage.Languages != null) 97 { 98 foreach (var lang in currentPage.Languages) 99 { 100 if (lang.Area.Active == true) // Filter active languages 101 { 102 websiteLanguages.Add(lang); 103 } 104 } 105 } 106 } 107 else 108 { 109 websiteLanguages.Add(currentPage.MasterPage); // Add master page 110 if (currentPage.MasterPage != null && currentPage.MasterPage.Languages != null) 111 { 112 foreach (var lang in currentPage.MasterPage.Languages) 113 { 114 if (lang.Area.Active == true) 115 { 116 websiteLanguages.Add(lang); 117 } 118 } 119 } 120 } 121 122 @* Get ecommerce languages and filter by active website languages *@ 123 var ecomLanguages = Dynamicweb.Ecommerce.Services.Languages.GetLanguages(); 124 List<Dynamicweb.Ecommerce.International.Language> activeLanguages = new List<Dynamicweb.Ecommerce.International.Language>(); 125 126 @* Filter ecommerce languages to only include those corresponding to active website languages *@ 127 foreach (var websiteLanguage in websiteLanguages) 128 { 129 var matchingEcomLanguage = ecomLanguages.FirstOrDefault(ecomLang => 130 string.Equals(ecomLang.Culture, websiteLanguage.Area.CultureInfo.Name, StringComparison.OrdinalIgnoreCase) || 131 string.Equals(ecomLang.Code, websiteLanguage.Area.CultureInfo.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase)); 132 133 if (matchingEcomLanguage != null && !activeLanguages.Contains(matchingEcomLanguage)) 134 { 135 activeLanguages.Add(matchingEcomLanguage); 136 } 137 } 138 @* Fallback: if no matches found, use all ecommerce languages *@ 139 if (activeLanguages.Count == 0) 140 { 141 activeLanguages = ecomLanguages.ToList(); 142 } 143 } 144 @if (product is object) 145 { 146 @* Supported formats *@ 147 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 148 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 149 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", ".pptx", ".igs", ".ipt", ".sat", ".stp", ".dwg", ".dxf", ".dwf" }; 150 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 151 152 @* Collect the assets *@ 153 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 154 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 155 156 @* PDB: Collect the valid assets and languages *@ 157 Dynamicweb.Ecommerce.Products.ProductService ps = new Dynamicweb.Ecommerce.Products.ProductService(); 158 Dynamicweb.Ecommerce.Products.DetailsGroupService dgs = new Dynamicweb.Ecommerce.Products.DetailsGroupService(); 159 160 List<ewiMediaViewModel> productAssets = new List<ewiMediaViewModel>(); 161 List<Dynamicweb.Ecommerce.Products.Product> products = new List<Dynamicweb.Ecommerce.Products.Product>(); 162 foreach (var language in ecomLanguages) 163 { 164 var productitem = ps.GetProductById(product.Id, product.VariantId, language.LanguageId); 165 if (productitem is object) 166 { 167 Dynamicweb.Ecommerce.Products.DetailService detailService = new Dynamicweb.Ecommerce.Products.DetailService(); 168 169 foreach (var detail in detailService.GetDetails(productitem)) 170 { 171 if (detail.LanguageId == language.LanguageId) 172 { 173 Dynamicweb.Ecommerce.Products.DetailsGroup detailsGroup = dgs.GetById(detail.GroupId); 174 175 if (selectedAssetCategories.Contains(detailsGroup.SystemName)) 176 { 177 // Check if this language is already in activeLanguages before adding 178 if (!activeLanguages.Any(al => al.LanguageId == language.LanguageId)) 179 { 180 activeLanguages.Add(language); 181 } 182 183 ewiMediaViewModel productAsset = new ewiMediaViewModel(); 184 productAsset.Value = detail.Value; 185 productAsset.AssetSystemName = detailsGroup.SystemName; 186 productAsset.LanguageId = detail.LanguageId; 187 productAsset.LanguageName = language.NativeName; 188 productAsset.DisplayName = detail.Name; 189 productAssets.Add(productAsset); 190 } 191 } 192 } 193 } 194 } 195 196 197 @* Standard asset collection (existing logic) *@ 198 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 199 IEnumerable<MediaViewModel> assetsImages = selectedAssetCategories != null ? 200 product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets) : 201 product.AssetCategories.SelectMany(x => x.Assets); 202 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 203 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 204 assetsList = productAssets.Cast<MediaViewModel>(); 205 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 206 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 207 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 208 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 209 int totalAssets = 0; 210 if (showOnlyPrimaryImage == false) { 211 foreach (MediaViewModel asset in assetsList) { 212 var assetValue = asset.Value; 213 foreach (string format in allSupportedFormats) { 214 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { 215 totalAssets++; 216 } 217 } 218 } 219 } 220 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories?.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null)) 221 { 222 assetsList = new List<MediaViewModel>(){ product.DefaultImage }; 223 totalAssets = 1; 224 } 225 @* Layout settings *@ 226 string spacing = Model.Item.GetRawValueString("Spacing", "p-0"); 227 spacing = spacing == "none" ? "p-0" : spacing; 228 spacing = spacing == "small" ? "p-3" : spacing; 229 spacing = spacing == "large" ? "p-5" : spacing; 230 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 231 bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails"); 232 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 233 int modalVideoNumber = 0; 234 @* Get assets from selected categories or get all assets *@ 235 if (totalAssets != 0 && assetsList.Any()) 236 { 237 <div class="@spacing@(theme) item_@Model.Item.SystemName.ToLower()"> 238 @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 239 { 240 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 241 <h3 class="@titleFontSize mb-3"> 242 @Model.Item.GetString("Title") 243 </h3> 244 } 245 @if (activeLanguages.Count > 1) 246 { 247 @{ 248 // Filter activeLanguages als deze taal assets bevat 249 var languagesWithAssets = new List<Dynamicweb.Ecommerce.International.Language>(); 250 251 foreach (var lang in activeLanguages) 252 { 253 bool hasAssets = false; 254 foreach (MediaViewModel asset in assetsList) 255 { 256 try { 257 if (asset.GetType().GetProperty("LanguageId") != null) 258 { 259 var assetLangId = asset.GetType().GetProperty("LanguageId").GetValue(asset)?.ToString() ?? ""; 260 if (assetLangId == lang.LanguageId) 261 { 262 hasAssets = true; 263 break; 264 } 265 } 266 } catch { } 267 } 268 269 if (hasAssets) 270 { 271 languagesWithAssets.Add(lang); 272 } 273 } 274 275 Dynamicweb.Ecommerce.International.Language currentLanguage = null; 276 string currentLanguageValue = "ALL"; 277 278 // Toon enkel de taal dropdown als er meer dan 1 taal is met assets 279 if (languagesWithAssets.Count > 1) 280 { 281 282 currentLanguage = languagesWithAssets.FirstOrDefault(lang => 283 string.Equals(lang.Culture, siteLanguage, StringComparison.OrdinalIgnoreCase)) ?? 284 languagesWithAssets.FirstOrDefault(lang => 285 string.Equals(lang.NativeName, "English", StringComparison.OrdinalIgnoreCase)) ?? 286 languagesWithAssets.FirstOrDefault(); 287 288 // Map English naar LANG1 289 currentLanguageValue = currentLanguage != null && 290 string.Equals(currentLanguage.NativeName, "English", StringComparison.OrdinalIgnoreCase) 291 ? "LANG1" : currentLanguage?.LanguageId ?? "ALL"; 292 } 293 } 294 295 @if (languagesWithAssets.Count > 1) 296 { 297 <div class="mb-3"> 298 <div class="mb-1">@Translate("Language")</div> 299 <div class="dropdown js-dropdown"> 300 <button class="form-select text-start w-100 js-dropdown-btn" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"> 301 @(currentLanguage?.NativeName ?? "All") 302 </button> 303 <div class="dropdown-menu w-100 p-3"> 304 <div class="form-check"> 305 <input class="form-check-input" type="checkbox" name="LanguageId" value="ALL" id="LanguageCheckAll" onchange="filterResults('ALL', event);"> 306 <label class="form-check-label" for="LanguageCheckAll"> 307 @Translate("All") 308 </label> 309 </div> 310 @foreach (var language in languagesWithAssets.GroupBy(l => l.NativeName).Select(g => g.First())) 311 { 312 string languageValue = string.Equals(language.NativeName, "English", StringComparison.OrdinalIgnoreCase) 313 ? "LANG1" : language.LanguageId; 314 bool isCurrentLanguage = language == currentLanguage; 315 <div class="form-check"> 316 <input class="form-check-input" type="checkbox" name="LanguageId" data-short-name="@language.NativeName" value="@languageValue" id="Check_@languageValue" @(isCurrentLanguage ? "checked" : "") onchange="filterResults('@languageValue', event);"> 317 <label class="form-check-label" for="Check_@languageValue"> 318 @language.NativeName 319 </label> 320 </div> 321 } 322 </div> 323 </div> 324 </div> 325 } 326 } 327 <div class="table-responsive"> 328 <table class="table table-hover align-middle mb-0" style="table-layout: fixed;" id="assets-table"> 329 <thead> 330 <tr> 331 @if (!hideThumbnails) 332 { 333 <th style="width:60px">&nbsp;</th> 334 } 335 <th>@Translate("Name")</th> 336 <th>@Translate("Asset type")</th> 337 <th>@Translate("Language")</th> 338 <th class="text-end" style="width:100px">@Translate("File type")</th> 339 <th class="text-end d-none d-lg-table-cell">@Translate("Download")</th> 340 </tr> 341 </thead> 342 <tbody class="border-top-0"> 343 @foreach (ewiMediaViewModel asset in productAssets) 344 { 345 var assetValue = asset.Value; 346 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); 347 348 // Skip videos 349 bool isVideo = false; 350 foreach (string format in supportedVideoFormats) 351 { 352 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 353 { 354 isVideo = true; 355 } 356 } 357 358 // Only process non-video files 359 if (!isVideo) 360 { 361 // Check if file exists 362 string filePath = Dynamicweb.Context.Current.Server.MapPath(assetValue); 363 if (File.Exists(filePath)) 364 { 365 // Check if it's a supported format 366 if (allSupportedFormats.Any(format => assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0)) 367 { 368 // Get file extension 369 string fileExtension = Path.GetExtension(assetValue).ToLower(); 370 371 // Map English to LANG1 for filtering 372 string languageId = string.Equals(asset.LanguageName, "English", StringComparison.OrdinalIgnoreCase) ? "LANG1" : asset.LanguageId; 373 374 <tr data-language-ids="@languageId" data-language-name="@asset.LanguageName"> 375 @if (!hideThumbnails) 376 { 377 @RenderAsset(asset) 378 } 379 <td> 380 <a href="@assetValue" class="text-decoration-none text-break" download="@assetName" title="@assetName"> 381 @assetName 382 </a> 383 </td> 384 <td>@asset.AssetSystemName</td> 385 <td>@asset.LanguageName</td> 386 <td class="text-end">@fileExtension</td> 387 <td class="text-end d-none d-lg-table-cell"> 388 <a href="@assetValue" class="download-button" download="@assetName" title="@assetName"> 389 @Translate("Download") 390 </a> 391 </td> 392 </tr> 393 } 394 } 395 } 396 } 397 </tbody> 398 </table> 399 </div> 400 <script> 401 function filterResults(selectedLang, event) { 402 console.log('Filtering by language:', selectedLang); 403 404 // Prevent event bubbling 405 if (event) { 406 event.stopPropagation(); 407 } 408 409 const table = document.getElementById('assets-table'); 410 const rows = table.querySelectorAll('tbody tr'); 411 const button = document.querySelector('.js-dropdown-btn'); 412 413 const checkedBoxes = document.querySelectorAll('input[name="LanguageId"]:checked'); 414 const checkedLanguages = Array.from(checkedBoxes).map(cb => cb.value); 415 416 // Handle "All" checkbox behavior - if "All" is checked, uncheck others 417 if (selectedLang === 'ALL') { 418 const allCheckbox = document.querySelector('input[value="ALL"]'); 419 if (allCheckbox && allCheckbox.checked) { 420 // Uncheck all other checkboxes 421 document.querySelectorAll('input[name="LanguageId"]:not([value="ALL"])').forEach(cb => { 422 cb.checked = false; 423 }); 424 } 425 } else { 426 // If any specific language is checked, uncheck "All" 427 const allCheckbox = document.querySelector('input[value="ALL"]'); 428 if (allCheckbox) { 429 allCheckbox.checked = false; 430 } 431 } 432 433 // Re-get checked languages after potential changes 434 const finalCheckedBoxes = document.querySelectorAll('input[name="LanguageId"]:checked'); 435 const finalCheckedLanguages = Array.from(finalCheckedBoxes).map(cb => cb.value); 436 437 // Update button text based on selected languages 438 if (finalCheckedLanguages.length === 0) { 439 button.textContent = '@Translate("All")'; 440 } else if (finalCheckedLanguages.includes('ALL')) { 441 button.textContent = '@Translate("All")'; 442 } else if (finalCheckedLanguages.length === 1) { 443 const selectedCheckbox = document.querySelector(`input[value="${finalCheckedLanguages[0]}"]`); 444 button.textContent = selectedCheckbox ? selectedCheckbox.getAttribute('data-short-name') : 'All'; 445 } else { 446 button.textContent = `${finalCheckedLanguages.length} languages selected`; 447 } 448 449 // Filter table rows 450 rows.forEach(row => { 451 const rowLanguageIds = row.getAttribute('data-language-ids'); 452 const rowLanguageName = row.getAttribute('data-language-name'); 453 454 if (finalCheckedLanguages.length === 0 || finalCheckedLanguages.includes('ALL')) { 455 row.style.display = ''; 456 } else { 457 const shouldShow = rowLanguageIds && finalCheckedLanguages.some(lang => 458 rowLanguageIds === lang || 459 rowLanguageIds === 'ALL' 460 ); 461 462 row.style.display = shouldShow ? '' : 'none'; 463 } 464 }); 465 466 } 467 document.addEventListener('DOMContentLoaded', function() { 468 // Set initial state - apply filter for pre-checked language 469 const currentLangCheckbox = document.querySelector('input[name="LanguageId"]:checked'); 470 if (currentLangCheckbox) { 471 filterResults(currentLangCheckbox.value); 472 } else { 473 // Default to show all if nothing is checked 474 const table = document.getElementById('assets-table'); 475 const rows = table.querySelectorAll('tbody tr'); 476 rows.forEach(row => { 477 row.style.display = ''; 478 }); 479 } 480 }); 481 </script> 482 @foreach (MediaViewModel asset in assetsList) 483 { 484 var assetName = asset.Value.ToLower(); 485 foreach (string videoFormat in supportedVideoFormats) 486 { //Videos 487 if (assetName.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 488 { 489 <div class="modal fade js-video-modal" id="modal_@(Model.ID)_@modalVideoNumber" tabindex="-1" aria-labelledby="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber" aria-hidden="true"> 490 <div class="modal-dialog modal-dialog-centered modal-xl"> 491 <div class="modal-content"> 492 <div class="modal-header visually-hidden"> 493 <h5 class="modal-title" id="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber">@product.Title</h5> 494 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 495 </div> 496 <div class="modal-body p-2 p-lg-3 h-100"> 497 @{ 498 var videoParams = GetVideoParams(asset, "modal"); 499 @RenderPartial("Components/VideoPlayer.cshtml", new Dynamicweb.Frontend.FileViewModel { Path = asset.Value }, videoParams) 500 } 501 </div> 502 </div> 503 </div> 504 </div> 505 modalVideoNumber++; 506 } 507 } 508 } 509 </div> 510 } 511 else if (Pageview.IsVisualEditorMode) 512 { 513 <div class="h-100 @theme"> 514 <div class="alert alert-dark m-0"> 515 @Translate("No assets are available") 516 </div> 517 </div> 518 } 519 } 520 521 @helper RenderAsset(ewiMediaViewModel asset) 522 { 523 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 524 string assetValue = asset.Value; 525 526 <td class="@(theme) px-0"> 527 @foreach (string format in supportedDocumentFormats) 528 { //Documents 529 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 530 { 531 @RenderDocument(asset) 532 } 533 } 534 </td> 535 } 536 537 @helper RenderDocument(ewiMediaViewModel asset) 538 { 539 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 540 string productName = product.Name; 541 productName += !string.IsNullOrEmpty(asset.DisplayName) ? " " + asset.DisplayName : ""; 542 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 543 string imageLinkPath = imagePath; 544 imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; 545 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 546 547 RatioSettings ratioSettings = GetRatioSettings(); 548 549 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName"> 550 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 551 { 552 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 553 <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle /> 554 </div> 555 } 556 else 557 { 558 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 559 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 560 </div> 561 } 562 </a> 563 } 564
By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Statistics and Marketing