K2 T:Nine Twister Ladies Road Bike cc

10101
7.075,00 kr. OutOfStock

New, compact double gearing makes this advanced road bike lighter and easier to shift for 2008!

Ikke på lager
Varen er ikke på lager i nogen butikker

Levering

Levering inden 7 hverdage

Garanti

3 års garanti

  • Lighter, more compliant ride thanks to a butted frame with Reflex Road tubing
  • T:Nine design gives all women riders a customized fit and look
  • Slim, carbon seatstays and T:Nine tuned fork smooth out the road ahead
  • K2 Bike Fit System stem supplies personalized bar height without the extra weight
  • Shimano Tiagra/SRAM 18-speed drivetrain with FSA Gossamer compact cranks offer plenty of quick, easy and efficient gearing options for the climbs
  • S.T.I. shifters with reach adjust and T:Nine tuned handlebar improves riding confidence
  • Selle San Marco Women’s Ischia saddle with T:Nine tuned seatpost adds personalized comfort
  • Tektro dual-pivot brakes provide quick and easy stops
  • Crank Brothers Smarty clipless pedals deliver more power in every rotation
  • Lightweight, A-Class wheelset with color-matched, Vittoria Rubino tires for a high level of control, response and lateral rigidity

Be comfortable with our equipments

Specifications

