France Valleys fonde investerer i tyske skove med støtte fra Dalgas
France Valley, en af Europas førende forvaltere af skovaktiver (anerkendt af IPE Real Assets), udvider sin internationale tilstedeværelse gennem betydelige investeringer i tyske skovarealer. Fondene har erhvervet næsten 1.000 hektar i Brandenburg, hvilket markerer virksomhedens hidtil største skovinvestering uden for Frankrig.
De tre nyerhvervede skove skal forvaltes i samarbejde med den specialiserede skovvirksomhed Dalgas, som indtræder som driftsansvarlig. Partnerskabet har til formål at styrke skovenes økologiske kvalitet og langsigtede robusthed gennem bæredygtige driftsmetoder. Initiativet skal forbedre biodiversiteten, udvikle skovstrukturen og bidrage til produktionen af bæredygtige, træbaserede byggematerialer – en central del af Europas strategi for CO₂-reduktion.
”Vores økonomiske model bygger på den naturlige værdistigning i skovaktiver, drevet af biologisk tilvækst og løbende forbedringer af træets kvalitet. De eksisterende arters egenskaber – og de økosystemer, de indgår i – er styrende for vores forvaltning og indgreb i skoven,” siger Thomas de Cointet, Chief Investment Officer i Europa hos France Valley.
Opkøbet udvider porteføljen i France Valleys europæiske skovfond Foncière Europe, som nu omfatter mere end 16.000 hektar fordelt på 12 europæiske lande. Fondens ambition er at tilbyde investorer en balanceret portefølje på tværs af lande med forskellige markedsprofiler, hvilket optimerer afkast og reducerer risiko.
France Valleys skovinvesteringer er langsigtede med fokus på at opbygge fremtidssikre og klimastærke produktionsskove. Alle ejendomme er PEFC-certificerede, og France Valley følger en udvidet bæredygtighedspolitik, der går ud over standardkravene for at sikre bedre beskyttelse af biodiversitet og naturlige ressourcer.
Dalgas, der skal stå for driften, har gennem mange år været aktiv på det tyske træ- og skovsmarked – fra handel med juletræer til tømmerhandel, råtræsmåling og senest skovforvaltning i Brandenburg, hvor virksomheden allerede forvalter 3.500 hektar. Dalgas har drevet skovforvaltning i Danmark i mere end 150 år og har i dag tyske kontorer i Eberswalde og Trittau. Ud over Danmark og Tyskland forvalter Dalgas også skove i Estland, Letland og Litauen – samlet 190.000 hektar.
”Denne type internationale samarbejde er en del af vores DNA, hvor vi skaber værdi for skovejere på tværs af landegrænser. Vi ønsker at støtte skovejere i at nå deres mål og fremme bæredygtig skovdrift, så vi kan levere klimavenlige råmaterialer med respekt for natur og biodiversitet. Vi ser frem til at arbejde sammen med France Valley om deres strategi for langsigtet, bæredygtig skovforvaltning i Tyskland og om at understøtte deres kommende investeringer,” siger Martin Bösselmann, direktør i Dalgas’ Forest & Trading-division.
Ansvarsfraskrivelse: Historiske afkast er ikke garanti for fremtidige resultater og kan variere over tid.
Skovinvesteringer indebærer risici, herunder:
- Risiko for tab af kapital: Investoren kan miste hele eller dele af den investerede kapital.
- Likviditetsrisiko: Enheder kan ikke frit sælges, og fondens likviditet er begrænset.
- Risici relateret til skovaktiver: Eksponering mod biologiske risici, klimahændelser og usikkerhed på træmarkedet.
- Operationelle og regulatoriske risici: Forbundet med skovdrift, lokale regler og driftsmæssige forhold.
- Binding af investeringen: Obligatorisk bindingsperiode for at opnå eventuelle skattemæssige fordele. Skatteregler kan ændre sig over tid.
- Bæredygtighedsrisici: Miljømæssige, sociale eller ledelsesmæssige forhold kan påvirke investeringens værdi negativt.
En fuldstændig beskrivelse af risiciene findes i dokumentet med central investorinformation (KID) og i markedsføringsmaterialet.
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/Dalgas_Featured_Lists.cshtml" System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Dalgas.Custom.Services.ContentRelationService.GetRelatedPagesByUrlAndParameters(String url, List`1 parameters, Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 81 at Dalgas.Custom.Services.ContentRelationService.GetNewsByCurrentPage(Int32 pageSize, Boolean onlyFromCurrentArea, List`1 parameters) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 785 at CompiledRazorTemplates.Dynamic.RazorEngine_6a7c2055180b4fc08a98751ee17ecbb9.Execute() in D:\solutions\dalgas-production\Files\Templates\Designs\Swift\Grid\Page\RowTemplates\Dalgas_Featured_Lists.cshtml:line 252 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.GridRowViewModel> 2 @using System 3 @using System.Collections.Generic 4 @using System.Linq 5 @using System.Text.RegularExpressions 6 @using Dalgas.Custom.Constants 7 @using Dalgas.Custom.Models.Content 8 @using Dalgas.Custom.Services 9 @using Dalgas.Custom.ViewModels.UI 10 @using Dynamicweb.Content 11 @using Dynamicweb.Core.Encoders 12 @using Dynamicweb.Frontend 13 @using Dynamicweb.Ecommerce.ProductCatalog 14 @using Page = Dynamicweb.Content.Page 15 @using System 16 @using System.Collections.Generic 17 @using System.Linq 18 @using Dalgas.Custom.ViewModels.UI 19 @using Dynamicweb.Content 20 @using Dynamicweb.Ecommerce.ProductCatalog 21 @using Dynamicweb.Frontend 22 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 23 24 @*TODO: Move these functions onto the model *@ 25 26 @functions 27 { 28 29 public string GetSectionClassList(GridRowViewModel model, string overwriteTheme = "") 30 { 31 var returnValues = new List<string> 32 { 33 $"item_{model.Item.SystemName.ToLower()}" 34 }; 35 36 if (Services.Grids.GetGridRowById(model.Id).Sort == 1) 37 { 38 returnValues.Add("dalgas-section-first-on-page"); 39 } 40 41 var sectionBackgroundTheme = model.Item.GetItem("ColorScheme")?.GetString("ColorScheme") ?? string.Empty; 42 43 if (!string.IsNullOrEmpty(overwriteTheme)) 44 { 45 sectionBackgroundTheme = overwriteTheme; 46 } 47 48 // Add theme class if it exists 49 if (!string.IsNullOrWhiteSpace(sectionBackgroundTheme)) 50 { 51 if (sectionBackgroundTheme.Contains("default")) 52 { 53 returnValues.Add("theme theme-light"); 54 } 55 else 56 { 57 returnValues.Add($"theme {sectionBackgroundTheme.Replace(" ", "").Trim().ToLower()}"); 58 } 59 } 60 61 // Determine if top padding should be removed 62 63 string removeTopPadding = model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 64 65 returnValues.Add("pb-6"); 66 if (removeTopPadding != "enable") 67 { 68 returnValues.Add("pt-6"); 69 } 70 71 return string.Join(" ", returnValues); 72 } 73 74 } 75 76 77 @{ 78 IEnumerable<HeadingViewModel> headings = ParagraphService.Instance.GetHeadingsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Headings")); 79 string text = Model.Item.GetItem("Paragraph_Text")?.GetString("Text"); 80 string lead = Model.Item.GetItem("Paragraph_Text")?.GetString("Lead"); 81 IEnumerable<ButtonViewModel> buttons = ParagraphService.Instance.GetButtonsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Buttons")); 82 83 bool hasImage = Model.Item.GetItem("Paragraph_Image")?.GetFile("Image") != null; 84 bool hasText = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Text")); 85 bool hasLead = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Lead")); 86 bool hasHeading = headings.Any(); 87 bool hasButton = buttons.Any(); 88 89 var theme = Model.Item.GetItem("ColorScheme")?.GetString("ColorScheme"); 90 var fifthElementTheme = "fifth-element-color-" + Model.Item?.GetItem("ColorScheme")?.GetString("FifthElementColor"); 91 92 var sectionClassList = GetSectionClassList(Model); 93 94 var image = string.Empty; 95 var imageParameters = new Dictionary<string, object>(); 96 97 string layout = string.Empty; 98 Boolean enableFifthElement = false; 99 if (Model?.Item != null) 100 { 101 var paragraphLayout = Model.Item.GetItem("Paragraph_Layout"); 102 103 if (paragraphLayout != null) 104 { 105 layout = paragraphLayout.GetString("Layout"); 106 107 enableFifthElement = !string.IsNullOrEmpty(paragraphLayout.GetString("Layout_FifthElement")); 108 } 109 } 110 111 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Image")?.GetFile("Image")?.Path)) 112 { 113 image = Model.Item.GetItem("Paragraph_Image").GetFile("Image").Path; 114 imageParameters.Add("alt", Model.Item.GetItem("Paragraph_Image")?.GetString("ImageAltText")); 115 int xPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromLeft ?? 50; 116 int yPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromTop ?? 50; 117 string cssPosition = $"{xPos}% {yPos}%"; 118 imageParameters.Add("style", "object-position:" + cssPosition); 119 } 120 121 LinkViewModel imageLink = new LinkViewModel(); 122 if (Model.Item?.GetItem("Paragraph_Image")?.GetItem("Link") != null && !string.IsNullOrEmpty(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link").GetString("ButtonLink"))) 123 { 124 imageLink = ParagraphService.Instance.GetLinkByItem(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link")); 125 } 126 127 string fifthElementIconPath = "/Files/Templates/Designs/Swift/Assets/Images/DalgasFifthElements/"; 128 } 129 130 131 @{ 132 ClassList rowWidthClasslist = new ClassList("col-12"); 133 ClassList colClasslist = new ClassList("js-content-container content-container col-12 mb-4 dalgas-list-card"); 134 ClassList cardClasslist = new ClassList("pt-3"); 135 string imageAspectRatio = string.Empty; 136 string newsModolusClasslist = string.Empty; 137 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 138 139 FileViewModel featuredListImage = new FileViewModel(); 140 List<FileViewModel> imageList = new List<FileViewModel>(); // List to hold images for the modal 141 IList<ItemViewModel> featureListItems = Model.Item?.GetItem("Content")?.GetItems("PageSelector") ?? Enumerable.Empty<ItemViewModel>().ToList(); 142 bool hasFeatureListItems = featureListItems.Any(); 143 144 int.TryParse(Dynamicweb.Context.Current.Request["PageSize"], out int pageSize); 145 bool isProductPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"]); 146 string separator = Pageview.SearchFriendlyUrl.Contains("?") ? "&" : "?"; 147 string showAllUrl = $"{Pageview.SearchFriendlyUrl}{separator}PageSize=999"; 148 149 bool showAll = Model.Item.GetItem("Content").GetBoolean("ShowAll"); 150 bool showFacets = Model.Item.GetItem("Content").GetBoolean("ShowFacets"); 151 bool showSearch = Model.Item.GetItem("Content").GetBoolean("ShowSearch"); 152 bool allowAllQueryItems = showFacets || showSearch; 153 showAll = allowAllQueryItems || showAll; 154 int numberOfItemsToShow = 999; 155 int rowsPerPage = 3; 156 157 158 List<FacetOption> selectedFacetOptions = new List<FacetOption>(); 159 if (hasFeatureListItems) 160 { 161 allowAllQueryItems = false; 162 } 163 164 QueryResult queryResult = new QueryResult(); 165 string contentType = Model.Item.GetItem("Content").GetString("FeatureOptions"); 166 int totaleCount = 0; 167 168 switch (contentType) 169 { 170 case "articles": 171 numberOfItemsToShow = 4; 172 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 173 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 174 175 if (!hasFeatureListItems) 176 { 177 queryResult = showAll ? ContentRelationService.Instance.GetAllKnowledge(numberOfItemsToShow) : ContentRelationService.Instance.GetKnowledgeByCurrentPage(numberOfItemsToShow); 178 } 179 180 imageAspectRatio = "ratio-4x3"; 181 colClasslist.Add("col-md-3"); 182 break; 183 case "events": 184 numberOfItemsToShow = 3; 185 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 186 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 187 if (!hasFeatureListItems) 188 { 189 queryResult = showAll ? ContentRelationService.Instance.GetAllEvents(numberOfItemsToShow) : ContentRelationService.Instance.GetEventsByCurrentPage(numberOfItemsToShow); 190 } 191 192 imageAspectRatio = "ratio-16x9"; 193 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 194 colClasslist.Add("col-md-4 d-flex flex-column"); 195 break; 196 case "cases": 197 numberOfItemsToShow = 3; 198 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 199 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 200 if (!hasFeatureListItems) 201 { 202 if (PageView.Current().Page.Item.SystemName.Contains("Funding")) 203 { 204 queryResult = ContentRelationService.Instance.GetCaseCustomerStoriesByCurrentFunding(numberOfItemsToShow); 205 } 206 else 207 { 208 queryResult = showAll ? ContentRelationService.Instance.GetAllCaseCustomerStoriesByCurrentPage(numberOfItemsToShow) : ContentRelationService.Instance.GetCaseCustomerStoriesByCurrentPage(numberOfItemsToShow); 209 } 210 } 211 212 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 213 imageAspectRatio = "ratio-16x9"; 214 colClasslist.Add("col-md-4 d-flex flex-column"); 215 break; 216 case "news": 217 numberOfItemsToShow = 3; 218 numberOfItemsToShow = showAll ? numberOfItemsToShow * (rowsPerPage * 2) : numberOfItemsToShow; 219 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 220 if (!hasFeatureListItems) 221 { 222 if (Pageview.Area.Item["Custom_Website_Styling"].ToString().Contains("shop") && string.IsNullOrEmpty(Pageview.Area.Item["NewsFromOtherSites"].ToString()) == false) 223 { 224 // Initialize the list of parameters for the content query 225 var parameters = new List<KeyValuePair<string, string>>(); 226 227 // Get the "NewsFromOtherSites" field value from the current area 228 var newsFromOtherSites = Pageview.Area.Item["NewsFromOtherSites"]?.ToString(); 229 230 // Start building the list of area IDs, including the current page's area ID 231 var areaIds = new List<string> 232 { 233 PageView.Current()?.Area?.ID.ToString() 234 }; 235 236 // If "NewsFromOtherSites" has any values, split by comma and add them to the areaIds list 237 if (!string.IsNullOrEmpty(newsFromOtherSites)) 238 { 239 areaIds.AddRange(newsFromOtherSites.Split(',').Select(x => x.Trim())); 240 } 241 242 // Create a key-value pair for the content query, joining all area IDs with a comma 243 var keyValue = new KeyValuePair<string, string>( 244 ContentKeys.DW_INDEXING_CONTENT_FIELD_AREA_IDS, 245 string.Join(", ", areaIds.Where(id => !string.IsNullOrEmpty(id))) 246 ); 247 248 // Add the key-value pair to the parameters list 249 parameters.Add(keyValue); 250 251 // Execute the query to get news items 252 queryResult = showAll ? ContentRelationService.Instance.GetAllNews(numberOfItemsToShow, parameters) : ContentRelationService.Instance.GetNewsByCurrentPage(numberOfItemsToShow, false, parameters); 253 } 254 else 255 { 256 queryResult = showAll ? ContentRelationService.Instance.GetAllNews(numberOfItemsToShow) : ContentRelationService.Instance.GetNewsByCurrentPage(numberOfItemsToShow); 257 } 258 } 259 260 rowWidthClasslist.Add("col-lg-11 ms-auto"); 261 colClasslist.Add("mb-5"); 262 break; 263 case "projects": 264 numberOfItemsToShow = 3; 265 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 266 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 267 if (!hasFeatureListItems) 268 { 269 if (PageView.Current().Page.Item.SystemName.Contains("Funding")) 270 { 271 queryResult = ContentRelationService.Instance.GetCaseProjectsByCurrentFunding(numberOfItemsToShow); 272 } 273 else 274 { 275 queryResult = showAll ? ContentRelationService.Instance.GetAllCaseProjectsByCurrentPage(numberOfItemsToShow) : ContentRelationService.Instance.GetCaseProjectsByCurrentPage(numberOfItemsToShow); 276 } 277 } 278 279 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 280 imageAspectRatio = "ratio-16x9"; 281 colClasslist.Add("col-md-4 d-flex flex-column"); 282 break; 283 case "related-services": 284 numberOfItemsToShow = 6; 285 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 286 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 287 if (!hasFeatureListItems) 288 { 289 queryResult = ContentRelationService.Instance.GetRelatedServicesByCurrentPage(numberOfItemsToShow); 290 } 291 292 cardClasslist.Add("theme theme-mud p-4 pt-5 h-100"); 293 imageAspectRatio = "ratio-16x9"; 294 colClasslist.Add("col-md-4 d-flex flex-column"); 295 break; 296 } 297 298 int pageNum = int.TryParse(Dynamicweb.Context.Current.Request["PageNum"], out int result) ? result : 1; 299 string searchTerm = Dynamicweb.Context.Current.Request["q"]; 300 301 List<string> pageIds = new List<string>(); 302 if (hasFeatureListItems) 303 { 304 pageIds.AddRange(featureListItems.Select(fli => fli.Fields.FirstOrDefault(f => f.Name == "Page")?.GetLink().PageId.ToString())); 305 } 306 else if (queryResult.Results.Any()) 307 { 308 pageIds.AddRange(queryResult.Results.Select(qrr => qrr["PageId"].ToString())); 309 } 310 311 string strTitle = string.Empty; 312 string strLink = string.Empty; 313 string strSummary = string.Empty; 314 string strImage = string.Empty; 315 string strType = string.Empty; 316 string badgeTheme = string.Empty; 317 DateTime strDate = new DateTime(); 318 } 319 320 @if ((queryResult.FacetGroups.Any() && allowAllQueryItems) || (queryResult.Results.Any() && !allowAllQueryItems) || featureListItems.Any()) 321 { 322 int loopCounter = 1; // Initialize loop counter for each group 323 324 <section id="section-@Model.Id" class="@sectionClassList" data-swift-gridrow> 325 <div class="container-xl"> 326 <div class="row justify-content-center"> 327 <div class="@rowWidthClasslist"> 328 <div class="js-dalgas-queryresult-container dalgas-queryresult-container" 329 id="@($"query-result-{Model.Id}")"> 330 331 @if (hasLead || hasText || hasHeading) 332 { 333 <div class="js-content-container content-container col-12 mb-3"> 334 335 <div class="col-lg-6"> 336 <span> 337 @string.Join("", headings.Select(h => h.ToString())) 338 </span> 339 340 @if (!string.IsNullOrEmpty(lead)) 341 { 342 <p class="lead">@lead</p> 343 } 344 345 @text 346 347 </div> 348 </div> 349 } 350 351 @{ 352 ButtonViewModel btnViewResult = new ButtonViewModel 353 { 354 Text = Translate("View more"), 355 Type = ButtonType.Link, 356 DisplayType = ButtonDisplayType.Link 357 }; 358 359 if (showAll) 360 { 361 totaleCount = queryResult.TotalCount; 362 } 363 364 365 <form method="post" action="@Pageview.SearchFriendlyUrl" 366 data-response-target-element="content" tabindex="-1" aria-hidden="false" 367 class="d-flex js-dalgas-facets-form dalgas-facets-form" 368 data-total-count="@totaleCount" data-page-size="@numberOfItemsToShow"> 369 <input type="hidden" name="LayoutTemplate" 370 value="Designs/Swift/Swift_PageClean.cshtml"/> 371 <input type="hidden" name="PageNum" value="@pageNum"/> 372 <input type="hidden" name="PageSize" value="@numberOfItemsToShow"/> 373 @if (allowAllQueryItems) 374 { 375 if (showFacets) 376 { 377 foreach (FacetGroup facetGroup in queryResult.FacetGroups) 378 { 379 foreach (Facet facet in facetGroup.Facets) 380 { 381 string showClass = " show"; 382 string ariaExpanded = "true"; 383 string facetGroupId = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(5000)); 384 385 386 if (facet.Options.Any()) 387 { 388 int selectedFacetsInGroup = 0; 389 390 foreach (FacetOption option in facet.Options) 391 { 392 if (option.Selected) 393 { 394 selectedFacetsInGroup++; 395 } 396 } 397 398 string label = selectedFacetsInGroup > 0 ? Translate(facet.Name) + "<span style=\"padding: 0.3em 0.6em\" class=\"badge badge ms-2\">" + selectedFacetsInGroup + "</span>" : Translate(facet.Name); 399 400 <div class="dropdown js-facets-selector"> 401 <button class="btn dropdown-toggle" type="button" 402 id="FacetGroup_@facetGroupId" data-bs-toggle="dropdown" 403 aria-expanded="false"> 404 @label 405 </button> 406 <div data-lenis-prevent class="dropdown-menu p-3" 407 aria-labelledby="FacetGroup_@facetGroupId" 408 style="min-width: 280px"> 409 @foreach (FacetOption facetOption in facet.Options.OrderBy(fo => fo.Label)) 410 { 411 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 412 string disabled = facetOption.Count <= 0 ? "disabled" : string.Empty; 413 string selected = facetOption.Selected ? "checked" : string.Empty; 414 string facetValue = Uri.UnescapeDataString(facetOption.Value); 415 string optionValue = $"[{facetValue}]"; 416 417 facetLabel = facetLabel.ToLower() == "true" ? facetLabel = Translate("Yes") : facetLabel; 418 facetLabel = facetLabel.ToLower() == "false" ? facetLabel = Translate("No") : facetLabel; 419 420 <label class="form-check mt-1" @disabled> 421 <input type="checkbox" 422 onclick="custom.QueryResult.update(event)" 423 class="form-check-input" 424 name="@facet.QueryParameter" 425 value="@optionValue" 426 data-filter-value="@facetLabel" @selected> 427 <span 428 class="form-check-label d-flex align-items-center"> 429 <span class="flex-fill">@facetLabel </span> 430 <small 431 class="opacity-85">@facetOption.Count</small> 432 </span> 433 </label> 434 435 if (facetOption.Selected) 436 { 437 FacetOption selectFacetOption = facetOption; 438 selectFacetOption.Name = facet.QueryParameter; 439 selectedFacetOptions.Add(selectFacetOption); 440 } 441 } 442 </div> 443 </div> 444 } 445 } 446 } 447 448 if (!string.IsNullOrEmpty(searchTerm)) 449 { 450 selectedFacetOptions.Add(new FacetOption() 451 { 452 Count = 1, 453 Label = searchTerm, 454 Name = "q", 455 Selected = true, 456 Value = searchTerm 457 }); 458 } 459 } 460 461 if (showSearch) 462 { 463 <div class="type-ahead-dropdown"> 464 <div class="position-relative suggest-form"> 465 <span 466 class="position-absolute top-0 end-0 icon-3 px-3 d-flex align-items-center h-100 search-icon"> 467 @ReadFile(iconPath + "search.svg") 468 </span> 469 470 <input id="searchField_@Model.Id" 471 class="form-control custom-header-searchbar js-custom-facets-search-field pe-5 ps-3 js-" 472 type="search" 473 placeholder="@Translate("Search here")" 474 autocomplete="off" 475 maxlength="255" 476 name="q" 477 value="@searchTerm" 478 data-original="@searchTerm"> 479 480 <button type="button" 481 onclick="custom.QueryResult.clearSearchField(event)" 482 class="btn h-100 icon-2 reset-search" 483 aria-label="@Translate("Clear search")" 484 style="opacity: 0; position: absolute; top: 0; right: 0; visibility: hidden;"> 485 @ReadFile(iconPath + "x.svg") 486 </button> 487 </div> 488 </div> 489 <input type="submit" onclick="custom.QueryResult.update(event)" 490 class="btn btn-primary" value="@Translate("Search", "Search")"> 491 } 492 } 493 </form> 494 495 if (showFacets && selectedFacetOptions.Any()) 496 { 497 <div 498 class="js-dalgas-queryresult-selectedfacets-container dalgas-queryresult-selectedfacets-container mt-3"> 499 @foreach (FacetOption facetOption in selectedFacetOptions) 500 { 501 string facetValue = Uri.UnescapeDataString(facetOption.Value); 502 string optionValue = $"[{facetValue}]"; 503 <input class="visually-hidden" 504 id="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)" 505 name="@facetOption.Name" 506 onclick="custom.QueryResult.deselectFacetOption(event)" type="checkbox" 507 value="@optionValue" title="@facetOption.Label" checked> 508 <label class="badge theme border border-dark text-nowrap" 509 for="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)"> 510 <span class="text-nowrap">@(facetOption.Label)</span> 511 <span class="icon-2 ms-2"> 512 @ReadFile(iconPath + "x.svg") 513 </span> 514 </label> 515 } 516 517 @if (selectedFacetOptions.Count >= 3) 518 { 519 <input class="visually-hidden" id="ClearAll" name="ClearAll" 520 onclick="custom.QueryResult.clearAll(event)" type="checkbox" value="" 521 title="" checked> 522 <label class="badge theme border border-dark dalgas-btn-clear-all" 523 for="ClearAll"> 524 <span class="text-nowrap">@Translate("Clear all")</span> 525 <span class="icon-2 ms-2"> 526 @ReadFile(iconPath + "x.svg") 527 </span> 528 </label> 529 } 530 </div> 531 }} 532 533 @if (pageIds.Any() == false) 534 { 535 <div class="mt-4">@Translate("Your search returned no results...")</div> 536 } 537 538 <div 539 class="row @(!showAll ? "dalgas-featured-list-mobile-horizontal-scroll" : "mt-5") js-dalgas-queryresult-itemlist dalgas-queryresult-itemlist mt-2"> 540 @foreach (string pageId in pageIds) 541 { 542 if (!int.TryParse(pageId, out int intPageId)) 543 { 544 continue; 545 } 546 547 Page page = Services.Pages.GetPage(intPageId); 548 549 if (page == null) 550 { 551 continue; 552 } 553 554 @* Renders articles from another website language *@ 555 556 string resolvedPageId = pageId; 557 if (PageView.Current().Page.AreaId != page.AreaId) 558 { 559 resolvedPageId = GetPageIdByNavigationTag("ArticlePageFromOtherSite") + "&render-article-id=" + pageId; 560 } 561 562 string articleUrl = SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?ID=" + resolvedPageId); 563 564 strTitle = page.Item["Title"]?.ToString(); 565 strSummary = page.Item["Summary"]?.ToString(); 566 strImage = page.Item["CoverImage"] == null ? string.Empty : page.Item["CoverImage"]?.ToString(); 567 btnViewResult.Id = "pageId_" + page.ID; 568 btnViewResult.Url = !string.IsNullOrEmpty(articleUrl) ? articleUrl : "/Default.aspx?ID=" + resolvedPageId; 569 if (page.Item["Date"] != null) 570 { 571 strDate = (DateTime) page.Item["Date"]; 572 } 573 574 int jpgIndex = strImage.IndexOf(".jpg", StringComparison.OrdinalIgnoreCase); 575 if (jpgIndex != -1) 576 { 577 strImage = strImage.Substring(0, jpgIndex + 4); 578 } 579 580 featuredListImage = ViewModelFactory.CreateFieldFileValueView(strImage); 581 imageList.Add(featuredListImage); 582 583 if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "news") 584 { 585 badgeTheme = ""; 586 if (loopCounter % 6 == 2 || loopCounter % 6 == 4) 587 { 588 newsModolusClasslist = "col-lg-5"; 589 imageAspectRatio = "ratio-16x9"; 590 if (showAll) 591 { 592 imageAspectRatio = "ratio-3x4 ratio-custom-news"; 593 } 594 } 595 else 596 { 597 newsModolusClasslist = "col-lg-3"; 598 imageAspectRatio = "ratio-16x9 ratio-lg-3x4"; 599 if (showAll) 600 { 601 imageAspectRatio = "ratio-3x4"; 602 } 603 } 604 605 loopCounter++; 606 } 607 608 609 <div class="@colClasslist @newsModolusClasslist"> 610 611 @if (!string.IsNullOrEmpty(featuredListImage.Path)) 612 { 613 <a href="@btnViewResult.Url"> 614 <figure class="ratio @imageAspectRatio mb-0"> 615 @RenderPartial("Components/Image.cshtml", featuredListImage ?? new FileViewModel()) 616 </figure> 617 </a> 618 } 619 620 <div class="@cardClasslist"> 621 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "events") 622 { 623 badgeTheme = "mb-5"; 624 } 625 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "events" || Model.Item.GetItem("Content").GetString("FeatureOptions") == "news") 626 { 627 if (strDate != null) 628 { 629 var date = strDate; 630 var formattedDate = date.ToLongDateString(); 631 if (date.TimeOfDay.ToString() != "00:00:00") 632 { 633 formattedDate = formattedDate + " - " + date.ToShortTimeString(); 634 } 635 636 <div class="badge mb-3 @badgeTheme"> 637 @formattedDate 638 </div> 639 } 640 } 641 642 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "cases" || Model.Item.GetItem("Content").GetString("FeatureOptions") == "projects") 643 { 644 var selectedValues = page.Item["Type"].ToString(); 645 <div class="badge mb-5 mr-3 @badgeTheme"> 646 @ContentService.Instance.GetLabelForCaseType(selectedValues) 647 </div> 648 } 649 650 @{ 651 var badgeParms = new Dictionary<string, object>(); 652 badgeParms.Add("pageId", page.ID); 653 } 654 @RenderPartial("UserInterfaceModels/badge.cshtml", Model, badgeParms) 655 656 <h4> 657 <a href="@btnViewResult.Url" class="text-decoration-none"> 658 @strTitle 659 </a> 660 </h4> 661 @if (strSummary != null) 662 { 663 <span class="small">@strSummary</span> 664 } 665 666 <div class="mt-2"> 667 @RenderModel(btnViewResult) 668 </div> 669 </div> 670 </div> 671 } 672 </div> 673 674 @if (showAll && totaleCount > numberOfItemsToShow) 675 { 676 <div class="row"> 677 <div class="col-12 text-center"> 678 <button onclick="custom.QueryResult.getNextPage(event)" 679 class="btn btn-primary">@Translate("Vis flere")</button> 680 </div> 681 </div> 682 } 683 684 @if (hasButton) 685 { 686 <div class="js-content-container content-container col-12"> 687 688 <div class="d-flex flex-wrap gap-3"> 689 @foreach (ButtonViewModel button in buttons) 690 { 691 @button 692 } 693 </div> 694 695 </div> 696 } 697 698 </div> 699 </div> 700 </div> 701 </div> 702 @if (enableFifthElement) 703 { 704 <div class="fifth-element-section-container"> 705 <div class="fifth-element size-2 bottom-0 ob-50 right-0 @fifthElementTheme"> 706 @ReadFile(fifthElementIconPath + "sun.svg") 707 </div> 708 </div> 709 } 710 </section> 711 } 712 else 713 { 714 if (Pageview.IsVisualEditorMode) 715 { 716 <div class="container-xl alert alert-danger" role="alert"> 717 This <strong>@Model.Item.SystemName</strong> is empty 718 </div> 719 } 720 } 721
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/Dalgas_Featured_Lists.cshtml" System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Dalgas.Custom.Services.ContentRelationService.GetRelatedPagesByUrlAndParameters(String url, List`1 parameters, Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 81 at Dalgas.Custom.Services.ContentRelationService.GetKnowledgeByCurrentPage(Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 745 at CompiledRazorTemplates.Dynamic.RazorEngine_6a7c2055180b4fc08a98751ee17ecbb9.Execute() in D:\solutions\dalgas-production\Files\Templates\Designs\Swift\Grid\Page\RowTemplates\Dalgas_Featured_Lists.cshtml:line 177 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.GridRowViewModel> 2 @using System 3 @using System.Collections.Generic 4 @using System.Linq 5 @using System.Text.RegularExpressions 6 @using Dalgas.Custom.Constants 7 @using Dalgas.Custom.Models.Content 8 @using Dalgas.Custom.Services 9 @using Dalgas.Custom.ViewModels.UI 10 @using Dynamicweb.Content 11 @using Dynamicweb.Core.Encoders 12 @using Dynamicweb.Frontend 13 @using Dynamicweb.Ecommerce.ProductCatalog 14 @using Page = Dynamicweb.Content.Page 15 @using System 16 @using System.Collections.Generic 17 @using System.Linq 18 @using Dalgas.Custom.ViewModels.UI 19 @using Dynamicweb.Content 20 @using Dynamicweb.Ecommerce.ProductCatalog 21 @using Dynamicweb.Frontend 22 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 23 24 @*TODO: Move these functions onto the model *@ 25 26 @functions 27 { 28 29 public string GetSectionClassList(GridRowViewModel model, string overwriteTheme = "") 30 { 31 var returnValues = new List<string> 32 { 33 $"item_{model.Item.SystemName.ToLower()}" 34 }; 35 36 if (Services.Grids.GetGridRowById(model.Id).Sort == 1) 37 { 38 returnValues.Add("dalgas-section-first-on-page"); 39 } 40 41 var sectionBackgroundTheme = model.Item.GetItem("ColorScheme")?.GetString("ColorScheme") ?? string.Empty; 42 43 if (!string.IsNullOrEmpty(overwriteTheme)) 44 { 45 sectionBackgroundTheme = overwriteTheme; 46 } 47 48 // Add theme class if it exists 49 if (!string.IsNullOrWhiteSpace(sectionBackgroundTheme)) 50 { 51 if (sectionBackgroundTheme.Contains("default")) 52 { 53 returnValues.Add("theme theme-light"); 54 } 55 else 56 { 57 returnValues.Add($"theme {sectionBackgroundTheme.Replace(" ", "").Trim().ToLower()}"); 58 } 59 } 60 61 // Determine if top padding should be removed 62 63 string removeTopPadding = model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 64 65 returnValues.Add("pb-6"); 66 if (removeTopPadding != "enable") 67 { 68 returnValues.Add("pt-6"); 69 } 70 71 return string.Join(" ", returnValues); 72 } 73 74 } 75 76 77 @{ 78 IEnumerable<HeadingViewModel> headings = ParagraphService.Instance.GetHeadingsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Headings")); 79 string text = Model.Item.GetItem("Paragraph_Text")?.GetString("Text"); 80 string lead = Model.Item.GetItem("Paragraph_Text")?.GetString("Lead"); 81 IEnumerable<ButtonViewModel> buttons = ParagraphService.Instance.GetButtonsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Buttons")); 82 83 bool hasImage = Model.Item.GetItem("Paragraph_Image")?.GetFile("Image") != null; 84 bool hasText = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Text")); 85 bool hasLead = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Lead")); 86 bool hasHeading = headings.Any(); 87 bool hasButton = buttons.Any(); 88 89 var theme = Model.Item.GetItem("ColorScheme")?.GetString("ColorScheme"); 90 var fifthElementTheme = "fifth-element-color-" + Model.Item?.GetItem("ColorScheme")?.GetString("FifthElementColor"); 91 92 var sectionClassList = GetSectionClassList(Model); 93 94 var image = string.Empty; 95 var imageParameters = new Dictionary<string, object>(); 96 97 string layout = string.Empty; 98 Boolean enableFifthElement = false; 99 if (Model?.Item != null) 100 { 101 var paragraphLayout = Model.Item.GetItem("Paragraph_Layout"); 102 103 if (paragraphLayout != null) 104 { 105 layout = paragraphLayout.GetString("Layout"); 106 107 enableFifthElement = !string.IsNullOrEmpty(paragraphLayout.GetString("Layout_FifthElement")); 108 } 109 } 110 111 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Image")?.GetFile("Image")?.Path)) 112 { 113 image = Model.Item.GetItem("Paragraph_Image").GetFile("Image").Path; 114 imageParameters.Add("alt", Model.Item.GetItem("Paragraph_Image")?.GetString("ImageAltText")); 115 int xPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromLeft ?? 50; 116 int yPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromTop ?? 50; 117 string cssPosition = $"{xPos}% {yPos}%"; 118 imageParameters.Add("style", "object-position:" + cssPosition); 119 } 120 121 LinkViewModel imageLink = new LinkViewModel(); 122 if (Model.Item?.GetItem("Paragraph_Image")?.GetItem("Link") != null && !string.IsNullOrEmpty(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link").GetString("ButtonLink"))) 123 { 124 imageLink = ParagraphService.Instance.GetLinkByItem(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link")); 125 } 126 127 string fifthElementIconPath = "/Files/Templates/Designs/Swift/Assets/Images/DalgasFifthElements/"; 128 } 129 130 131 @{ 132 ClassList rowWidthClasslist = new ClassList("col-12"); 133 ClassList colClasslist = new ClassList("js-content-container content-container col-12 mb-4 dalgas-list-card"); 134 ClassList cardClasslist = new ClassList("pt-3"); 135 string imageAspectRatio = string.Empty; 136 string newsModolusClasslist = string.Empty; 137 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 138 139 FileViewModel featuredListImage = new FileViewModel(); 140 List<FileViewModel> imageList = new List<FileViewModel>(); // List to hold images for the modal 141 IList<ItemViewModel> featureListItems = Model.Item?.GetItem("Content")?.GetItems("PageSelector") ?? Enumerable.Empty<ItemViewModel>().ToList(); 142 bool hasFeatureListItems = featureListItems.Any(); 143 144 int.TryParse(Dynamicweb.Context.Current.Request["PageSize"], out int pageSize); 145 bool isProductPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"]); 146 string separator = Pageview.SearchFriendlyUrl.Contains("?") ? "&" : "?"; 147 string showAllUrl = $"{Pageview.SearchFriendlyUrl}{separator}PageSize=999"; 148 149 bool showAll = Model.Item.GetItem("Content").GetBoolean("ShowAll"); 150 bool showFacets = Model.Item.GetItem("Content").GetBoolean("ShowFacets"); 151 bool showSearch = Model.Item.GetItem("Content").GetBoolean("ShowSearch"); 152 bool allowAllQueryItems = showFacets || showSearch; 153 showAll = allowAllQueryItems || showAll; 154 int numberOfItemsToShow = 999; 155 int rowsPerPage = 3; 156 157 158 List<FacetOption> selectedFacetOptions = new List<FacetOption>(); 159 if (hasFeatureListItems) 160 { 161 allowAllQueryItems = false; 162 } 163 164 QueryResult queryResult = new QueryResult(); 165 string contentType = Model.Item.GetItem("Content").GetString("FeatureOptions"); 166 int totaleCount = 0; 167 168 switch (contentType) 169 { 170 case "articles": 171 numberOfItemsToShow = 4; 172 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 173 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 174 175 if (!hasFeatureListItems) 176 { 177 queryResult = showAll ? ContentRelationService.Instance.GetAllKnowledge(numberOfItemsToShow) : ContentRelationService.Instance.GetKnowledgeByCurrentPage(numberOfItemsToShow); 178 } 179 180 imageAspectRatio = "ratio-4x3"; 181 colClasslist.Add("col-md-3"); 182 break; 183 case "events": 184 numberOfItemsToShow = 3; 185 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 186 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 187 if (!hasFeatureListItems) 188 { 189 queryResult = showAll ? ContentRelationService.Instance.GetAllEvents(numberOfItemsToShow) : ContentRelationService.Instance.GetEventsByCurrentPage(numberOfItemsToShow); 190 } 191 192 imageAspectRatio = "ratio-16x9"; 193 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 194 colClasslist.Add("col-md-4 d-flex flex-column"); 195 break; 196 case "cases": 197 numberOfItemsToShow = 3; 198 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 199 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 200 if (!hasFeatureListItems) 201 { 202 if (PageView.Current().Page.Item.SystemName.Contains("Funding")) 203 { 204 queryResult = ContentRelationService.Instance.GetCaseCustomerStoriesByCurrentFunding(numberOfItemsToShow); 205 } 206 else 207 { 208 queryResult = showAll ? ContentRelationService.Instance.GetAllCaseCustomerStoriesByCurrentPage(numberOfItemsToShow) : ContentRelationService.Instance.GetCaseCustomerStoriesByCurrentPage(numberOfItemsToShow); 209 } 210 } 211 212 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 213 imageAspectRatio = "ratio-16x9"; 214 colClasslist.Add("col-md-4 d-flex flex-column"); 215 break; 216 case "news": 217 numberOfItemsToShow = 3; 218 numberOfItemsToShow = showAll ? numberOfItemsToShow * (rowsPerPage * 2) : numberOfItemsToShow; 219 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 220 if (!hasFeatureListItems) 221 { 222 if (Pageview.Area.Item["Custom_Website_Styling"].ToString().Contains("shop") && string.IsNullOrEmpty(Pageview.Area.Item["NewsFromOtherSites"].ToString()) == false) 223 { 224 // Initialize the list of parameters for the content query 225 var parameters = new List<KeyValuePair<string, string>>(); 226 227 // Get the "NewsFromOtherSites" field value from the current area 228 var newsFromOtherSites = Pageview.Area.Item["NewsFromOtherSites"]?.ToString(); 229 230 // Start building the list of area IDs, including the current page's area ID 231 var areaIds = new List<string> 232 { 233 PageView.Current()?.Area?.ID.ToString() 234 }; 235 236 // If "NewsFromOtherSites" has any values, split by comma and add them to the areaIds list 237 if (!string.IsNullOrEmpty(newsFromOtherSites)) 238 { 239 areaIds.AddRange(newsFromOtherSites.Split(',').Select(x => x.Trim())); 240 } 241 242 // Create a key-value pair for the content query, joining all area IDs with a comma 243 var keyValue = new KeyValuePair<string, string>( 244 ContentKeys.DW_INDEXING_CONTENT_FIELD_AREA_IDS, 245 string.Join(", ", areaIds.Where(id => !string.IsNullOrEmpty(id))) 246 ); 247 248 // Add the key-value pair to the parameters list 249 parameters.Add(keyValue); 250 251 // Execute the query to get news items 252 queryResult = showAll ? ContentRelationService.Instance.GetAllNews(numberOfItemsToShow, parameters) : ContentRelationService.Instance.GetNewsByCurrentPage(numberOfItemsToShow, false, parameters); 253 } 254 else 255 { 256 queryResult = showAll ? ContentRelationService.Instance.GetAllNews(numberOfItemsToShow) : ContentRelationService.Instance.GetNewsByCurrentPage(numberOfItemsToShow); 257 } 258 } 259 260 rowWidthClasslist.Add("col-lg-11 ms-auto"); 261 colClasslist.Add("mb-5"); 262 break; 263 case "projects": 264 numberOfItemsToShow = 3; 265 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 266 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 267 if (!hasFeatureListItems) 268 { 269 if (PageView.Current().Page.Item.SystemName.Contains("Funding")) 270 { 271 queryResult = ContentRelationService.Instance.GetCaseProjectsByCurrentFunding(numberOfItemsToShow); 272 } 273 else 274 { 275 queryResult = showAll ? ContentRelationService.Instance.GetAllCaseProjectsByCurrentPage(numberOfItemsToShow) : ContentRelationService.Instance.GetCaseProjectsByCurrentPage(numberOfItemsToShow); 276 } 277 } 278 279 cardClasslist.Add("theme theme-mud p-4 pt-4 h-100"); 280 imageAspectRatio = "ratio-16x9"; 281 colClasslist.Add("col-md-4 d-flex flex-column"); 282 break; 283 case "related-services": 284 numberOfItemsToShow = 6; 285 numberOfItemsToShow = showAll ? numberOfItemsToShow * rowsPerPage : numberOfItemsToShow; 286 numberOfItemsToShow = pageSize > 0 ? pageSize : numberOfItemsToShow; 287 if (!hasFeatureListItems) 288 { 289 queryResult = ContentRelationService.Instance.GetRelatedServicesByCurrentPage(numberOfItemsToShow); 290 } 291 292 cardClasslist.Add("theme theme-mud p-4 pt-5 h-100"); 293 imageAspectRatio = "ratio-16x9"; 294 colClasslist.Add("col-md-4 d-flex flex-column"); 295 break; 296 } 297 298 int pageNum = int.TryParse(Dynamicweb.Context.Current.Request["PageNum"], out int result) ? result : 1; 299 string searchTerm = Dynamicweb.Context.Current.Request["q"]; 300 301 List<string> pageIds = new List<string>(); 302 if (hasFeatureListItems) 303 { 304 pageIds.AddRange(featureListItems.Select(fli => fli.Fields.FirstOrDefault(f => f.Name == "Page")?.GetLink().PageId.ToString())); 305 } 306 else if (queryResult.Results.Any()) 307 { 308 pageIds.AddRange(queryResult.Results.Select(qrr => qrr["PageId"].ToString())); 309 } 310 311 string strTitle = string.Empty; 312 string strLink = string.Empty; 313 string strSummary = string.Empty; 314 string strImage = string.Empty; 315 string strType = string.Empty; 316 string badgeTheme = string.Empty; 317 DateTime strDate = new DateTime(); 318 } 319 320 @if ((queryResult.FacetGroups.Any() && allowAllQueryItems) || (queryResult.Results.Any() && !allowAllQueryItems) || featureListItems.Any()) 321 { 322 int loopCounter = 1; // Initialize loop counter for each group 323 324 <section id="section-@Model.Id" class="@sectionClassList" data-swift-gridrow> 325 <div class="container-xl"> 326 <div class="row justify-content-center"> 327 <div class="@rowWidthClasslist"> 328 <div class="js-dalgas-queryresult-container dalgas-queryresult-container" 329 id="@($"query-result-{Model.Id}")"> 330 331 @if (hasLead || hasText || hasHeading) 332 { 333 <div class="js-content-container content-container col-12 mb-3"> 334 335 <div class="col-lg-6"> 336 <span> 337 @string.Join("", headings.Select(h => h.ToString())) 338 </span> 339 340 @if (!string.IsNullOrEmpty(lead)) 341 { 342 <p class="lead">@lead</p> 343 } 344 345 @text 346 347 </div> 348 </div> 349 } 350 351 @{ 352 ButtonViewModel btnViewResult = new ButtonViewModel 353 { 354 Text = Translate("View more"), 355 Type = ButtonType.Link, 356 DisplayType = ButtonDisplayType.Link 357 }; 358 359 if (showAll) 360 { 361 totaleCount = queryResult.TotalCount; 362 } 363 364 365 <form method="post" action="@Pageview.SearchFriendlyUrl" 366 data-response-target-element="content" tabindex="-1" aria-hidden="false" 367 class="d-flex js-dalgas-facets-form dalgas-facets-form" 368 data-total-count="@totaleCount" data-page-size="@numberOfItemsToShow"> 369 <input type="hidden" name="LayoutTemplate" 370 value="Designs/Swift/Swift_PageClean.cshtml"/> 371 <input type="hidden" name="PageNum" value="@pageNum"/> 372 <input type="hidden" name="PageSize" value="@numberOfItemsToShow"/> 373 @if (allowAllQueryItems) 374 { 375 if (showFacets) 376 { 377 foreach (FacetGroup facetGroup in queryResult.FacetGroups) 378 { 379 foreach (Facet facet in facetGroup.Facets) 380 { 381 string showClass = " show"; 382 string ariaExpanded = "true"; 383 string facetGroupId = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(5000)); 384 385 386 if (facet.Options.Any()) 387 { 388 int selectedFacetsInGroup = 0; 389 390 foreach (FacetOption option in facet.Options) 391 { 392 if (option.Selected) 393 { 394 selectedFacetsInGroup++; 395 } 396 } 397 398 string label = selectedFacetsInGroup > 0 ? Translate(facet.Name) + "<span style=\"padding: 0.3em 0.6em\" class=\"badge badge ms-2\">" + selectedFacetsInGroup + "</span>" : Translate(facet.Name); 399 400 <div class="dropdown js-facets-selector"> 401 <button class="btn dropdown-toggle" type="button" 402 id="FacetGroup_@facetGroupId" data-bs-toggle="dropdown" 403 aria-expanded="false"> 404 @label 405 </button> 406 <div data-lenis-prevent class="dropdown-menu p-3" 407 aria-labelledby="FacetGroup_@facetGroupId" 408 style="min-width: 280px"> 409 @foreach (FacetOption facetOption in facet.Options.OrderBy(fo => fo.Label)) 410 { 411 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 412 string disabled = facetOption.Count <= 0 ? "disabled" : string.Empty; 413 string selected = facetOption.Selected ? "checked" : string.Empty; 414 string facetValue = Uri.UnescapeDataString(facetOption.Value); 415 string optionValue = $"[{facetValue}]"; 416 417 facetLabel = facetLabel.ToLower() == "true" ? facetLabel = Translate("Yes") : facetLabel; 418 facetLabel = facetLabel.ToLower() == "false" ? facetLabel = Translate("No") : facetLabel; 419 420 <label class="form-check mt-1" @disabled> 421 <input type="checkbox" 422 onclick="custom.QueryResult.update(event)" 423 class="form-check-input" 424 name="@facet.QueryParameter" 425 value="@optionValue" 426 data-filter-value="@facetLabel" @selected> 427 <span 428 class="form-check-label d-flex align-items-center"> 429 <span class="flex-fill">@facetLabel </span> 430 <small 431 class="opacity-85">@facetOption.Count</small> 432 </span> 433 </label> 434 435 if (facetOption.Selected) 436 { 437 FacetOption selectFacetOption = facetOption; 438 selectFacetOption.Name = facet.QueryParameter; 439 selectedFacetOptions.Add(selectFacetOption); 440 } 441 } 442 </div> 443 </div> 444 } 445 } 446 } 447 448 if (!string.IsNullOrEmpty(searchTerm)) 449 { 450 selectedFacetOptions.Add(new FacetOption() 451 { 452 Count = 1, 453 Label = searchTerm, 454 Name = "q", 455 Selected = true, 456 Value = searchTerm 457 }); 458 } 459 } 460 461 if (showSearch) 462 { 463 <div class="type-ahead-dropdown"> 464 <div class="position-relative suggest-form"> 465 <span 466 class="position-absolute top-0 end-0 icon-3 px-3 d-flex align-items-center h-100 search-icon"> 467 @ReadFile(iconPath + "search.svg") 468 </span> 469 470 <input id="searchField_@Model.Id" 471 class="form-control custom-header-searchbar js-custom-facets-search-field pe-5 ps-3 js-" 472 type="search" 473 placeholder="@Translate("Search here")" 474 autocomplete="off" 475 maxlength="255" 476 name="q" 477 value="@searchTerm" 478 data-original="@searchTerm"> 479 480 <button type="button" 481 onclick="custom.QueryResult.clearSearchField(event)" 482 class="btn h-100 icon-2 reset-search" 483 aria-label="@Translate("Clear search")" 484 style="opacity: 0; position: absolute; top: 0; right: 0; visibility: hidden;"> 485 @ReadFile(iconPath + "x.svg") 486 </button> 487 </div> 488 </div> 489 <input type="submit" onclick="custom.QueryResult.update(event)" 490 class="btn btn-primary" value="@Translate("Search", "Search")"> 491 } 492 } 493 </form> 494 495 if (showFacets && selectedFacetOptions.Any()) 496 { 497 <div 498 class="js-dalgas-queryresult-selectedfacets-container dalgas-queryresult-selectedfacets-container mt-3"> 499 @foreach (FacetOption facetOption in selectedFacetOptions) 500 { 501 string facetValue = Uri.UnescapeDataString(facetOption.Value); 502 string optionValue = $"[{facetValue}]"; 503 <input class="visually-hidden" 504 id="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)" 505 name="@facetOption.Name" 506 onclick="custom.QueryResult.deselectFacetOption(event)" type="checkbox" 507 value="@optionValue" title="@facetOption.Label" checked> 508 <label class="badge theme border border-dark text-nowrap" 509 for="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)"> 510 <span class="text-nowrap">@(facetOption.Label)</span> 511 <span class="icon-2 ms-2"> 512 @ReadFile(iconPath + "x.svg") 513 </span> 514 </label> 515 } 516 517 @if (selectedFacetOptions.Count >= 3) 518 { 519 <input class="visually-hidden" id="ClearAll" name="ClearAll" 520 onclick="custom.QueryResult.clearAll(event)" type="checkbox" value="" 521 title="" checked> 522 <label class="badge theme border border-dark dalgas-btn-clear-all" 523 for="ClearAll"> 524 <span class="text-nowrap">@Translate("Clear all")</span> 525 <span class="icon-2 ms-2"> 526 @ReadFile(iconPath + "x.svg") 527 </span> 528 </label> 529 } 530 </div> 531 }} 532 533 @if (pageIds.Any() == false) 534 { 535 <div class="mt-4">@Translate("Your search returned no results...")</div> 536 } 537 538 <div 539 class="row @(!showAll ? "dalgas-featured-list-mobile-horizontal-scroll" : "mt-5") js-dalgas-queryresult-itemlist dalgas-queryresult-itemlist mt-2"> 540 @foreach (string pageId in pageIds) 541 { 542 if (!int.TryParse(pageId, out int intPageId)) 543 { 544 continue; 545 } 546 547 Page page = Services.Pages.GetPage(intPageId); 548 549 if (page == null) 550 { 551 continue; 552 } 553 554 @* Renders articles from another website language *@ 555 556 string resolvedPageId = pageId; 557 if (PageView.Current().Page.AreaId != page.AreaId) 558 { 559 resolvedPageId = GetPageIdByNavigationTag("ArticlePageFromOtherSite") + "&render-article-id=" + pageId; 560 } 561 562 string articleUrl = SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?ID=" + resolvedPageId); 563 564 strTitle = page.Item["Title"]?.ToString(); 565 strSummary = page.Item["Summary"]?.ToString(); 566 strImage = page.Item["CoverImage"] == null ? string.Empty : page.Item["CoverImage"]?.ToString(); 567 btnViewResult.Id = "pageId_" + page.ID; 568 btnViewResult.Url = !string.IsNullOrEmpty(articleUrl) ? articleUrl : "/Default.aspx?ID=" + resolvedPageId; 569 if (page.Item["Date"] != null) 570 { 571 strDate = (DateTime) page.Item["Date"]; 572 } 573 574 int jpgIndex = strImage.IndexOf(".jpg", StringComparison.OrdinalIgnoreCase); 575 if (jpgIndex != -1) 576 { 577 strImage = strImage.Substring(0, jpgIndex + 4); 578 } 579 580 featuredListImage = ViewModelFactory.CreateFieldFileValueView(strImage); 581 imageList.Add(featuredListImage); 582 583 if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "news") 584 { 585 badgeTheme = ""; 586 if (loopCounter % 6 == 2 || loopCounter % 6 == 4) 587 { 588 newsModolusClasslist = "col-lg-5"; 589 imageAspectRatio = "ratio-16x9"; 590 if (showAll) 591 { 592 imageAspectRatio = "ratio-3x4 ratio-custom-news"; 593 } 594 } 595 else 596 { 597 newsModolusClasslist = "col-lg-3"; 598 imageAspectRatio = "ratio-16x9 ratio-lg-3x4"; 599 if (showAll) 600 { 601 imageAspectRatio = "ratio-3x4"; 602 } 603 } 604 605 loopCounter++; 606 } 607 608 609 <div class="@colClasslist @newsModolusClasslist"> 610 611 @if (!string.IsNullOrEmpty(featuredListImage.Path)) 612 { 613 <a href="@btnViewResult.Url"> 614 <figure class="ratio @imageAspectRatio mb-0"> 615 @RenderPartial("Components/Image.cshtml", featuredListImage ?? new FileViewModel()) 616 </figure> 617 </a> 618 } 619 620 <div class="@cardClasslist"> 621 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "events") 622 { 623 badgeTheme = "mb-5"; 624 } 625 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "events" || Model.Item.GetItem("Content").GetString("FeatureOptions") == "news") 626 { 627 if (strDate != null) 628 { 629 var date = strDate; 630 var formattedDate = date.ToLongDateString(); 631 if (date.TimeOfDay.ToString() != "00:00:00") 632 { 633 formattedDate = formattedDate + " - " + date.ToShortTimeString(); 634 } 635 636 <div class="badge mb-3 @badgeTheme"> 637 @formattedDate 638 </div> 639 } 640 } 641 642 @if (Model.Item.GetItem("Content").GetString("FeatureOptions") == "cases" || Model.Item.GetItem("Content").GetString("FeatureOptions") == "projects") 643 { 644 var selectedValues = page.Item["Type"].ToString(); 645 <div class="badge mb-5 mr-3 @badgeTheme"> 646 @ContentService.Instance.GetLabelForCaseType(selectedValues) 647 </div> 648 } 649 650 @{ 651 var badgeParms = new Dictionary<string, object>(); 652 badgeParms.Add("pageId", page.ID); 653 } 654 @RenderPartial("UserInterfaceModels/badge.cshtml", Model, badgeParms) 655 656 <h4> 657 <a href="@btnViewResult.Url" class="text-decoration-none"> 658 @strTitle 659 </a> 660 </h4> 661 @if (strSummary != null) 662 { 663 <span class="small">@strSummary</span> 664 } 665 666 <div class="mt-2"> 667 @RenderModel(btnViewResult) 668 </div> 669 </div> 670 </div> 671 } 672 </div> 673 674 @if (showAll && totaleCount > numberOfItemsToShow) 675 { 676 <div class="row"> 677 <div class="col-12 text-center"> 678 <button onclick="custom.QueryResult.getNextPage(event)" 679 class="btn btn-primary">@Translate("Vis flere")</button> 680 </div> 681 </div> 682 } 683 684 @if (hasButton) 685 { 686 <div class="js-content-container content-container col-12"> 687 688 <div class="d-flex flex-wrap gap-3"> 689 @foreach (ButtonViewModel button in buttons) 690 { 691 @button 692 } 693 </div> 694 695 </div> 696 } 697 698 </div> 699 </div> 700 </div> 701 </div> 702 @if (enableFifthElement) 703 { 704 <div class="fifth-element-section-container"> 705 <div class="fifth-element size-2 bottom-0 ob-50 right-0 @fifthElementTheme"> 706 @ReadFile(fifthElementIconPath + "sun.svg") 707 </div> 708 </div> 709 } 710 </section> 711 } 712 else 713 { 714 if (Pageview.IsVisualEditorMode) 715 { 716 <div class="container-xl alert alert-danger" role="alert"> 717 This <strong>@Model.Item.SystemName</strong> is empty 718 </div> 719 } 720 } 721