
Wir ändern unseren Namen zu Dalgas
Seit Oktober 2024 treten alle Geschäftsbereiche unter dem einheitlichen Markennamen Dalgas auf. Dies ist auch der Name der dänischen Muttergesellschaft. Die alten Markennamen wie HD SILVA, HD Forest und HD LogSystems gibt es nicht mehr. Die rechtliche Firmierung der deutschen Tochtergesellschaft ist jedoch noch Heidegesellschaft Forstprodukte und -geräte GmbH.
Published on 24. Juni 2024
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/Dalgas_Paragraph.cshtml" System.Exception: Custom field 'AccessUser_JobTitleTranslatedDE' was not found. at Dalgas.Custom.Extensions.UserViewModelExtensions.GetCustomFieldValue[T](UserViewModel user, String fieldSystemName) in D:\a\1\s\Custom\Extensions\UserViewModelExtensions.cs:line 34 at Dalgas.Custom.Extensions.UserViewModelExtensions.GetJobTitleTranslatedDE(UserViewModel user) in D:\a\1\s\Custom\Extensions\UserViewModelExtensions.cs:line 236 at Dalgas.Custom.Extensions.UserViewModelExtensions.GetJobTitle(UserViewModel user) in D:\a\1\s\Custom\Extensions\UserViewModelExtensions.cs:line 255 at CompiledRazorTemplates.Dynamic.RazorEngine_9fe3aa69cd654dc58d752773c4c21eb6.Execute() in E:\Solutions\dalgas\Files\Templates\Designs\Swift\Grid\Page\RowTemplates\Dalgas_Paragraph.cshtml:line 200 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 @using System 2 @using System.Collections.Generic 3 @using System.Linq 4 @using Dalgas.Custom.Extensions 5 @using Dynamicweb.Content 6 @using Dynamicweb.Frontend 7 @using Dalgas.Custom.Services 8 @using Dalgas.Custom.ViewModels.UI 9 @using Dynamicweb.Core.Json 10 @using Dynamicweb.Ecommerce.ProductCatalog 11 @using Dynamicweb.Indexing.Querying 12 @using Dynamicweb.Indexing.Querying.Faceting 13 @using Dynamicweb.Indexing.Querying.Sorting 14 @using Dynamicweb.Modules 15 @using Dynamicweb.Security.UserManagement 16 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 17 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.GridRowViewModel> 18 19 @using System 20 @using System.Collections.Generic 21 @using System.Linq 22 @using Dalgas.Custom.ViewModels.UI 23 @using Dynamicweb.Content 24 @using Dynamicweb.Ecommerce.ProductCatalog 25 @using Dynamicweb.Frontend 26 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 27 28 @*TODO: Move these functions onto the model *@ 29 30 @functions 31 { 32 33 public string GetSectionClassList(GridRowViewModel model, string overwriteTheme = "") 34 { 35 var returnValues = new List<string> 36 { 37 $"item_{model.Item.SystemName.ToLower()}" 38 }; 39 40 if (Services.Grids.GetGridRowById(model.Id).Sort == 1) 41 { 42 returnValues.Add("dalgas-section-first-on-page"); 43 } 44 45 var sectionBackgroundTheme = model.Item.GetItem("ColorScheme")?.GetString("ColorScheme") ?? string.Empty; 46 47 if (!string.IsNullOrEmpty(overwriteTheme)) 48 { 49 sectionBackgroundTheme = overwriteTheme; 50 } 51 52 // Add theme class if it exists 53 if (!string.IsNullOrWhiteSpace(sectionBackgroundTheme)) 54 { 55 if (sectionBackgroundTheme.Contains("default")) 56 { 57 returnValues.Add("theme theme-light"); 58 } 59 else 60 { 61 returnValues.Add($"theme {sectionBackgroundTheme.Replace(" ", "").Trim().ToLower()}"); 62 } 63 } 64 65 // Determine if top padding should be removed 66 67 string removeTopPadding = model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 68 69 returnValues.Add("pb-6"); 70 if (removeTopPadding != "enable") 71 { 72 returnValues.Add("pt-6"); 73 } 74 75 return string.Join(" ", returnValues); 76 } 77 78 } 79 80 81 @{ 82 IEnumerable<HeadingViewModel> headings = ParagraphService.Instance.GetHeadingsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Headings")); 83 string text = Model.Item.GetItem("Paragraph_Text")?.GetString("Text"); 84 string lead = Model.Item.GetItem("Paragraph_Text")?.GetString("Lead"); 85 IEnumerable<ButtonViewModel> buttons = ParagraphService.Instance.GetButtonsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Buttons")); 86 87 bool hasImage = Model.Item.GetItem("Paragraph_Image")?.GetFile("Image") != null; 88 bool hasText = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Text")); 89 bool hasLead = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Lead")); 90 bool hasHeading = headings.Any(); 91 bool hasButton = buttons.Any(); 92 93 var theme = Model.Item.GetItem("ColorScheme")?.GetString("ColorScheme"); 94 var fifthElementTheme = "fifth-element-color-" + Model.Item?.GetItem("ColorScheme")?.GetString("FifthElementColor"); 95 96 var sectionClassList = GetSectionClassList(Model); 97 98 var image = string.Empty; 99 var imageParameters = new Dictionary<string, object>(); 100 101 string layout = string.Empty; 102 Boolean enableFifthElement = false; 103 if (Model?.Item != null) 104 { 105 var paragraphLayout = Model.Item.GetItem("Paragraph_Layout"); 106 107 if (paragraphLayout != null) 108 { 109 layout = paragraphLayout.GetString("Layout"); 110 111 enableFifthElement = !string.IsNullOrEmpty(paragraphLayout.GetString("Layout_FifthElement")); 112 } 113 } 114 115 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Image")?.GetFile("Image")?.Path)) 116 { 117 image = Model.Item.GetItem("Paragraph_Image").GetFile("Image").Path; 118 imageParameters.Add("alt", Model.Item.GetItem("Paragraph_Image")?.GetString("ImageAltText")); 119 int xPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromLeft ?? 50; 120 int yPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromTop ?? 50; 121 string cssPosition = $"{xPos}% {yPos}%"; 122 imageParameters.Add("style", "object-position:" + cssPosition); 123 } 124 125 LinkViewModel imageLink = new LinkViewModel(); 126 if (Model.Item?.GetItem("Paragraph_Image")?.GetItem("Link") != null && !string.IsNullOrEmpty(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link").GetString("ButtonLink"))) 127 { 128 imageLink = ParagraphService.Instance.GetLinkByItem(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link")); 129 } 130 131 string fifthElementIconPath = "/Files/Templates/Designs/Swift/Assets/Images/DalgasFifthElements/"; 132 } 133 134 135 @{ 136 ClassList imageAspectRatio = new ClassList(""); 137 ClassList textClasslist = new ClassList(""); 138 ClassList textContainerClassList = new ClassList(""); 139 ClassList rowClasslist = new ClassList(""); 140 ClassList sectionClasslist = new ClassList("col-md-10"); 141 142 var contentFlow = Model.Item?.GetItem("Content")?.GetString("ContentFlow"); 143 144 IList<ItemViewModel> paragraphItems = Model.Item?.GetItem("Content")?.GetItems("ContentType") ?? Enumerable.Empty<ItemViewModel>().ToList(); 145 Page page = Services.Pages.GetPage(PageView.Current().Page.ID); 146 147 if (!string.IsNullOrEmpty(page.Item["Author"]?.ToString())) 148 { 149 textClasslist.Remove("col-lg-6"); 150 textClasslist.Add("col-lg-9"); 151 sectionClasslist.Remove("col-md-10"); 152 textContainerClassList.Add("col-lg-9 offset-lg-1"); 153 } 154 155 string removeTopPadding = Model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 156 157 if (contentFlow == "vertical") 158 { 159 if (removeTopPadding != "enable") 160 { 161 rowClasslist.Add("gap-6"); 162 } 163 164 imageAspectRatio.Add("ratio-21x9"); 165 } 166 else 167 { 168 sectionClasslist.Add("col-xxl-10"); 169 rowClasslist.Add("g-5"); 170 imageAspectRatio.Add("ratio-16x9"); 171 textClasslist.Add("col-lg-6"); 172 } 173 } 174 175 <section id="section-@Model.Id" class="@sectionClassList" data-swift-gridrow> 176 <div class=""> 177 178 @if (paragraphItems.Count > 0) 179 { 180 <div class="container-xl"> 181 <div class="row justify-content-center"> 182 <div class="col-12 @sectionClasslist"> 183 184 <div class="row flex-column-reverse flex-lg-row"> 185 186 @if (page.Item["Author"] != null) 187 { 188 var authorValue = page.Item["Author"]; 189 if (int.TryParse((string) authorValue, out int parsedValue)) 190 { 191 int articleAuthor = parsedValue; 192 UserCollection authers = User.GetUsersByIds(new List<int> {articleAuthor}); 193 foreach (var author in authers) 194 { 195 UserViewModel resultViewModel = author.ToViewModel(); 196 object contactPhone = resultViewModel.Phone; 197 object contactEmail = resultViewModel.GetContactEmail(); 198 object contactImage = resultViewModel.Image; 199 object contactName = resultViewModel.Name; 200 object contactTitle = resultViewModel.GetJobTitle(); 201 FileViewModel imageFile = ViewModelFactory.CreateFieldFileValueView(contactImage.ToString()); 202 203 <div class="col-6 col-lg-2 mb-5"> 204 <div class="position-sticky" style="top: calc(var(--header-height)* 2);"> 205 <div class="p-img-container d-flex"> 206 <figure class="ratio ratio-1x1"> 207 @RenderPartial("Components/Image.cshtml", imageFile ?? new FileViewModel()) 208 </figure> 209 </div> 210 <div class="p-txt-container mt-2"> 211 <h4 class="mb-2">@contactName</h4> 212 213 <div class="small d-flex flex-column mb-3 opacity-75"> 214 <span>@contactTitle</span> 215 </div> 216 @if (!string.IsNullOrEmpty(contactEmail?.ToString())) 217 { 218 <div class="d-flex gap-3 small opacity-75"> 219 <span>E.</span> 220 <span>@contactEmail</span> 221 </div> 222 } 223 @if (!string.IsNullOrEmpty(contactPhone?.ToString())) 224 { 225 <div class="d-flex gap-3 small opacity-75"> 226 <span>T.</span> 227 <span>@contactPhone</span> 228 </div> 229 } 230 </div> 231 </div> 232 </div> 233 } 234 } 235 } 236 237 <div class="@textContainerClassList"> 238 <div class="row @rowClasslist"> 239 240 @* Topic, Issue & Podcast *@ 241 242 @{ 243 // Topic – Gets value from "Tag" Dropdown List 244 string topicTitle = string.Empty; 245 string topicLink = string.Empty; 246 247 // Check if there is a related topic and get the first related topic item ID 248 string topicItemId = page.Item["RelatedTopics"]?.ToString() 249 ?.Split(',') 250 .Select(v => v.Trim()) 251 .FirstOrDefault(id => !string.IsNullOrEmpty(id)); 252 253 if (!string.IsNullOrEmpty(topicItemId)) 254 { 255 // Fetch the item using topicItemId and retrieve both Title and Link fields 256 var topicItem = Services.Items.GetItem("HS_TopicType", topicItemId); 257 if (topicItem != null) 258 { 259 topicTitle = topicItem["Title"]?.ToString() ?? string.Empty; 260 topicLink = topicItem["Link"]?.ToString() ?? string.Empty; // Assuming "Link" is the field for the link 261 } 262 } 263 264 // Issue – Gets value from "Tag" Dropdown List 265 266 string issueTitle = string.Empty; 267 string issueLink = string.Empty; 268 269 // Check if there is a related issue and get the first related issue item ID 270 string issueItemId = page.Item["RelatedIssues"]?.ToString() 271 ?.Split(',') 272 .Select(v => v.Trim()) 273 .FirstOrDefault(id => !string.IsNullOrEmpty(id)); 274 275 if (!string.IsNullOrEmpty(issueItemId)) 276 { 277 // Fetch the item using issueItemId and retrieve both Title and Link fields 278 var issueItem = Services.Items.GetItem("HS_IssueType", issueItemId); 279 if (issueItem != null) 280 { 281 issueTitle = issueItem["Title"]?.ToString() ?? string.Empty; 282 issueLink = issueItem["Link"]?.ToString() ?? string.Empty; // Assuming "Link" is the field for the link 283 } 284 } 285 286 // Podcast 287 string podcastInput = page.Item["Podcast"]?.ToString(); // Replace with the actual model property if using a form or similar 288 string embedBaseUrl = "https://embed.podcasts.apple.com"; 289 string podcastSrcUrl; 290 291 // Check if the input is a full URL 292 if (Uri.TryCreate(podcastInput, UriKind.Absolute, out Uri parsedUri) && parsedUri.Host.Contains("apple.com")) 293 { 294 // If it's a full URL, build the src URL using its path and query 295 podcastSrcUrl = $"{embedBaseUrl}{parsedUri.PathAndQuery}&theme=auto"; 296 } 297 else 298 { 299 // If only an ID is provided, construct the URL assuming a US podcast region 300 podcastSrcUrl = $"{embedBaseUrl}/us/podcast/id{podcastInput}?theme=auto"; 301 } 302 } 303 304 @if (!string.IsNullOrEmpty(topicTitle)) 305 { 306 <div class="col-12 col-sm-6 col-lg-4 col-xxl-3"> 307 308 <div class="mb-3 col-6 col-sm-10 small"> 309 @Translate("Knowledge Topic - Text", "Artiklen er en del af vores tema om") @topicTitle 310 </div> 311 312 @if (!string.IsNullOrEmpty(topicLink)) 313 { 314 <div> 315 <a href="@topicLink" class="btn btn-secondary btn-sm fs-7"> 316 @Translate("Knowledge Topic - Button Text", "Gå til overblik") 317 </a> 318 </div> 319 } 320 321 </div> 322 } 323 324 @if (!string.IsNullOrEmpty(issueTitle)) 325 { 326 <div class="col-12 col-sm-6 col-lg-4 col-xxl-3"> 327 <div class="mb-3 col-6 col-sm-10 small"> 328 @Translate("Knowledge Issue - Text", "Artiklen er også bragt i vores medlemsmagasin") @issueTitle 329 </div> 330 @if (!string.IsNullOrEmpty(issueLink)) 331 { 332 <a href="@issueLink" class="btn btn-secondary btn-sm fs-7"> 333 @Translate("Knowledge Issue - Button Text", "Se mere om Vækst") 334 </a> 335 } 336 </div> 337 <hr class="col-12 opacity-0 m-0"/> 338 } 339 <div class="col-12 col-lg-9"> 340 @if (!string.IsNullOrEmpty(podcastInput)) 341 { 342 if (podcastInput.Contains(".mp3")) 343 { 344 <div class="theme theme-mud p-4"> 345 <audio controls class="w-100"> 346 <source src="@podcastInput" type="audio/mpeg"> 347 Your browser does not support the audio element. 348 </audio> 349 <a href="@podcastInput" class="btn btn-link" target="_blank" 350 download> 351 @Translate("Download lydfil") 352 </a> 353 </div> 354 } 355 else 356 { 357 <div class="cookieconsent-optout-marketing p-4 border" 358 style="border-color: var(--swift-accent-color) !important;"> 359 <a href="javascript:Cookiebot.renew()"> 360 @Translate("CookieBot - Please", "Venligst") @Translate("CookieBot - accept marketing-cookies", "acceptere marketing-cookies") 361 @Translate("CookieBot - to hear this podcast.", "for at se lytte til denne podcast") 362 </a> 363 </div> 364 365 <div class="cookieconsent-optin-marketing" 366 data-cookieconsent="marketing" 367 data-cookieblock-src="@podcastSrcUrl"> 368 369 <iframe 370 allow="autoplay *; encrypted-media *; fullscreen *; clipboard-write" 371 frameborder="0" 372 height="175" 373 style="width:100%;max-width:100%;overflow:hidden;border-radius:10px;" 374 sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-storage-access-by-user-activation allow-top-navigation-by-user-activation" 375 data-cookieblock-src="@podcastSrcUrl" 376 data-cookieconsent="marketing"> 377 </iframe> 378 379 @if (!string.IsNullOrEmpty(Pageview.AreaSettings.GetString("Podcast_Page_Link"))) 380 { 381 <a href="@Pageview.AreaSettings.GetString("Podcast_Page_Link")" 382 class="btn btn-link"> 383 @Translate("Podcast – Find flere episoder – Link", "Find flere episoder") 384 </a> 385 } 386 </div> 387 } 388 } 389 </div> 390 391 @foreach (var item in paragraphItems.Select((item, index) => new {Item = item, Index = index + 1})) 392 { 393 if (item.Index > 1) 394 { 395 } 396 397 var paragraphItem = item.Item; 398 string paragraphLead = paragraphItem.GetItem("Paragraph_Text").GetString("Lead"); 399 string paragraphText = paragraphItem.GetItem("Paragraph_Text").GetString("Text"); 400 IEnumerable<HeadingViewModel> paragraphHeadings = ParagraphService.Instance.GetHeadingsByItems(paragraphItem.GetItem("Paragraph_Text").GetItems("Headings")); 401 IEnumerable<ButtonViewModel> paragraphButtons = ParagraphService.Instance.GetButtonsByItems(paragraphItem.GetItem("Paragraph_Text").GetItems("Buttons")); 402 403 string colorScheme = paragraphItem.GetItem("ColorScheme")?.GetString("ColorScheme"); 404 string paragraphTheme = string.Empty; 405 406 if (!string.IsNullOrEmpty(colorScheme) && colorScheme != theme) 407 { 408 paragraphTheme = "p-4 pb-1 theme " + colorScheme; 409 } 410 411 bool hasMedia = !string.IsNullOrEmpty(paragraphItem.GetItem("Paragraph_Media")?.GetItem("Video").GetString("VideoSourceID")) || !string.IsNullOrEmpty(paragraphItem.GetItem("Paragraph_Media")?.GetItem("Video").GetString("VideoPath")); 412 413 string quote = paragraphItem?.GetItem("Paragraph_Quote")?.GetString("Text"); 414 string name = paragraphItem?.GetItem("Paragraph_Quote")?.GetString("Name"); 415 string titleAndCompany = paragraphItem?.GetItem("Paragraph_Quote")?.GetString("TitleAndCompany"); 416 417 418 <div class="col-12 @textClasslist"> 419 <div class="@paragraphTheme"> 420 @if (string.IsNullOrEmpty(paragraphLead) && string.IsNullOrEmpty(quote) && string.IsNullOrEmpty(paragraphText) && paragraphButtons.Count() < 1 && paragraphHeadings.Count() < 1 && string.IsNullOrEmpty(paragraphItem.GetItem("Paragraph_Media").GetItem("Image").GetString("Image")) && !hasMedia) 421 { 422 if (Pageview.IsVisualEditorMode) 423 { 424 <div class="alert alert-light" role="alert"> 425 This column is empty. <br/> 426 You can use it as a "Ghost" paragraph, otherwise it should 427 be 428 deleted. 429 </div> 430 } 431 } 432 else 433 { 434 <div 435 class="js-content-container content-container d-flex flex-column @(hasMedia ? "gap-2" : "")"> 436 437 @if (paragraphItem.GetItem("Paragraph_Media")?.GetField("Media").Value.ToString() == "Image" && !string.IsNullOrEmpty(paragraphItem.GetItem("Paragraph_Media").GetItem("Image").GetString("Image"))) 438 { 439 imageLink = ParagraphService.Instance.GetLinkByItem(paragraphItem?.GetItem("Paragraph_Media")?.GetItem("Image")?.GetItem("Link")); 440 441 if (imageLink != null && !string.IsNullOrEmpty(imageLink.Url)) 442 { 443 <a href="@imageLink.Url"> 444 <figure 445 class="mb-0 d-flex flex-column mb-3"> 446 @RenderPartial("Components/Image.cshtml", paragraphItem.GetItem("Paragraph_Media").GetItem("Image").GetFile("Image") ?? new FileViewModel()) 447 </figure> 448 </a> 449 } 450 else 451 { 452 <figure 453 class="mb-0 d-flex flex-column mb-3"> 454 @RenderPartial("Components/Image.cshtml", paragraphItem.GetItem("Paragraph_Media").GetItem("Image").GetFile("Image") ?? new FileViewModel()) 455 </figure> 456 } 457 } 458 else if (paragraphItem.GetItem("Paragraph_Media")?.GetField("Media").Value.ToString() == "Video") 459 { 460 string provider = paragraphItem?.GetItem("Paragraph_Media")?.GetItem("Video").GetRawValueString("VideoSourceProvider", "none"); 461 string videoId = paragraphItem?.GetItem("Paragraph_Media")?.GetItem("Video").GetString("VideoSourceID"); 462 Dynamicweb.Frontend.FileViewModel video = paragraphItem?.GetItem("Paragraph_Media")?.GetItem("Video").GetFile("VideoPath"); 463 string videoPath = video?.Path ?? ""; 464 465 <div class="cookieconsent-optout-marketing p-4 border" 466 style="border-color: var(--swift-accent-color) !important;"> 467 <a href="javascript:Cookiebot.renew()"> 468 @Translate("CookieBot - Please", "Venligst") @Translate("CookieBot - accept marketing-cookies", "acceptere marketing-cookies") 469 @Translate("CookieBot - to watch this video.", "for at se denne video") 470 </a> 471 </div> 472 473 <div class="cookieconsent-optin-marketing" 474 data-cookieconsent="marketing" 475 data-cookieblock-src="@videoPath"> 476 477 @switch (provider) 478 { 479 case "youtube": 480 case "vimeo": 481 482 <div 483 id="player_@paragraphItem.Id" 484 class="player plyr__video-embed theme theme-light h-100 w-100 plyr-instance" 485 data-plyr-provider="@provider" 486 data-plyr-embed-id="@videoId" 487 style="--plyr-color-main: var(--swift-foreground-color); "> 488 </div> 489 490 break; 491 492 case "self-hosted": 493 494 <video 495 id="player_@paragraphItem.Id" 496 class="player plyr__video-embed theme theme-light h-100 w-100 plyr-instance" 497 src="@videoPath" 498 style="--plyr-color-main: var(--swift-foreground-color);" 499 preload="metadata"> 500 </video> 501 502 break; 503 } 504 <script type="module" defer 505 src="~/Files/Templates/Designs/Swift/Assets/js/plyr.js"></script> 506 <script type="text/plain" 507 data-cookieconsent="marketing"> 508 509 const players = document.querySelectorAll('.plyr-instance'); 510 players.forEach(function(playerElement) { 511 new Plyr(playerElement, { 512 type: 'video', 513 youtube: { 514 noCookie: true, 515 showinfo: 0 516 }, 517 fullscreen: { 518 enabled: true, 519 iosNative: true, 520 } 521 }); 522 }); 523 </script> 524 525 </div> 526 } 527 528 <div> 529 530 @if (paragraphItem.GetItem("Paragraph_Media")?.GetField("Media").Value.ToString() == "Graphic") 531 { 532 <div class="p-graphic-container mb-3"> 533 <div 534 class="graphic-size-@paragraphItem.GetItem("Paragraph_Media").GetItem("Graphic").GetString("GraphicSize")"> 535 @RenderPartial("Components/Image.cshtml", paragraphItem?.GetItem("Paragraph_Media")?.GetItem("Graphic")?.GetFile("Image") ?? new FileViewModel()) 536 </div> 537 </div> 538 } 539 @if (!string.IsNullOrEmpty(quote)) 540 { 541 <div class="col-12"> 542 543 <p class="quote">"@quote</p> 544 <h4 class="fs-6 mb-2">@name</h4> 545 <p class="small">@titleAndCompany</p> 546 547 </div> 548 } 549 <div> 550 <span> 551 @string.Join("", paragraphHeadings.Select(h => h.ToString())) 552 </span> 553 554 <span> 555 @if (!string.IsNullOrEmpty(paragraphLead)) 556 { 557 <p class="lead">@paragraphLead</p> 558 } 559 @paragraphText 560 </span> 561 @string.Join("", paragraphButtons.Select(h => h.ToString())) 562 </div> 563 </div> 564 565 </div> 566 } 567 </div> 568 </div> 569 } 570 </div> 571 </div> 572 </div> 573 </div> 574 </div> 575 576 </div> 577 } 578 else 579 { 580 if (Pageview.IsVisualEditorMode) 581 { 582 <div class="container-xl alert alert-danger" role="alert"> 583 This <strong>@Model.Item.SystemName</strong> is empty 584 </div> 585 } 586 } 587 </div> 588 </section> 589
Neuigkeiten aus der Natur
Dienstag, 10. Juni 2025
Dalgas geht neue Partnerschaft für digitale Messlösungen in der Forst- und Holzindustrie ein
Die Produkte LogStackLIDAR und LogStackPRO von Dalgas werden nun Teil des digitalen Portfolios von ForestX. Die neue Partnerschaft soll die Digitalisierung der Forst- und Holzindustrie in Europa stärken.Artikel und Inspiration

Whitepaper - Aufforstungsmöglichkeiten in den baltischen Staaten
Erwägen Sie, Ihr Anlageportfolio mit Forstwirtschaft in den baltischen Staaten zu diversifizieren, aber Ihnen fehlt das tiefgehende Wissen über die lokalen Vorschriften? Wir können Ihnen einen Überblick verschaffen.
Whitepaper - 10 Mythen über Waldinvestitionen
Entdecken Sie, was wahr und falsch über Waldinvestitionen ist.Fotooptische Vermessung von Holzpoltern ist nun Bestandteil der Rahmenvereinbarung für den Rohholzhandel in Deutschland (RVR)
Der deutsche Forstwirtschaftsrat und der deutsche Holzwirtschaftsrat haben die fotooptische Vermessung mit geeichten Systemen wie unserem LogStackPro in die Rahmenvereinbarung für den Rohholzhandel in Deutschland aufgenommen.