Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts.cshtml"
System.Exception: The Client Secret is expired. Visit the Azure portal to create new keys for your '6945a908-9a4b-44fa-9ced-6fa84bd4a866' app. GetTokenForClientCredentialsFlow failed: A configuration issue is preventing authentication - check the error message from the server for details. You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details. Original exception: AADSTS7000222: The provided client secret keys for app '6945a908-9a4b-44fa-9ced-6fa84bd4a866' are expired. Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret, or consider using certificate credentials for added security: https://aka.ms/certCreds. Trace ID: c3013e19-bd4d-44c6-b4d2-b82353601d00 Correlation ID: 86fb462e-b5b0-48b6-9af0-49613e0ca5ae Timestamp: 2025-08-19 08:37:21Z. Tenant:7dd45d63-24fc-4edd-8ad8-5fd66b6f9733 Client:6945a908-9a4b-44fa-9ced-6fa84bd4a866.
---> MSAL.NetCore.4.61.3.0.MsalServiceException:
ErrorCode: invalid_client
Microsoft.Identity.Client.MsalServiceException: A configuration issue is preventing authentication - check the error message from the server for details. You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details. Original exception: AADSTS7000222: The provided client secret keys for app '6945a908-9a4b-44fa-9ced-6fa84bd4a866' are expired. Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret, or consider using certificate credentials for added security: https://aka.ms/certCreds. Trace ID: c3013e19-bd4d-44c6-b4d2-b82353601d00 Correlation ID: 86fb462e-b5b0-48b6-9af0-49613e0ca5ae Timestamp: 2025-08-19 08:37:21Z
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders, Func`2 onBeforePostRequestData)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.<>c__DisplayClass11_1.<<RunAsync>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.Identity.Client.Utils.StopwatchService.MeasureCodeBlockAsync(Func`1 codeBlock)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
StatusCode: 401
ResponseBody: {"error":"invalid_client","error_description":"AADSTS7000222: The provided client secret keys for app '6945a908-9a4b-44fa-9ced-6fa84bd4a866' are expired. Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret, or consider using certificate credentials for added security: https://aka.ms/certCreds. Trace ID: c3013e19-bd4d-44c6-b4d2-b82353601d00 Correlation ID: 86fb462e-b5b0-48b6-9af0-49613e0ca5ae Timestamp: 2025-08-19 08:37:21Z","error_codes":[7000222],"timestamp":"2025-08-19 08:37:21Z","trace_id":"c3013e19-bd4d-44c6-b4d2-b82353601d00","correlation_id":"86fb462e-b5b0-48b6-9af0-49613e0ca5ae","error_uri":"https://login.microsoftonline.com/error?code=7000222"}
Headers: Cache-Control: no-store, no-cache
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
client-request-id: 86fb462e-b5b0-48b6-9af0-49613e0ca5ae
x-ms-request-id: c3013e19-bd4d-44c6-b4d2-b82353601d00
x-ms-ests-server: 2.1.21665.5 - WEULR1 ProdSlices
x-ms-clitelem: 1,7000222,0,,
x-ms-srs: 1.P
Content-Security-Policy-Report-Only: object-src 'none'; base-uri 'self'; script-src 'self' 'nonce-kAILHl7sKX8SSYraKgqr3g' 'unsafe-inline' 'unsafe-eval' https://*.msauth.net https://*.msftauth.net https://*.msftauthimages.net https://*.msauthimages.net https://*.msidentity.com https://*.microsoftonline-p.com https://*.microsoftazuread-sso.com https://*.azureedge.net https://*.outlook.com https://*.office.com https://*.office365.com https://*.microsoft.com https://*.bing.com 'report-sample'; report-uri https://csp.microsoft.com/report/ESTS-UX-All
X-XSS-Protection: 0
Set-Cookie: fpc=AqU8-QeNwIJMlti2wh4SU5J1fVnmFAAAAE0uNuAOAAAA; expires=Thu, 18-Sep-2025 08:37:21 GMT; path=/; secure; HttpOnly; SameSite=None, x-ms-gateway-slice=estsfd; path=/; secure; httponly
Date: Tue, 19 Aug 2025 08:37:20 GMT
--- End of inner exception stack trace ---
at Dynamicweb.DataIntegration.EndpointManagement.EndpointService.HandleException(Exception ex, Endpoint endpoint) in C:\Work\Repos\Dynamicweb10\src\Features\DataIntegration\Dynamicweb.DataIntegration\EndpointManagement\EndpointService.cs:line 668
at Dynamicweb.DataIntegration.EndpointManagement.EndpointService.GetResponse(Endpoint endpoint, String requestBody, TimeSpan requestTimeout) in C:\Work\Repos\Dynamicweb10\src\Features\DataIntegration\Dynamicweb.DataIntegration\EndpointManagement\EndpointService.cs:line 533
at DynamicwebLiveIntegration3.EndpointManager.ExecuteEndpointRequest(String urlSuffix, Object requestBody)
at DynamicwebLiveIntegration3.Caching.StockCache.FetchMissing(IEnumerable`1 keys)
at Dynamicweb.Caching.ServiceCache`2.GetCache(IEnumerable`1 keys) in C:\Work\Repos\Dynamicweb10\src\Core\Dynamicweb.Core\Caching\ServiceCache.cs:line 267
at Dynamicweb.Caching.ServiceCache`2.GetCache(TKey key) in C:\Work\Repos\Dynamicweb10\src\Core\Dynamicweb.Core\Caching\ServiceCache.cs:line 254
at DynamicwebLiveIntegration3.LiveIntegrationService.GetStock(ProductStockCacheKey productStockCacheKey, Boolean silent)
at DynamicwebLiveIntegration3.Providers.ProductStockProvider.FindStockLevel(Product product, String unitId, StockLocation stockLocation)
at Dynamicweb.Ecommerce.Stocks.StockLevelManager.FindStockLevel(Product product, String unitId, StockLocation stockLocation) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\Stocks\StockLevelManager.cs:line 25
at Dynamicweb.Ecommerce.Products.ProductExtentions.GetUnitStock(Product product, StockLocation stockLocation, String unitId) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\Products\ProductExtentions.cs:line 187
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Dynamicweb.Ecommerce.ProductCatalog.ViewModelPropertyFiller`1.Fill[S](T model, String propertyName, Func`1 source) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\ProductCatalog\ViewModelPropertyFiller.cs:line 49
at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.BulkCreateView(ProductViewModelSettings settings, Boolean isRecursive, IList`1 products) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\ProductCatalog\ViewEngine.cs:line 128
at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.CreateView(ProductListViewModelSettings settings, Group group, IList`1 products) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\ProductCatalog\ViewEngine.cs:line 586
at Dynamicweb.Ecommerce.ProductCatalog.ViewModelFactory.CreateView(ProductListViewModelSettings settings, IList`1 products, Group group) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\ProductCatalog\ViewModelFactory.cs:line 197
at Dynamicweb.Ecommerce.Content.Items.Editors.ProductCatalogEditor.GetViewModelValue(Object value) in C:\Work\Repos\Dynamicweb10\src\Features\Ecommerce\Dynamicweb.Ecommerce\Content\Items\Editors\ProductCatalogEditor.cs:line 55
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Dynamicweb.Frontend.ItemFieldViewModel.GetValue[T]() in C:\Work\Repos\Dynamicweb10\src\Features\Content\Dynamicweb\Frontend\ItemFieldViewModel.cs:line 276
at Dynamicweb.Frontend.ItemViewModel.GetValue[T](String systemName) in C:\Work\Repos\Dynamicweb10\src\Features\Content\Dynamicweb\Frontend\ItemViewModel.cs:line 769
at CompiledRazorTemplates.Dynamic.RazorEngine_190c68d3b53249ceb7b04e7921c9bb01.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 100
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) in C:\Work\Repos\Dynamicweb10\src\Core\Dynamicweb.Core\Rendering\TemplateRenderingService.cs:line 22
at Dynamicweb.Rendering.Template.RenderRazorTemplate() in C:\Work\Repos\Dynamicweb10\src\Core\Dynamicweb.Core\Rendering\Template.cs:line 694
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
@using Dynamicweb.Core
@using Dynamicweb.Ecommerce.ProductCatalog
@{
ProductViewModel product = null;
if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
{
product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
}
else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
{
var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
if (productList?.Products is object)
{
product = productList.Products[0];
}
}
string title = Model?.Item?.GetRawValueString("Title", Translate("Products"));
string campaignValues = string.Join(",", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList());
//Styling
string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3");
string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5");
string buttonStyle = Model.Item.GetRawValueString("ButtonStyle", "");
buttonStyle = buttonStyle == "primary" ? " btn-primary" : buttonStyle;
buttonStyle = buttonStyle == "secondary" ? " btn-secondary" : buttonStyle;
buttonStyle = buttonStyle == "link" ? " btn-link" : buttonStyle;
string maxWidth = Model.Item.GetRawValueString("TextReadability", "");
maxWidth = maxWidth == "max-width-on" ? " mw-75ch" : maxWidth;
maxWidth = maxWidth == "max-width-off" ? "" : maxWidth;
string generalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("GeneralTheme")) ? " theme " + Model.Item.GetRawValueString("GeneralTheme").Replace(" ", "").Trim().ToLower() : "";
string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : "";
//Link generation
string pageId = !string.IsNullOrEmpty(Model.Item.GetRawValueString("ProductSliderServicePage")) ? Model.Item.GetLink("ProductSliderServicePage").PageId.ToString() : "";
if (string.IsNullOrEmpty(pageId))
{
pageId = GetPageIdByNavigationTag("ProductSliderService").ToString();
}
string url = "/Default.aspx?ID=" + pageId;
if (!url.Contains("LayoutTemplate", StringComparison.OrdinalIgnoreCase))
{
url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml";
}
if (Pageview.IsVisualEditorMode)
{
url += "&VisualEdit=True";
}
bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]);
if (isLazyLoadingForProductInfoEnabled)
{
url += "&getproductinfo=true";
}
//Source type
string sourceType = Model.Item.GetRawValueString("RelationType", "trending");
IList<string> relateFromGroupIds = new List<string> { };
IList<string> relateFromProductVariantIds = new List<string> { };
IList<string> relateFromProductIds = new List<string> { };
bool hasVariants = false;
//--- VARIANTS ---
if (sourceType == "variants" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateToVariants") is ProductListViewModel productsToRelateToVariants)
{
foreach (var productSelection in productsToRelateToVariants.Products)
{
relateFromProductIds.Add(productSelection.Id);
}
}
//--- MOST SOLD ---
if (sourceType == "most-sold" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToMostSold") is IList<ProductGroupViewModel> groupsToRelateToMostSold)
{
foreach (var fromGroup in groupsToRelateToMostSold)
{
relateFromGroupIds.Add(fromGroup.Id);
}
}
//--- TRENDING ---
if (sourceType == "trending" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToTrending") is IList<ProductGroupViewModel> groupsToRelateToTrending)
{
foreach (var fromGroup in groupsToRelateToTrending)
{
relateFromGroupIds.Add(fromGroup.Id);
}
}
//--- LATEST ---
if (sourceType == "latest" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToLatest") is IList<ProductGroupViewModel> groupsToRelateToLatest)
{
foreach (var fromGroup in groupsToRelateToLatest)
{
relateFromGroupIds.Add(fromGroup.Id);
}
}
//--- FREQUENTLY BOUGHT ---
if (sourceType == "frequently" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo") is ProductListViewModel productsToRelateTo)
{
foreach (var fromProduct in productsToRelateTo.Products)
{
relateFromProductIds.Add(fromProduct.Id);
}
}
//--- SELECTED PRODUCTS ---
if ((sourceType == "selected" || sourceType == "frequently") && Model.Item.GetValue<ProductListViewModel>("Products") is ProductListViewModel products)
{
hasVariants = products.Products.Any(p => !string.IsNullOrEmpty(p.VariantId));
foreach (var productSelection in products.Products)
{
if (hasVariants)
{
if (!string.IsNullOrEmpty(productSelection.VariantId))
{
relateFromProductVariantIds.Add($"{productSelection.Id} {productSelection.VariantId}");
}
else
{
relateFromProductVariantIds.Add($"{productSelection.Id}");
}
}
relateFromProductIds.Add($"{productSelection.Id}");
}
}
//--- RELATED PRODUCTS ---
if (sourceType == "related-products" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo2") is ProductListViewModel selectedRelationProduct)
{
if (selectedRelationProduct.Products.Any())
{
product = selectedRelationProduct.Products.FirstOrDefault();
}
if (product?.RelatedGroups != null)
{
foreach (var group in product.RelatedGroups)
{
foreach (var relatedProduct in group.Products)
{
if (!string.IsNullOrEmpty(relatedProduct.VariantId))
{
relateFromProductVariantIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}");
}
else
{
relateFromProductVariantIds.Add($"{relatedProduct.ProductId}");
}
}
}
}
}
//Create group id collection and products id collection strings
string groupIds = product is object ? product.PrimaryOrDefaultGroup.Id : string.Join(",", relateFromGroupIds);
string productVariantIds = relateFromProductVariantIds.Count > 0 ? string.Join(",", relateFromProductVariantIds) : "";
string productIds = product is object && relateFromProductIds.Count == 0 ? product.Id : string.Join(",", relateFromProductIds);
//Set the parameters to the url
string linkParameters = "";
linkParameters += sourceType != "related-products" && sourceType != "frequently" && sourceType != "selected" ? "&GroupId=" + groupIds : "";
linkParameters += !string.IsNullOrEmpty(productIds) && sourceType != "most-sold" && sourceType != "trending" && sourceType != "latest" && sourceType != "frequently" && sourceType != "related-products" ? "&MainProductId=" + productIds : "";
linkParameters += !string.IsNullOrEmpty(productVariantIds) && sourceType == "related-products" ? "&ProductVariantId=" + productVariantIds : "";
linkParameters += sourceType == "variants" ? "&IsVariant=true" : "";
linkParameters += sourceType == "latest" ? "&SortBy=Created" : "";
linkParameters += sourceType == "most-sold" ? "&SortBy=OrderCount" : "";
linkParameters += sourceType == "trending" ? "&SortBy=OrderCountGrowth" : "";
linkParameters += !string.IsNullOrEmpty(productIds) && sourceType == "frequently" ? $"&BoughtWithProductIds=[{productIds}]" : "";
var productListPageId = GetPageIdByNavigationTag("Shop");
string link = "/Default.aspx?ID=" + productListPageId + linkParameters;
// Slider settings (documentation: swiffyslider.com/configuration)
string navigationStyle = $"{Model.Item.GetRawValueString("NavigationStyle", "slider-nav-round")}";
string navigationPlacement = $"{Model.Item.GetRawValueString("NavigationPlacement", "slider-nav-on-slides")}";
string indicatorStyle = $"{Model.Item.GetRawValueString("IndicatorStyle", "slider-indicators-hidden")}";
string revealSlides = Model.Item.GetRawValueString("RevealSlides", "no-reveal") == "reveal" ? "slider-item-reveal" : string.Empty;
string navigationAlwaysVisible = (Model.Item.GetBoolean("NavigationAlwaysVisible")) ? "slider-nav-visible" : string.Empty;
string navigationVisibleOnTouch = (Model.Item.GetBoolean("NavigationVisibleOnTouch")) ? "slider-nav-touch" : string.Empty;
string navigationShowScrollbar = (Model.Item.GetBoolean("NavigationShowScrollbar")) ? "slider-nav-scrollbar" : string.Empty;
string navigationSmall = (Model.Item.GetBoolean("NavigationSmall")) ? "slider-nav-sm" : string.Empty;
string navigationInvertColors = (Model.Item.GetBoolean("NavigationInvertColors")) ? "slider-nav-dark" : string.Empty;
string navigationSlideEntirePage = (Model.Item.GetBoolean("NavigationSlideEntirePage")) ? "slider-nav-page" : string.Empty;
string navigationNoLoop = (Model.Item.GetBoolean("NavigationNoLoop")) ? "slider-nav-noloop" : string.Empty;
string indicatorsOutsideSlider = (Model.Item.GetBoolean("IndicatorsOutsideSlider") && indicatorStyle != string.Empty) ? "slider-indicators-outside" : string.Empty;
string indicatorsHighlightActive = (Model.Item.GetBoolean("IndicatorsHighlightActive")) ? "slider-indicators-highlight" : string.Empty;
string indicatorsInvertColors = (Model.Item.GetBoolean("IndicatorsInvertedColors")) ? "slider-indicators-dark" : string.Empty;
string indicatorsVisibleOnSmallDevices = (Model.Item.GetBoolean("IndicatorsVisibleOnSmallDevices")) ? "slider-indicators-sm" : string.Empty;
bool productsFound = true;
if (string.IsNullOrEmpty(groupIds) && string.IsNullOrEmpty(productIds) && string.IsNullOrEmpty(productVariantIds))
{
if (Pageview.IsVisualEditorMode)
{
productIds = product.Id;
sourceType = "selected";
}
else
{
productsFound = false;
}
}
}
@*Container element for the request*@
@if (productsFound)
{
<form method="post" action="@url" id="RelatedProductsForm_@Model.ID" data-response-target-element="RelatedProducts_@Model.ID" data-preloader="inline" data-update-url="false" class="item_@Model.Item.SystemName.ToLower()">
<input type="hidden" name="ModelID" value="@Model.ID">
<input type="hidden" name="SourceType" value="@sourceType">
@*--- SLIDER SETTINGS ---*@
<input type="hidden" name="NavigationStyle" value="@navigationStyle">
<input type="hidden" name="NavigationPlacement" value="@navigationPlacement">
<input type="hidden" name="IndicatorStyle" value="@indicatorStyle">
<input type="hidden" name="RevealSlides" value="@revealSlides">
<input type="hidden" name="NavigationAlwaysVisible" value="@(navigationAlwaysVisible)">
<input type="hidden" name="NavigationVisibleOnTouch" value="@(navigationVisibleOnTouch)">
<input type="hidden" name="NavigationShowScrollbar" value="@(navigationShowScrollbar)">
<input type="hidden" name="NavigationSmall" value="@(navigationSmall)">
<input type="hidden" name="NavigationInvertColors" value="@(navigationInvertColors)">
<input type="hidden" name="NavigationNoLoop" value="@(navigationNoLoop)">
<input type="hidden" name="NavigationSlideEntirePage" value="@(navigationSlideEntirePage)">
<input type="hidden" name="IndicatorsOutsideSlider" value="@(indicatorsOutsideSlider)">
<input type="hidden" name="IndicatorsHighlightActive" value="@(indicatorsHighlightActive)">
<input type="hidden" name="IndicatorsInvertColors" value="@(indicatorsInvertColors)">
<input type="hidden" name="IndicatorsVisibleOnSmallDevices" value="@(indicatorsVisibleOnSmallDevices)">
@*--- VARIANTS ---*@
@if (sourceType == "variants")
{
<input type="hidden" name="isVariant" value="true">
<input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds">
}
@*--- MOST SOLD ---*@
@if (sourceType == "most-sold")
{
<input type="hidden" name="SortBy" value="OrderCount">
if (groupIds != "")
{
<input type="hidden" name="GroupId" value="@groupIds">
}
}
@*--- TRENDING ---*@
@if (sourceType == "trending")
{
<input type="hidden" name="SortBy" value="OrderCountGrowth">
if (groupIds != "")
{
<input type="hidden" name="GroupId" value="@groupIds">
}
}
@*--- FREQUENTLY BOUGHT ---*@
@if (sourceType == "frequently" && !string.IsNullOrEmpty(productIds))
{
<input type="hidden" name="BoughtWithProductIds" value="[@productIds]">
}
@if (sourceType != "frequently" && hasVariants)
{
<input type="hidden" name="ProductVariantId" value="@productVariantIds">
}
@*--- LATEST ---*@
@if (sourceType == "latest")
{
<input type="hidden" name="SortBy" value="Created">
<input type="hidden" name="GroupId" value="@groupIds">
}
@*--- SELECTED PRODUCTS ---*@
@if (sourceType == "selected" && !string.IsNullOrEmpty(productIds) && !hasVariants)
{
<input type="hidden" name="MainProductId" id="MainProductID_@Model.ID" value="@productIds">
}
@if (sourceType == "selected" && hasVariants)
{
<input type="hidden" name="ProductVariantId" value="@productVariantIds">
}
@*--- RELATED PRODUCTS ---*@
@if (sourceType == "related-products")
{
<input type="hidden" name="ProductVariantId" id="MainProductID_@Model.ID" value="@productVariantIds">
}
@* General parameters *@
<input type="hidden" name="Link" value="@link">
<input type="hidden" name="HideTitle" value="@Model.Item.GetString("HideTitle")">
@if (Model.Item.GetInt32("ProductsCount") != 0)
{
<input type="hidden" name="PageSize" value="@Model.Item.GetInt32("ProductsCount")">
}
<input type="hidden" name="HeadingTitle" id="RelatedProductsTitle_@Model.ID" value="@title">
@if (!string.IsNullOrEmpty(Model.Item.GetString("Subtitle")))
{
<input type="hidden" name="Subtitle" value="@Model.Item.GetString("Subtitle")">
}
@if (!string.IsNullOrEmpty(Model.Item.GetString("LinkText")))
{
<input type="hidden" name="LinkText" value="@Model.Item.GetString("LinkText")">
}
@if (!string.IsNullOrEmpty(Model.Item.GetString("ImageAspectRatio")))
{
string ratio = Model.Item.GetRawValueString("ImageAspectRatio", "");
ratio = ratio != "0" ? ratio : "";
<input type="hidden" name="ImageAspectRatio" value="@ratio">
}
@if (!string.IsNullOrEmpty(Model.Item.GetString("Layout")))
{
<input type="hidden" name="Layout" value="@Model.Item.GetRawValueString("Layout")">
}
@if (titleFontSize != "")
{
<input type="hidden" name="TitleFontSize" value="@titleFontSize">
}
@if (subtitleFontSize != "")
{
<input type="hidden" name="SubtitleFontSize" value="@subtitleFontSize">
}
@if (buttonStyle != "")
{
<input type="hidden" name="ButtonStyle" value="@buttonStyle">
}
@if (generalTheme != "")
{
<input type="hidden" name="GeneralTheme" value="@generalTheme">
}
@if (theme != "")
{
<input type="hidden" name="Theme" value="@theme">
}
@if (imageTheme != "")
{
<input type="hidden" name="ImageTheme" value="@imageTheme">
}
@if (!string.IsNullOrEmpty(Model.Item.GetString("ContentPadding")))
{
string contentPadding = Model.Item.GetRawValueString("ContentPadding");
<input type="hidden" name="ContentPadding" value="@contentPadding">
}
<input type="hidden" name="TextReadability" value="@maxWidth">
<input type="hidden" name="ParentColumnSize" id="ParentColumnSize_@Model.ID" value="12">
<input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")">
<input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")">
<input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")">
<input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")">
@if (campaignValues != string.Empty)
{
<input type="hidden" name="CampaignBadgesValues" value="@campaignValues">
}
</form>
<script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script>
<script>
window.addEventListener("load", () => {
swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css');
});
</script>
if (Pageview.IsVisualEditorMode)
{
<div class="alert alert-info" role="alert">
<span>@Translate("Product slider: Edit this column to configure")</span>
</div>
}
if (sourceType != "related-products")
{
<div class="w-100 h-100">
<div id="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></div>
<div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div>
</div>
}
else if (product?.RelatedGroups != null)
{
@* Create multiple slider containers, if type is Product relation *@
<div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem">
<div id="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></div>
@foreach (var group in product.RelatedGroups)
{
<div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div>
}
</div>
}
@* Initialize *@
if (sourceType != "related-products")
{
<script type="module">
if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) {
document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size");
}
swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () {
setTimeout(function() {
const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant());
const productSliderContainer = document.querySelector(".swift_product_slider_container");
if (productSliderContainer && productSliderContainer.innerHTML !== "") {
productSliderContainer.classList.remove("d-none");
}
else if (!isVisualEditor) {
productSliderContainer.closest("[class*=column]").classList.add("d-none");
}
}, 150);
});
</script>
}
else if (product?.RelatedGroups != null)
{
@* Create multiple sliders, if type is Product relation *@
foreach (var group in product.RelatedGroups)
{
IList<string> fromProductIds = new List<string> { };
foreach (var relatedProduct in group.Products)
{
if (!string.IsNullOrEmpty(relatedProduct.VariantId))
{
fromProductIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}");
}
else
{
fromProductIds.Add($"{relatedProduct.ProductId}");
}
}
<script type="module">
document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size");
document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)";
document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name";
document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id");
swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID"));
</script>
}
}
}