Mærke navn K2 bikes
Bremsetype Linear-pull
Bremser Shimano Ultegra
Farve
Forgaffel Synapse SAVE PLUS BallisTec Carbon
Stel Synapse BallisTec Carbon
Gear 21
Gearmodel Shimano Ultegra DI2
Geartype External Derailleur
Køn Women
Materialeforbrug Aluminum Carbon
Dæk Schwalbe Spicer (700x25c) m
Hjul RS 2.0
Hjulstørrelse 700c
Error executing template "/Designs/Swift/Paragraph/Swift_ProductDetailsMediaTable.cshtml"
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
   at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_57336dd21a174ed1875669c8bbb69017.<>c__DisplayClass0_0.<ExecuteAsync>b__0(AssetCategoryViewModel x)
   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.ToArray()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.GetEnumerator()+MoveNext()
   at System.Linq.Enumerable.UnionIterator`1.MoveNext()
   at CompiledRazorTemplates.Dynamic.RazorEngine_57336dd21a174ed1875669c8bbb69017.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 68
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\TemplateRenderingService.cs:line 21
   at Dynamicweb.Rendering.Template.RenderRazorTemplate() in E:\A10\_w\2\s\src\Core\Dynamicweb.Core\Rendering\Template.cs:line 805

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> @using Dynamicweb.Ecommerce.ProductCatalog @using System.Text.RegularExpressions; @using System.IO @functions { public ProductViewModel product { get; set; } = new ProductViewModel(); public string[] supportedImageFormats { get; set; } public string[] supportedVideoFormats { get; set; } public string[] supportedDocumentFormats { get; set; } public string[] allSupportedFormats { get; set; } public class RatioSettings { public string Ratio { get; set; } public string CssClass { get; set; } public string CssVariable { get; set; } public string Fill { get; set; } } public RatioSettings GetRatioSettings() { var ratioSettings = new RatioSettings(); string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); ratio = ratio != "0" ? ratio : ""; string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; ratioSettings.Ratio = ratio; ratioSettings.CssClass = cssClass; ratioSettings.CssVariable = cssVariable; ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; return ratioSettings; } public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) { string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; string type = GetVideoType(asset.Value); bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); var videoParams = new Dictionary<string, object>(); videoParams.Add("AssetName", asset.Name); videoParams.Add("AssetVideoType", type); videoParams.Add("AssetDisplayName", asset.DisplayName); videoParams.Add("OpenVideoInModal", openInModal); videoParams.Add("VideoAutoPlay", autoPlay); videoParams.Add("Size", size); videoParams.Add("Id", Model.ID); return videoParams; } public string GetVideoType(string assetValue) { string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; type = string.IsNullOrEmpty(type) ? "selfhosted" : type; return type; } public string GetYoutubeScreenDump(string assetValue) { var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/)([\w-]+)"); Match match = regex.Match(assetValue); string videoId = match.Success ? match.Groups[1].Value : string.Empty; string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/mqdefault.jpg"; return youtubeThumbnail; } } @{ @* Get the product data *@ 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]; } } } @if (product is object) { @* Supported formats *@ supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", ".pptx", ".igs", ".ipt", ".sat", ".stp", ".dwg", ".dxf", ".dwf" }; allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); @* Collect the assets *@ var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; assetsList = assetsList.Union(assetsImages); assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); int totalAssets = 0; if (showOnlyPrimaryImage == false) { foreach (MediaViewModel asset in assetsList) { var assetValue = asset.Value; foreach (string format in allSupportedFormats) { if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { totalAssets++; } } } } if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null)) { assetsList = new List<MediaViewModel>(){ product.DefaultImage }; totalAssets = 1; } int videoNumber = 0; @* Layout settings *@ string spacing = Model.Item.GetRawValueString("Spacing", "p-0"); spacing = spacing == "none" ? "p-0" : spacing; spacing = spacing == "small" ? "p-3" : spacing; spacing = spacing == "large" ? "p-5" : spacing; string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; bool hideThumbnails = Model.Item.GetBoolean("HideThumbnails"); string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; int modalVideoNumber = 0; @* Get assets from selected categories or get all assets *@ if (totalAssets != 0 && assetsList.Any()) { <div class="@spacing@(theme) item_@Model.Item.SystemName.ToLower()"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) { string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); <h3 class="@titleFontSize mb-3"> @Model.Item.GetString("Title") </h3> } <div class="table-responsive"> <table class="table table-hover align-middle mb-0" style="table-layout: fixed;"> <thead> <tr> @if (!hideThumbnails) { <th style="width:60px">&nbsp;</th> } <th>@Translate("Name")</th> <th class="text-end d-none d-lg-table-cell">@Translate("Download")</th> <th class="text-end" style="width:100px">@Translate("File type")</th> </tr> </thead> <tbody class="border-top-0"> @foreach (MediaViewModel asset in assetsList) { var assetValue = asset.Value; string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Value.Substring(asset.Value.LastIndexOf('/') + 1); bool isVideo = false; foreach (string format in supportedVideoFormats) { //Videos if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { isVideo = true; } } if (!isVideo) { if (assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) { string filePath = Dynamicweb.Context.Current.Server.MapPath(assetValue); long fileSize = 0; if (File.Exists(filePath)) { fileSize = new System.IO.FileInfo(filePath) != null ? new System.IO.FileInfo(filePath).Length / 1024 : 0; foreach (string format in allSupportedFormats) { if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { <tr> @if (!hideThumbnails) { //From @RenderAsset string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; <td class="@(imageTheme) px-0"> @foreach (string imageFormat in supportedImageFormats) { //Images if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; imagePath = !imageLinkPath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? asset.Value : imagePath; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle itemprop="image"> </div> </a> } } @foreach (string videoFormat in supportedVideoFormats) { //Videos if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); string type = GetVideoType(asset.Value); string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value) : string.Empty; videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-2 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> @if (type != "selfhosted") { <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> } else { string videoType = Path.GetExtension(asset.Value).ToLower(); <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> </video> } </div> </div> } } @foreach (string documentFormat in supportedDocumentFormats) { //Documents if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName"> @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle /> </div> } else { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> </div> } </a> } } </td> } <td> <a href="@assetValue" class="text-decoration-none text-break" download="@assetName" title="@assetName"> @assetName </a> </td> <td class="text-end d-none d-lg-table-cell"> <a href="@assetValue" class="text-decoration-none" download="@assetName" title="@assetName"> @fileSize KB <div class="icon-2" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> </a> </td> <td class="text-end">@format</td> </tr> } } } } else { <tr> @if (!hideThumbnails) { //From @RenderAsset string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; <td class="@(imageTheme) px-0"> @foreach (string format in supportedImageFormats) { //Images if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; imagePath = !imageLinkPath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? asset.Value : imagePath; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle itemprop="image"> </div> </a> } } @foreach (string format in supportedVideoFormats) { //Videos if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string type = GetVideoType(asset.Value); string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value) : string.Empty; videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-2 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> @if (type != "selfhosted") { <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> } else { string videoType = Path.GetExtension(asset.Value).ToLower(); <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> </video> } </div> </div> } } @foreach (string format in supportedDocumentFormats) { //Documents if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName"> @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle /> </div> } else { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> </div> } </a> } } </td> } <td> <a href="@assetValue" class="text-decoration-none text-break" download="@assetName" title="@assetName"> @assetName </a> </td> <td>&nbsp;</td> <td>&nbsp;</td> </tr> } } else { string videoType = asset.Value.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || asset.Value.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "Youtube" : ""; videoType = asset.Value.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "Vimeo" : videoType; <tr data-bs-toggle="modal" data-bs-target="#modal_@(Model.ID)_@videoNumber" style="cursor: pointer"> @if (!hideThumbnails) { //From @RenderAsset string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; <td class="@(imageTheme) px-0"> @foreach (string format in supportedImageFormats) { //Images if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; imagePath = !imageLinkPath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? asset.Value : imagePath; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle itemprop="image"> </div> </a> } } @foreach (string format in supportedVideoFormats) { //Videos if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string type = GetVideoType(asset.Value); string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value) : string.Empty; videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-2 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> @if (type != "selfhosted") { <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> } else { string fileExtension = Path.GetExtension(asset.Value).ToLower(); <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> <source src="@(videoScreendumpPath)#t=0.001" type="video/@fileExtension.Replace(".", "")"> </video> } </div> </div> } } @foreach (string documentFormat in supportedDocumentFormats) { //Documents if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = imagePath; imagePath = $"/Admin/Public/GetImage.ashx?image={imagePath}&width=60&format=webp"; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(); <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@productName"> @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <img loading="lazy" src="@imagePath" class="mw-100 mh-100" alt="@productName" @assetTitle /> </div> } else { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> </div> } </a> } } </td> } <td> @assetName </td> <td class="d-none d-lg-table-cell">&nbsp;</td> <td align="right">@videoType</td> </tr> videoNumber++; } } </tbody> </table> </div> @foreach (MediaViewModel asset in assetsList) { var assetName = asset.Value.ToLower(); foreach (string videoFormat in supportedVideoFormats) { //Videos if (assetName.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { <div class="modal fade js-video-modal" id="modal_@(Model.ID)_@modalVideoNumber" tabindex="-1" aria-labelledby="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered modal-xl"> <div class="modal-content"> <div class="modal-header visually-hidden"> <h5 class="modal-title" id="productDetailsTableModalTitle_@(Model.ID)_@modalVideoNumber">@product.Title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body p-2 p-lg-3 h-100"> @{ var videoParams = GetVideoParams(asset, "modal"); @RenderPartial("Components/VideoPlayer.cshtml", new Dynamicweb.Frontend.FileViewModel { Path = asset.Value }, videoParams) } </div> </div> </div> </div> modalVideoNumber++; } } } </div> } else if (Pageview.IsVisualEditorMode) { <div class="h-100 @theme"> <div class="alert alert-dark m-0"> @Translate("No assets are available") </div> </div> } }

Be updated on the newest events

Trending

Be updated on the newest events

By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Statistics and Marketing