2-3 May, 2025
Days of Knowledge Nordic 2025
Join us in Odense, in the core of Denmark, for Days of Knowledge Nordic 2025! This local training event offers a unique opportunity for continuous learning in Business Central and related products, mastering cloud and AI technologies and accelerating technology adoption. Stay ahead by gaining the skills to implement modern customer solutions efficiently and connect with the Dynamics community to deliver more value to your clients.
Error executing template "Designs/Swift/Paragraph/COMM_SpeakerWall.cshtml" System.Net.WebException: The remote server returned an error: (404) Not Found. at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) at System.Net.WebClient.DownloadString(Uri address) at CompiledRazorTemplates.Dynamic.RazorEngine_060e5ae436a74cb5a6c9ba53b731f81b.GetJson(String address) in C:\inetpub\wwwroot\directions2023\Files\Templates\Designs\Swift\Paragraph\COMM_SpeakerWall.cshtml:line 145 at CompiledRazorTemplates.Dynamic.RazorEngine_060e5ae436a74cb5a6c9ba53b731f81b.Execute() in C:\inetpub\wwwroot\directions2023\Files\Templates\Designs\Swift\Paragraph\COMM_SpeakerWall.cshtml:line 262 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.ParagraphViewModel> 2 @using Dynamicweb.Frontend.Navigation 3 @using Dynamicweb.Content.Items 4 @using Dynamicweb.Frontend 5 @using System.Web.Helpers 6 @using System.Web 7 @using System.Text 8 @using System.Net 9 @using System.Linq 10 @using System 11 @using System.Globalization 12 @using Newtonsoft.Json 13 @using Newtonsoft.Json.Linq 14 15 16 @functions{ 17 18 19 public class Root 20 { 21 public List<Session> sessions {get; set;} 22 public List<Speaker> speakers {get; set;} 23 public List<Category> categories {get; set;} 24 } 25 26 public class Session 27 { 28 public string id {get; set;} 29 public string title {get; set;} 30 public string description {get; set;} 31 public DateTime? startsAt {get; set;} 32 public DateTime? endsAt {get; set;} 33 public bool isServiceSession {get; set;} 34 public bool isPlenumSession {get; set;} 35 public List<string> speakers {get; set;} 36 public List<int> categoryItems {get; set;} 37 public List<QuestionAnswers> questionAnswers {get; set;} 38 public int? roomId {get; set;} 39 //liveUrl 40 //recordingUrl 41 } 42 43 public class categoryItems 44 { 45 public string name { get; set; } 46 } 47 // For Speaker class 48 public class sessions 49 { 50 public int id { get; set; } 51 public string name { get; set; } 52 } 53 // For Speaker class 54 public class categories 55 { 56 public int id { get; set; } 57 public string name { get; set; } 58 public List<Item> categoryItems {get; set;} 59 public int sort { get; set; } 60 } 61 62 public class Speaker 63 { 64 public string id {get; set;} 65 public string firstName {get; set;} 66 public string lastName {get; set;} 67 public string bio {get; set;} 68 public string tagLine {get; set;} 69 public string profilePicture {get; set;} 70 public bool isTopSpeaker {get; set;} 71 public List<Link> links {get; set;} 72 73 public List<sessions> sessions {get; set;} 74 public List<categories> categories { get; set; } 75 public string fullName {get; set;} 76 public List<int> categoryItems {get; set;} 77 public List<QuestionAnswers> questionAnswers {get; set;} 78 public int displayPriority {get; set;} 79 } 80 81 public class Category 82 { 83 public int id {get; set;} 84 public string title {get; set;} 85 public List<Item> items {get; set;} 86 public int sort {get; set;} 87 public string type {get; set;} 88 } 89 90 public class Link 91 { 92 public string title {get; set;} 93 public string url {get; set;} 94 public string linType {get; set;} 95 } 96 97 public class Item 98 { 99 public int id {get; set;} 100 public string name {get; set;} 101 public int sort {get; set;} 102 } 103 104 public class Timeslot 105 { 106 public string Code {get; set;} 107 public DateTime? DateAndStart {get; set;} 108 public DateTime? SlotDate {get; set;} 109 public DateTime SlotDuration {get; set;} 110 public string SlotEnd {get; set;} 111 public string SlotStart {get; set;} 112 public string Status {get; set;} 113 114 } 115 116 public class Attribute 117 { 118 public string categoryTitle {get; set;} 119 public int categoryId {get; set;} 120 public int categorySort {get; set;} 121 public int attributeId {get; set;} 122 public string attributeName {get; set;} 123 public int attributeSort {get; set;} 124 } 125 126 public string GetTimeslot(Session session) 127 { 128 string code = session.startsAt != null && session.endsAt != null ? session.startsAt.ToString().GetHashCode().ToString("x") + session.endsAt.ToString().GetHashCode().ToString("x") : "UNDEFINED"; 129 return code; 130 } 131 132 public class QuestionAnswers 133 { 134 public string questionId {get; set;} 135 public string answerValue {get; set;} 136 } 137 138 static string GetJson(string address) 139 { 140 using (var client = new WebClient()) 141 { 142 client.Headers.Add("Content-Type", "application/json"); 143 try 144 { 145 return client.DownloadString(address); 146 } 147 catch (InvalidCastException e) 148 { 149 return ""; 150 } 151 } 152 } 153 154 string makeStringReadable(string data){ 155 string myStr = data; 156 byte[] bytes = Encoding.Default.GetBytes(myStr); 157 return Encoding.UTF8.GetString(bytes); 158 } 159 //we define variables for acces in other helpers 160 string theme = ""; 161 bool showSummary = false; 162 string sessionDetailsPage = ""; 163 } 164 165 166 @{ 167 var parentPages = Dynamicweb.Content.Services.Pages.GetAncestors(Pageview.Page.ID, true); 168 Dynamicweb.Content.Page rootPage = parentPages.Any() ? parentPages.Where(x => x.ItemType == "COMM_EventSection").FirstOrDefault() : new Dynamicweb.Content.Page(); 169 theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) && Model.Item.GetRawValueString("Theme") != "no-theme" ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 170 171 var item = Dynamicweb.Content.Services.Items.GetItem(rootPage.ItemType, rootPage.ItemId); 172 var sessionizeCode = item?["SessionizeCode"].ToString() ?? ""; 173 var parentTheme = !string.IsNullOrEmpty(item?["Theme"].ToString()) ? "theme " + item?["Theme"].ToString() : ""; 174 var eventCode = !string.IsNullOrEmpty(Model.Item?.GetString("SessionizeCode")) ? Model.Item?.GetString("SessionizeCode") : sessionizeCode; 175 sessionDetailsPage = !string.IsNullOrEmpty(Model.Item?.GetString("SessionDetailPage")) ? Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(Model.Item?.GetString("SessionDetailPage")) : ""; 176 177 theme = theme != "" ? theme : parentTheme; 178 179 showSummary = Model.Item.GetBoolean("ShowSummaryOnly"); 180 181 182 183 string eyebrow = Model.Item.GetString("Eyebrow", string.Empty).Replace(System.Environment.NewLine, "<br>"); 184 string eyebrowHeadingLevel = Model.Item.GetString("EyebrowHeadingLevel", "h3"); 185 string eyebrowFontSize = Model.Item.GetRawValueString("EyebrowFontSize", "h5"); 186 string eyebrowColor = Model.Item.GetString("EyebrowColor", "text-inherit"); 187 string eyebrowTextOpacity = Model.Item.GetString("EyebrowTextOpacity", "opacity-100"); 188 string eyebrowCssClass = Model.Item.GetString("EyebrowCssClass", string.Empty); 189 string eyebrowSpacingBottomDesktop = Model.Item.GetRawValueString("EyebrowSpacingBottomDesktop", "default"); 190 eyebrowSpacingBottomDesktop = eyebrowSpacingBottomDesktop != "default" ? eyebrowSpacingBottomDesktop : string.Empty; 191 string eyebrowSpacingBottomMobile = Model.Item.GetRawValueString("EyebrowSpacingBottomMobile", "default"); 192 eyebrowSpacingBottomMobile = eyebrowSpacingBottomMobile != "default" ? eyebrowSpacingBottomMobile : string.Empty; 193 194 string title = Model.Item.GetString("Title", string.Empty).Replace(System.Environment.NewLine, "<br>"); 195 string titleHeadingLevel = Model.Item.GetString("TitleHeadingLevel", "h2"); 196 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h2"); 197 string titleColor = Model.Item.GetString("TitleColor", "text-inherit"); 198 string titleTextOpacity = Model.Item.GetString("TitleTextOpacity", "opacity-100"); 199 string titleCssClass = Model.Item.GetString("TitleCssClass", string.Empty); 200 string titleSpacingBottomDesktop = Model.Item.GetRawValueString("TitleSpacingBottomDesktop", "default"); 201 titleSpacingBottomDesktop = titleSpacingBottomDesktop != "default" ? titleSpacingBottomDesktop : string.Empty; 202 string titleSpacingBottomMobile = Model.Item.GetRawValueString("TitleSpacingBottomMobile", "default"); 203 titleSpacingBottomMobile = titleSpacingBottomMobile != "default" ? titleSpacingBottomMobile : string.Empty; 204 205 string subtitle = Model.Item.GetString("Subtitle", string.Empty).Replace(System.Environment.NewLine, "<br>"); 206 string subtitleHeadingLevel = Model.Item.GetString("SubtitleHeadingLevel", "p"); 207 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 208 string subtitleColor = Model.Item.GetString("SubtitleColor", "text-inherit"); 209 string subtitleTextOpacity = Model.Item.GetString("SubtitleTextOpacity", "opacity-100"); 210 string subtitleCssClass = Model.Item.GetString("SubtitleCssClass", string.Empty); 211 string subtitleSpacingBottomDesktop = Model.Item.GetRawValueString("SubtitleSpacingBottomDesktop", "default"); 212 subtitleSpacingBottomDesktop = subtitleSpacingBottomDesktop != "default" ? subtitleSpacingBottomDesktop : string.Empty; 213 string subtitleSpacingBottomMobile = Model.Item.GetRawValueString("SubtitleSpacingBottomMobile", "default"); 214 subtitleSpacingBottomMobile = subtitleSpacingBottomMobile != "default" ? subtitleSpacingBottomMobile : string.Empty; 215 216 //Button 1 217 var button1Link = Model.Item.GetLink("Button1Link"); 218 var button1Label = Model.Item.GetString("Button1Label", string.Empty); 219 var button1Icon = Model.Item.GetRawValueString("Button1Icon"); 220 var button1IconPosition = Model.Item.GetRawValueString("Button1IconPosition", "right"); 221 var button1Style = Model.Item.GetRawValueString("Button1Style", "btn-primary"); 222 223 //Button 2 224 var button2Link = Model.Item.GetLink("Button2Link"); 225 var button2Label = Model.Item.GetString("Button2Label", string.Empty); 226 var button2Icon = Model.Item.GetRawValueString("Button2Icon"); 227 var button2IconPosition = Model.Item.GetRawValueString("Button2IconPosition", "right"); 228 var button2Style = Model.Item.GetRawValueString("Button2Style", "btn-primary"); 229 230 string contentAlignment = "align-items-center justify-content-center"; 231 string contentTextAlignment = "text-start"; 232 233 string renderTextCss = showSummary ? "d-none" : ""; 234 235 string layout = Model.Item.GetRawValueString("DisplayMode"); 236 string gridLayout = Model.Item.GetRawValueString("GridLayout"); 237 238 } 239 240 <div class="h-100 item_@Model.Item.SystemName.ToLower()"> 241 <div class="@renderTextCss"> 242 @if (!string.IsNullOrEmpty(eyebrow)) 243 { 244 @RenderContent(eyebrow, eyebrowHeadingLevel, eyebrowFontSize, eyebrowColor, eyebrowTextOpacity, eyebrowSpacingBottomDesktop, eyebrowSpacingBottomMobile, eyebrowCssClass) 245 } 246 247 @if (!string.IsNullOrEmpty(title)) 248 { 249 @RenderContent(title, titleHeadingLevel, titleFontSize, titleColor, titleTextOpacity, titleSpacingBottomDesktop, titleSpacingBottomMobile, titleCssClass) 250 } 251 252 @if (!string.IsNullOrEmpty(subtitle)) 253 { 254 @RenderContent(subtitle, subtitleHeadingLevel, subtitleFontSize, subtitleColor, subtitleTextOpacity, subtitleSpacingBottomDesktop, subtitleSpacingBottomMobile, subtitleCssClass) 255 } 256 </div> 257 258 @if (!string.IsNullOrEmpty(eventCode)) 259 { 260 261 string sessionizeSpeakers = "https://sessionize.com/api/v2/"+ sessionizeCode + "/view/Speakers"; 262 string response = GetJson(sessionizeSpeakers).ToString(); 263 var speakers = JsonConvert.DeserializeObject<List<Speaker>>(response); 264 265 //extend speakers with DisplayPriority property 266 List<Speaker> updatedSpeakers = new List<Speaker>(); 267 foreach(var speaker in speakers) 268 { 269 var speakerCategories = speaker.categories; 270 var speakerDisplayPriorities = speakerCategories != null ? speakerCategories.Where(c => c.name =="DisplayPriority")?.FirstOrDefault() : new categories(); 271 var categoryItems = speakerDisplayPriorities != null ? speakerDisplayPriorities.categoryItems : new List<Item>(); 272 Item priority = categoryItems.Any() ? categoryItems.FirstOrDefault() : new Item();//speaker.categories != null ? speaker.categories.Where(c => c.name =="DisplayPriority")?.FirstOrDefault().categoryItems?.FirstOrDefault() : new Item(); 273 //var priority = speaker.categories.Where(c => c.name =="DisplayPriority")?.FirstOrDefault().categoryItems?.FirstOrDefault();// : new Item(); 274 275 276 Speaker updatedSpeaker = new Speaker(); 277 updatedSpeaker = speaker; 278 updatedSpeaker.displayPriority = priority.name != null ? Dynamicweb.Core.Converter.ToInt32(priority.name) : 99; 279 updatedSpeakers.Add(updatedSpeaker); 280 } 281 282 //sort speakers by display priority 283 speakers = updatedSpeakers.OrderBy(x=>x.displayPriority).ThenBy(x=>x.lastName).ToList(); 284 if(speakers.Any()) 285 { 286 @RenderSpeakers(speakers , showSummary , theme , sessionDetailsPage, layout, gridLayout) 287 } 288 289 } 290 else 291 { 292 <div class="alert alert-info" role="alert"> 293 <span>@Translate("Missing sessionize Id")</span> 294 </div> 295 } 296 </div> 297 298 @helper RenderSpeakers(System.Collections.Generic.List<Speaker> speakers, bool showSummary , string theme , string sessionDetailsPage, string layout, string gridLayout) 299 { 300 string iconBadgeWidth = Model.Item.GetString("IconBadgeWidth"); 301 string iconBadgeHeight = Model.Item.GetString("IconBadgeHeight"); 302 303 var summaryCss = showSummary ? "grid-auto-rows-1-fr" : ""; 304 var gridCss = !showSummary ? "grid" : "container-lg p-0"; 305 int categoryParameter = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["Category"]) ? 306 Convert.ToInt32(Dynamicweb.Context.Current.Request.QueryString["Category"]) : 0; 307 308 bool isSlider = layout == "carousel"; 309 310 var filtersList = new string []{"SpeakerType"}; 311 312 bool hideSpeakerCategory = Model.Item.GetBoolean("HideSpeakerCategory"); 313 314 List<Attribute> sessionizeAttributes = new List<Attribute>(); 315 316 foreach (var speaker in speakers) 317 { 318 foreach(var category in speaker.categories) 319 { 320 foreach(var element in category.categoryItems) 321 { 322 if(category.name == "SpeakerType") 323 { 324 Attribute attribute = new Attribute(); 325 attribute.categoryTitle = category.name; 326 attribute.categoryId = category.id; 327 attribute.categorySort = category.sort; 328 attribute.attributeId = element.id; 329 attribute.attributeName = element.name; 330 // attribute.attributeSort = element.sort; 331 sessionizeAttributes.Add(attribute); 332 } 333 } 334 } 335 } 336 337 //Remove grouping 338 var groupedAttributes = sessionizeAttributes.GroupBy( 339 attr => attr.categoryTitle, 340 (key, g) => new { Title = key, Items = g.GroupBy(x => x.attributeId).Select(x => x.First()).ToList() }); 341 342 343 string categoryId = Model.Item.GetRawValueString("CategoryId"); 344 345 if (!showSummary && string.IsNullOrEmpty(categoryId)) 346 { 347 <div class="grid mb-3"> 348 @{ 349 Uri url = Dynamicweb.Context.Current.Request.Url; 350 var query = System.Web.HttpUtility.ParseQueryString(url.Query); 351 query.Remove("Category"); 352 var link = new UriBuilder( url ) { Query = query.ToString() }.Uri; 353 } 354 @foreach (var attrCollection in groupedAttributes) 355 { 356 foreach (var attr in attrCollection.Items.Where(item => item.attributeId == categoryParameter)) 357 { 358 <a href="@link" class="px-0 g-col-lg-3 g-col-12 btn btn-link btn-sm d-flex justify-content-between align-items-center"> 359 <span>@attrCollection.Title : @attr.attributeName</span> 360 <span class="btn-close btn-sm" aria-label="Close"></span> 361 </a> 362 } 363 } 364 </div> 365 <div class="grid mb-4"> 366 <div class="g-col-lg-3 g-col-12"> 367 <div class="form-group"> 368 <label class="fw-bold mb-2" for="searchSpeaker">@Translate("Search")</label> 369 <input type="search" class="form-control" id="searchSpeaker" placeholder="@Translate("Enter speaker name...")"></input> 370 </div> 371 </div> 372 373 <div class="g-col-lg-3 g-col-12"> 374 <label class="fw-bold mb-2" for="Category">@Translate("Category")</label> 375 <select class="form-control filter-session-ref filter-session-trigger speaker-category-dropdown-filter" id="Category" name="Category"> 376 <option value="">@Translate("Choose category")</option> 377 @foreach (var attrCollection in groupedAttributes) 378 { 379 @*<optgroup label="@attrCollection.Title">*@ 380 foreach (var attr in attrCollection.Items) 381 { 382 var selectedAttr = attr.attributeId == categoryParameter ? "selected" : ""; 383 <option value="@attr.attributeId" @selectedAttr>@attr.attributeName</option> 384 } 385 @*</optgroup>*@ 386 } 387 </select> 388 </div> 389 390 391 <div class="g-col-lg-3 g-col-12 d-flex justify-content-start align-items-end"> 392 <a class="btn btn-link p-0 clear-all-speaker-filters" data-params-to-remove="Category">@Translate("Clear all")</a> 393 </div> 394 </div> 395 } 396 397 398 if (speakers.Any()) 399 { 400 speakers = !string.IsNullOrEmpty(categoryId) ? speakers.Where(speaker => speaker.categories.Any(i => i.categoryItems.Any(cat => cat.id.ToString().Equals(categoryId)))).ToList() : speakers; 401 int summaryItemsCount = Model.Item.GetInt32("SummaryItemsCount"); 402 403 summaryItemsCount = summaryItemsCount > speakers.Count() ? speakers.Count() : summaryItemsCount; 404 int displayCount = showSummary ? summaryItemsCount : speakers.Count(); 405 406 407 if (showSummary) 408 { 409 410 string eyebrow = Model.Item.GetString("Eyebrow", string.Empty).Replace(System.Environment.NewLine, "<br>"); 411 string eyebrowHeadingLevel = Model.Item.GetString("EyebrowHeadingLevel", "h3"); 412 string eyebrowFontSize = Model.Item.GetRawValueString("EyebrowFontSize", "h5"); 413 string eyebrowColor = Model.Item.GetString("EyebrowColor", "text-inherit"); 414 string eyebrowTextOpacity = Model.Item.GetString("EyebrowTextOpacity", "opacity-100"); 415 string eyebrowCssClass = Model.Item.GetString("EyebrowCssClass", string.Empty); 416 string eyebrowSpacingBottomDesktop = Model.Item.GetRawValueString("EyebrowSpacingBottomDesktop", "default"); 417 eyebrowSpacingBottomDesktop = eyebrowSpacingBottomDesktop != "default" ? eyebrowSpacingBottomDesktop : string.Empty; 418 string eyebrowSpacingBottomMobile = Model.Item.GetRawValueString("EyebrowSpacingBottomMobile", "default"); 419 eyebrowSpacingBottomMobile = eyebrowSpacingBottomMobile != "default" ? eyebrowSpacingBottomMobile : string.Empty; 420 421 string title = Model.Item.GetString("Title", string.Empty).Replace(System.Environment.NewLine, "<br>"); 422 string titleHeadingLevel = Model.Item.GetString("TitleHeadingLevel", "h2"); 423 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h2"); 424 string titleColor = Model.Item.GetString("TitleColor", "text-inherit"); 425 string titleTextOpacity = Model.Item.GetString("TitleTextOpacity", "opacity-100"); 426 string titleCssClass = Model.Item.GetString("TitleCssClass", string.Empty); 427 string titleSpacingBottomDesktop = Model.Item.GetRawValueString("TitleSpacingBottomDesktop", "default"); 428 titleSpacingBottomDesktop = titleSpacingBottomDesktop != "default" ? titleSpacingBottomDesktop : string.Empty; 429 string titleSpacingBottomMobile = Model.Item.GetRawValueString("TitleSpacingBottomMobile", "default"); 430 titleSpacingBottomMobile = titleSpacingBottomMobile != "default" ? titleSpacingBottomMobile : string.Empty; 431 432 string subtitle = Model.Item.GetString("Subtitle", string.Empty).Replace(System.Environment.NewLine, "<br>"); 433 string subtitleHeadingLevel = Model.Item.GetString("SubtitleHeadingLevel", "p"); 434 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 435 string subtitleColor = Model.Item.GetString("SubtitleColor", "text-inherit"); 436 string subtitleTextOpacity = Model.Item.GetString("SubtitleTextOpacity", "opacity-100"); 437 string subtitleCssClass = Model.Item.GetString("SubtitleCssClass", string.Empty); 438 string subtitleSpacingBottomDesktop = Model.Item.GetRawValueString("SubtitleSpacingBottomDesktop", "default"); 439 subtitleSpacingBottomDesktop = subtitleSpacingBottomDesktop != "default" ? subtitleSpacingBottomDesktop : string.Empty; 440 string subtitleSpacingBottomMobile = Model.Item.GetRawValueString("SubtitleSpacingBottomMobile", "default"); 441 subtitleSpacingBottomMobile = subtitleSpacingBottomMobile != "default" ? subtitleSpacingBottomMobile : string.Empty; 442 443 444 //Button 1 445 var button1Link = Model.Item.GetLink("Button1Link"); 446 var button1Label = Model.Item.GetString("Button1Label", string.Empty); 447 var button1Icon = Model.Item.GetRawValueString("Button1Icon"); 448 var button1IconPosition = Model.Item.GetRawValueString("Button1IconPosition", "right"); 449 var button1Style = Model.Item.GetRawValueString("Button1Style", "btn-primary"); 450 451 //Button 2 452 var button2Link = Model.Item.GetLink("Button2Link"); 453 var button2Label = Model.Item.GetString("Button2Label", string.Empty); 454 var button2Icon = Model.Item.GetRawValueString("Button2Icon"); 455 var button2IconPosition = Model.Item.GetRawValueString("Button2IconPosition", "right"); 456 var button2Style = Model.Item.GetRawValueString("Button2Style", "btn-primary"); 457 458 string contentAlignment = "align-items-center justify-content-center"; 459 string contentTextAlignment = "text-start"; 460 461 462 var count = 0; 463 speakers = speakers.Where((speaker, index) => index < displayCount).ToList(); 464 465 var summarySpeakers = speakers.Select((speaker, index) => new {speaker, index}) 466 .GroupBy(g => g.index <= 5, 467 (key, g) => new { Title = key, Items = g.ToList() }); 468 string sliderCss = isSlider ? "swiffy-slider slider-nav-visible slider-nav-round" : ""; 469 string sliderListCss = isSlider ? "slider-container" : "container"; 470 471 <div class="@gridCss"> 472 <div id="Slider_@Model.ID" class="@sliderCss speaker-wall-preview"> 473 <div class="g-col-12 w-100 d-flex align-items-end justify-content-between gap-3 flex-wrap mb-4"> 474 <div> 475 @if (!string.IsNullOrEmpty(eyebrow)) 476 { 477 @RenderContent(eyebrow, eyebrowHeadingLevel, eyebrowFontSize, eyebrowColor, eyebrowTextOpacity, eyebrowSpacingBottomDesktop, eyebrowSpacingBottomMobile, eyebrowCssClass) 478 } 479 480 @if (!string.IsNullOrEmpty(title)) 481 { 482 @RenderContent(title, titleHeadingLevel, titleFontSize, titleColor, titleTextOpacity, titleSpacingBottomDesktop, titleSpacingBottomMobile, titleCssClass) 483 } 484 485 @if (!string.IsNullOrEmpty(subtitle)) 486 { 487 @RenderContent(subtitle, subtitleHeadingLevel, subtitleFontSize, subtitleColor, subtitleTextOpacity, subtitleSpacingBottomDesktop, subtitleSpacingBottomMobile, subtitleCssClass) 488 } 489 </div> 490 <div class="d-flex gap-3 align-items-stretch"> 491 <div> 492 @if (button1Link is object || button2Link is object) 493 { 494 if (contentTextAlignment == "text-start") 495 { 496 contentAlignment = "justify-content-start"; 497 } 498 if (contentTextAlignment == "text-center") 499 { 500 contentAlignment = "justify-content-center"; 501 } 502 if (contentTextAlignment == "text-end") 503 { 504 contentAlignment = "justify-content-end"; 505 } 506 507 <div class="d-flex flex-wrap @(contentAlignment) gap-3"> 508 @if (button1Link is object && !string.IsNullOrEmpty(button1Label)) 509 { 510 button1Style = button1Style + " rounded-7 btn-sm"; 511 @RenderButton(button1Link, button1Label, button1Style, button1Icon, button1IconPosition) 512 } 513 514 @if (button2Link is object && !string.IsNullOrEmpty(button1Label)) 515 { 516 @RenderButton(button2Link, button2Label, button2Style, button2Icon, button2IconPosition) 517 } 518 </div> 519 } 520 </div> 521 <div class="d-flex"> 522 <button type="button" title="@Translate("Previous slide")" class="btn btn-primary slider-nav position-relative p-lg-3 rounded-7-start bg-black text-white" style="z-index:1;max-height: 2.75em;min-height: 2.75em"> 523 <span class="icon-auto"> 524 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg> 525 </span> 526 <span class="visually-hidden">@Translate("Previous slide")</span> 527 </button> 528 <button type="button" title="@Translate("Next slide")" class="btn btn-primary slider-nav slider-nav-next position-relative p-lg-3 rounded-7-end bg-black text-white" style="z-index:1;max-height: 2.75em;min-height: 2.75em"> 529 <span class="icon-auto"> 530 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg> 531 </span> 532 <span class="visually-hidden">@Translate("Next slide")</span> 533 </button> 534 </div> 535 </div> 536 </div> 537 538 539 <ul class="@sliderListCss"> 540 541 @foreach (var _i in summarySpeakers) 542 { 543 <li class="grid speaker-slider"> 544 @foreach (var _item in _i.Items.Take(6)) 545 { 546 count++; 547 string viewSpeakerInfoTranslate = Translate("View") + " " + _item.speaker.fullName + " " + Translate("info"); 548 string speakerName = _item.speaker.fullName != null ? _item.speaker.fullName.ToString() : ""; 549 string speakerBio = _item.speaker.bio != null ? _item.speaker.bio.ToString() : ""; 550 string speakerTagLine = _item.speaker.tagLine != null ? _item.speaker.tagLine.ToString() : ""; 551 string speakerProfilePicture = _item.speaker.profilePicture != null ? _item.speaker.profilePicture.ToString() : ""; 552 var sessionsTranslate = _item.speaker.sessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 553 var speakerTypeList = _item.speaker.categories.Where(cat => cat.name == "SpeakerType") ?? null; 554 555 <div class="speaker h-100 grid grid-12 gap-lg-4 @theme gap-2 position-relative rounded-7"> 556 <div class="h-100 p-4 g-col-md-6 g-col-12 order-last order-md-first d-flex flex-column gap-1 max-h-15-em"> 557 <a href="#" class="btn btn-link p-0 text-decoration-none" title="@viewSpeakerInfoTranslate" onclick="event.preventDefault(); new bootstrap.Modal(document.getElementById('SpeakerModal_@(count - 1)')).show()"> 558 <h5 class="text-start">@makeStringReadable(speakerName)</h5> 559 </a> 560 <p class="fs-7 m-0">@speakerTagLine</p> 561 @if (speakerTypeList != null) 562 { 563 <div class="d-flex gap-2 mt-2"> 564 @foreach (var cat in speakerTypeList) 565 { 566 foreach (var c in cat.categoryItems) 567 { 568 string badgePath = "/Files/Images/"; 569 570 if (c.name.Equals("Microsoft")) 571 { 572 badgePath += "microsoftIconBadge.png"; 573 } 574 else if (c.name.Equals("Sponsor")) 575 { 576 badgePath += "sponsorIconBadge.png"; 577 } 578 else if (c.name.Equals("MVP")) 579 { 580 badgePath += "mvpIconBadge.png"; 581 } 582 else if (c.name.Equals("Directions")) 583 { 584 badgePath += "directionsIconBadge.png"; 585 } 586 else 587 { 588 badgePath = badgePath; 589 } 590 591 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 592 } 593 } 594 </div> 595 } 596 </div> 597 <div class="h-100 g-col-md-6 g-col-12 overflow-hidden rounded-7"> 598 <a class="btn btn-link p-0" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@(count - 1)')).show()"> 599 <img src="@speakerProfilePicture" class="w-100 img-fluid rounded-7"></img> 600 </a> 601 </div> 602 </div> 603 } 604 </li> 605 } 606 </ul> 607 608 @for (int x = 0; x < displayCount; x++) 609 { 610 string viewSpeakerInfoTranslate = Translate("View") + " " + speakers[x].fullName + " " + Translate("info"); 611 string speakerName = speakers[x].fullName != null ? speakers[x].fullName.ToString() : ""; 612 string speakerBio = speakers[x].bio != null ? speakers[x].bio.ToString() : ""; 613 string speakerTagLine = speakers[x].tagLine != null ? speakers[x].tagLine.ToString() : ""; 614 string speakerProfilePicture = speakers[x].profilePicture != null ? speakers[x].profilePicture.ToString() : ""; 615 string speakerCategories = speakers[x].categoryItems != null ? String.Join(",", speakers[x].categoryItems) : ""; 616 var sessionsTranslate = speakers[x].sessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 617 var speakerTypeList = speakers[x].categories.Where(cat => cat.name == "SpeakerType") ?? null; 618 619 <div class="modal fade modal-xl" id="SpeakerModal_@x"> 620 <div class="modal-dialog"> 621 <div class="modal-content @theme rounded-7"> 622 <div class="modal-body p-0" id="SpeakerModalBodyContainer_@x"> 623 <div class="close-container position-absolute p-3 end-0 m-3 bg-white rounded-7 z-index-9"> 624 <button type="button" class="btn-close bg-dark z-index-9" data-bs-dismiss="modal" aria-label="Close"></button> 625 </div> 626 <div class="grid @theme gap-0 rounded-7"> 627 <div class="h-100 g-col-lg-7 g-col-12 order-last order-md-first"> 628 <div class="h-100 p-4 overflow-auto max-h-30-em"> 629 <div> 630 <h5>@makeStringReadable(speakerName)</h5> 631 <p>@speakerTagLine</p> 632 </div> 633 <div class="d-flex flex-column gap-3 justify-content-between overflow-auto max-h-15-em"> 634 <p class="m-0">@makeStringReadable(speakerBio)</p> 635 </div> 636 <div class="mt-4 d-grid"> 637 <p class="m-0 fw-bold">@sessionsTranslate</p> 638 @foreach (var session in speakers[x].sessions) 639 { 640 if (!string.IsNullOrEmpty(sessionDetailsPage)) 641 { 642 var sessionLink = sessionDetailsPage.IndexOf("?") > 0 ? sessionDetailsPage + "&session=" + session.id : sessionDetailsPage + "?session=" + session.id; 643 <a class="btn btn-link text-start p-0 mb-2" title="@makeStringReadable(session.name)" href="@sessionLink"> 644 @makeStringReadable(session.name) 645 </a> 646 } 647 else 648 { 649 <p class="mb-2">@makeStringReadable(session.name)</p> 650 } 651 } 652 </div> 653 @if (speakerTypeList != null) 654 { 655 <div class="d-flex gap-2"> 656 @foreach (var cat in speakerTypeList) 657 { 658 foreach (var c in cat.categoryItems) 659 { 660 string badgePath = "/Files/Images/"; 661 662 if (c.name.Equals("Microsoft")) 663 { 664 badgePath += "microsoftIconBadge.png"; 665 } 666 else if (c.name.Equals("Sponsor")) 667 { 668 badgePath += "sponsorIconBadge.png"; 669 } 670 else if (c.name.Equals("MVP")) 671 { 672 badgePath += "mvpIconBadge.png"; 673 } 674 else if (c.name.Equals("Directions")) 675 { 676 badgePath += "directionsIconBadge.png"; 677 } 678 else 679 { 680 badgePath = badgePath; 681 } 682 683 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 684 } 685 } 686 </div> 687 } 688 </div> 689 </div> 690 <div class="h-100 g-col-lg-5 g-col-12"> 691 <img src="@speakerProfilePicture" class="h-100 w-100 img-fluid rounded-7"></img> 692 </div> 693 </div> 694 </div> 695 </div> 696 </div> 697 </div> 698 } 699 </div> 700 </div> 701 } 702 else 703 { 704 var level1Speakers = speakers.Where(s => s.displayPriority == 1).ToList(); 705 var level2Speakers = speakers.Where(s => s.displayPriority == 2); 706 var level3Speakers = speakers.Where(s => s.displayPriority > 2); 707 708 if (categoryParameter != 0) 709 { 710 level1Speakers = level1Speakers.Where(speaker => speaker.categories.Any(i => i.categoryItems.Any(cat => cat.id.Equals(categoryParameter)))).ToList(); 711 level2Speakers = level2Speakers.Where(speaker => speaker.categories.Any(i => i.categoryItems.Any(cat => cat.id.Equals(categoryParameter)))).ToList(); 712 level3Speakers = level3Speakers.Where(speaker => speaker.categories.Any(i => i.categoryItems.Any(cat => cat.id.Equals(categoryParameter)))).ToList(); 713 } 714 715 string topSpeakersCarouselWidth = Model.Item.GetRawValueString("TopSpeakersCarouselWidth", "w-100"); 716 717 <div class="d-grid mb-3"> 718 @if (level1Speakers.Any() && !hideSpeakerCategory) 719 { 720 <h4 class="mb-4">@Translate("SpeakerWall_DisplayOrder_1")</h4> 721 } 722 723 <div id="Slider_@Model.ID" class="@(topSpeakersCarouselWidth) m-auto d-grid swiffy-slider slider-nav-visible slider-nav-round slider-nav-autoplay slider-nav-autopause speaker-wall-preview"> 724 @RenderSpeakerSlider(level1Speakers, 6) 725 </div> 726 @*foreach(var speaker in level1Speakers) 727 { 728 @RenderSpeaker(speaker) 729 730 } *@ 731 </div> 732 733 if (level1Speakers.Any() && !hideSpeakerCategory) 734 { 735 <hr class="my-5"> 736 } 737 738 <div class="@gridCss mb-3"> 739 @if (level2Speakers.Any() && !hideSpeakerCategory) 740 { 741 <h4 class="mb-4 g-col-12">@Translate("SpeakerWall_DisplayOrder_2")</h4> 742 } 743 744 @foreach (var speaker in level2Speakers) 745 { 746 @RenderSpeaker(speaker) 747 } 748 </div> 749 750 if (level2Speakers.Any() && !hideSpeakerCategory) 751 { 752 <hr class="my-5"> 753 } 754 755 <div class="@gridCss mb-3"> 756 @if (level3Speakers.Any() && !hideSpeakerCategory) 757 { 758 <h4 class="mb-4 g-col-12">@Translate("SpeakerWall_DisplayOrder_3")</h4> 759 } 760 761 @foreach(var speaker in level3Speakers) 762 { 763 @RenderSpeaker(speaker) 764 } 765 </div> 766 } 767 } 768 769 } 770 771 @helper RenderContent(string content, string heading, string fontSize, string color, string opacity, string margin, string marginMobile, string cssClass) 772 { 773 var classes = new List<string> { }; 774 if (!string.IsNullOrEmpty(fontSize)) { classes.Add(fontSize); } 775 if (!string.IsNullOrEmpty(color)) { classes.Add(color); } 776 if (!string.IsNullOrEmpty(opacity)) { classes.Add(opacity); } 777 if (!string.IsNullOrEmpty(margin)) { classes.Add(margin); } 778 if (!string.IsNullOrEmpty(marginMobile)) { classes.Add(marginMobile); } 779 if (!string.IsNullOrEmpty(cssClass)) { classes.Add(cssClass); } 780 781 var tagStart = $"<{heading} class=\"{string.Join(" ", classes)}\">"; 782 var tagEnd = $"</{heading}>"; 783 784 @tagStart 785 @content 786 @tagEnd 787 } 788 789 @helper RenderButton(Dynamicweb.Frontend.LinkViewModel link, string label, string style, string icon, string iconPosition) 790 { 791 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "target=\"_blank\"" : string.Empty; 792 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && link.IsExternal ? "rel=\"noopener\"" : string.Empty; 793 794 <a href="@link.Url" @target @rel class="btn @(style)"> 795 @if (icon is object) 796 { 797 <span class="d-flex align-items-center gap-1 @(iconPosition)"> 798 @label 799 @RenderIcon(icon) 800 </span> 801 } 802 else 803 { 804 @label 805 } 806 </a> 807 } 808 809 @helper RenderIcon(string icon) 810 { 811 if (System.IO.Path.GetExtension(icon).ToLower() == ".svg") 812 { 813 if (!icon.ToLower().Contains("none") && icon != string.Empty) 814 { 815 <span class="icon-auto"> 816 @ReadFile(icon) 817 </span> 818 } 819 } 820 } 821 @helper RenderSpeaker (Speaker speaker) 822 { 823 string iconBadgeWidth = Model.Item.GetString("IconBadgeWidth"); 824 string iconBadgeHeight = Model.Item.GetString("IconBadgeHeight"); 825 826 var columnSize = "grid g-col-xl-4 g-col-lg-6 g-col-md-6 g-col-12"; 827 columnSize = speaker.displayPriority == 1 ? "grid g-col-lg-12 g-col-12" : columnSize; 828 columnSize = speaker.displayPriority == 2 ? "grid g-col-lg-6 g-col-12" : columnSize; 829 830 string viewSpeakerInfoTranslate = Translate("View") + " " + speaker.fullName + " " + Translate("info"); 831 string speakerId = speaker.id; 832 string speakerName = speaker.fullName != null ? speaker.fullName.ToString() : ""; 833 string speakerBio = speaker.bio != null ? speaker.bio.ToString() : ""; 834 string speakerTagLine = speaker.tagLine != null ? speaker.tagLine.ToString() : ""; 835 string speakerProfilePicture = speaker.profilePicture != null ? speaker.profilePicture.ToString() : ""; 836 string speakerCategories = speaker.categoryItems != null ? String.Join(",", speaker.categoryItems) : ""; 837 string tagLineCssClass = "fs-7 m-0";//i == 0 ? string.Empty : "fs-7 m-0"; 838 var sessionsTranslate = speaker.sessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 839 var speakerTypeList = speaker.categories.Where(cat => cat.name == "SpeakerType") ?? null; 840 var speakerDisplayPriority = speaker.displayPriority.ToString(); 841 842 <div class="speaker @columnSize @theme gap-0 position-relative rounded-7 toggle-speaker" data-name="@makeStringReadable(speakerName)"> 843 <div class="h-100 g-col-lg-7 g-col-12 order-last order-lg-first"> 844 <div class="h-100 p-4 d-flex flex-column justify-content-between"> 845 <div class="d-flex flex-column"> 846 <a href="#" class="btn btn-link p-0 text-decoration-none" title="@viewSpeakerInfoTranslate" onclick="event.preventDefault(); new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()"> 847 <h5 class="text-start m-0">@makeStringReadable(speakerName)</h5> 848 </a> 849 <p class="@tagLineCssClass">@speakerTagLine</p> 850 </div> 851 <div class="d-flex flex-column gap-3 justify-content-between max-height-inherit overflow-auto"> 852 @*if (i == 0 && !showSummary) 853 { 854 <p class="m-0">@makeStringReadable(speakerBio)</p> 855 }*@ 856 </div> 857 @if (speakerTypeList != null) 858 { 859 <div class="d-flex gap-2"> 860 @foreach (var cat in speakerTypeList) 861 { 862 foreach (var c in cat.categoryItems) 863 { 864 string badgePath = "/Files/Images/"; 865 866 if (c.name.Equals("Microsoft")) 867 { 868 badgePath += "microsoftIconBadge.png"; 869 } 870 else if (c.name.Equals("Sponsor")) 871 { 872 badgePath += "sponsorIconBadge.png"; 873 } 874 else if (c.name.Equals("MVP")) 875 { 876 badgePath += "mvpIconBadge.png"; 877 } 878 else if (c.name.Equals("Directions")) 879 { 880 badgePath += "directionsIconBadge.png"; 881 } 882 else 883 { 884 badgePath = badgePath; 885 } 886 887 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 888 } 889 } 890 </div> 891 } 892 </div> 893 </div> 894 <div class="h-100 g-col-lg-5 g-col-12 rounded-7"> 895 <a class="btn btn-link p-0 d-flex" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()"> 896 <img src="@speakerProfilePicture" class="w-100 img-fluid rounded-7"></img> 897 </a> 898 </div> 899 <div class="h-100 w-100 position-absolute cursor-pointer d-none"> 900 <a class="btn btn-link stretched-link" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()"></a> 901 </div> 902 </div> 903 904 905 <div class="modal fade modal-xl" id="SpeakerModal_@speakerId"> 906 <div class="modal-dialog"> 907 <div class="modal-content @theme rounded-7"> 908 <div class="modal-body p-0" id="SpeakerModalBodyContainer_@speakerId"> 909 <div class="close-container position-absolute p-3 end-0 m-3 bg-white rounded-7 z-index-9"> 910 <button type="button" class="btn-close bg-dark z-index-9" data-bs-dismiss="modal" aria-label="Close"></button> 911 </div> 912 <div class="grid @theme gap-0 rounded-7"> 913 <div class="h-100 g-col-lg-7 g-col-12 order-last order-md-first"> 914 <div class="h-100 p-4 overflow-auto max-h-30-em"> 915 <div> 916 <h5>@makeStringReadable(speakerName)</h5> 917 <p>@speakerTagLine</p> 918 </div> 919 <div class="d-flex flex-column gap-3 justify-content-between overflow-auto max-h-15-em"> 920 <p class="m-0">@makeStringReadable(speakerBio)</p> 921 </div> 922 @if (speakerTypeList != null) 923 { 924 <div class="d-flex gap-2 mt-4"> 925 @foreach (var cat in speakerTypeList) 926 { 927 foreach (var c in cat.categoryItems) 928 { 929 string badgePath = "/Files/Images/"; 930 931 if (c.name.Equals("Microsoft")) 932 { 933 badgePath += "microsoftIconBadge.png"; 934 } 935 else if (c.name.Equals("Sponsor")) 936 { 937 badgePath += "sponsorIconBadge.png"; 938 } 939 else if (c.name.Equals("MVP")) 940 { 941 badgePath += "mvpIconBadge.png"; 942 } 943 else if (c.name.Equals("Directions")) 944 { 945 badgePath += "directionsIconBadge.png"; 946 } 947 else 948 { 949 badgePath = badgePath; 950 } 951 952 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 953 } 954 } 955 </div> 956 } 957 <div class="mt-4 d-grid"> 958 <p class="m-0 fw-bold">@sessionsTranslate</p> 959 @foreach (var session in speaker.sessions) 960 { 961 if (!string.IsNullOrEmpty(sessionDetailsPage)) 962 { 963 var sessionLink = sessionDetailsPage.IndexOf("?") > 0 ? sessionDetailsPage + "&session=" + session.id : sessionDetailsPage + "?session=" + session.id; 964 <a class="btn btn-link text-start p-0 mb-2" title="@makeStringReadable(session.name)" href="@sessionLink"> 965 @makeStringReadable(session.name) 966 </a> 967 } 968 else 969 { 970 <p class="mb-2">@makeStringReadable(session.name)</p> 971 } 972 } 973 </div> 974 @if (speaker.links.Any()) 975 { 976 <div class="d-flex gap-3 align-items-end"> 977 @foreach (var link in speaker.links) 978 { 979 string icon = "/Files/Templates/Designs/Swift/Assets/icons/"; 980 981 if (link.url.Contains("twitter")) 982 { 983 icon += "twitter.svg"; 984 } 985 else if (link.url.Contains("linkedin")) 986 { 987 icon += "linkedin.svg"; 988 } 989 else 990 { 991 icon += "link.svg"; 992 } 993 994 <a href="@link.url" title="@link.title" target="_blank"> 995 @RenderIcon(icon) 996 </a> 997 } 998 </div> 999 } 1000 </div> 1001 </div> 1002 <div class="h-100 g-col-lg-5 g-col-12"> 1003 <img src="@speakerProfilePicture" class="h-100 w-100 img-fluid rounded-7"></img> 1004 </div> 1005 </div> 1006 </div> 1007 </div> 1008 </div> 1009 </div> 1010 } 1011 1012 @helper RenderSpeakerSlider(List<Speaker> speakers, int pageSize) 1013 { 1014 string iconBadgeWidth = Model.Item.GetString("IconBadgeWidth"); 1015 string iconBadgeHeight = Model.Item.GetString("IconBadgeHeight"); 1016 var summarySpeakers = speakers.Select((speaker, index) => new {speaker, index}) 1017 .GroupBy(g => g.index < 3, 1018 (key, g) => new { Title = key, Items = g.ToList() }); 1019 if(speakers.Any()) 1020 { 1021 <div class="d-flex"> 1022 <button type="button" title="@Translate("Previous slide")" class="btn btn-primary slider-nav position-relative p-lg-3 rounded-7-start bg-black text-white" style="z-index:1;max-height: 2.75em;min-height: 2.75em"> 1023 <span class="icon-auto"> 1024 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg> 1025 </span> 1026 <span class="visually-hidden">@Translate("Previous slide")</span> 1027 </button> 1028 <button type="button" title="@Translate("Next slide")" class="btn btn-primary slider-nav slider-nav-next position-relative p-lg-3 rounded-7-end bg-black text-white" style="z-index:1;max-height: 2.75em;min-height: 2.75em"> 1029 <span class="icon-auto"> 1030 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg> 1031 </span> 1032 <span class="visually-hidden">@Translate("Next slide")</span> 1033 </button> 1034 </div> 1035 1036 <ul class="slider-container"> 1037 @foreach (var _speaker in speakers.Take(pageSize)) 1038 { 1039 string viewSpeakerInfoTranslate = Translate("View") + " " + _speaker.fullName + " " + Translate("info"); 1040 string speakerId = _speaker.id; 1041 string speakerName = _speaker.fullName != null ? _speaker.fullName.ToString() : ""; 1042 string speakerBio = _speaker.bio != null ? _speaker.bio.ToString() : ""; 1043 string speakerTagLine = _speaker.tagLine != null ? _speaker.tagLine.ToString() : ""; 1044 string speakerProfilePicture = _speaker.profilePicture != null ? _speaker.profilePicture.ToString() : ""; 1045 var sessionsTranslate = _speaker.sessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 1046 var speakerTypeList = _speaker.categories.Where(cat => cat.name == "SpeakerType") ?? null; 1047 string bioText = speakerBio.Count() > 700 ? speakerBio.Substring(0, 700) + "..." : speakerBio; 1048 1049 <li class="toggle-speaker" data-name="@makeStringReadable(speakerName)"> 1050 <div class="speaker grid @theme position-relative rounded-7"> 1051 <div class="h-100 p-4 g-col-lg-7 g-col-12 order-last order-lg-first d-flex flex-column gap-1"> 1052 <a href="#" class="btn btn-link p-0 text-decoration-none" title="@viewSpeakerInfoTranslate" onclick="event.preventDefault(); new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()"> 1053 <h5 class="text-start">@makeStringReadable(speakerName)</h5> 1054 </a> 1055 <h5>@speakerTagLine</h5> 1056 <div class="h-100 d-flex flex-column justify-content-between"> 1057 <div class="d-flex flex-column gap-3 justify-content-between overflow-hidden speaker-bio-container"> 1058 <p class="m-0 bio-text fs-lg-7">@makeStringReadable(bioText)</p> 1059 </div> 1060 <div class="d-flex justify-content-between align-items-center"> 1061 @if (speakerTypeList != null) 1062 { 1063 <div class="d-flex gap-2 mt-2"> 1064 @foreach (var cat in speakerTypeList) 1065 { 1066 foreach (var c in cat.categoryItems) 1067 { 1068 string badgePath = "/Files/Images/"; 1069 1070 if (c.name.Equals("Microsoft")) 1071 { 1072 badgePath += "microsoftIconBadge.png"; 1073 } 1074 else if (c.name.Equals("Sponsor")) 1075 { 1076 badgePath += "sponsorIconBadge.png"; 1077 } 1078 else if (c.name.Equals("MVP")) 1079 { 1080 badgePath += "mvpIconBadge.png"; 1081 } 1082 else if (c.name.Equals("Directions")) 1083 { 1084 badgePath += "directionsIconBadge.png"; 1085 } 1086 else 1087 { 1088 badgePath = badgePath; 1089 } 1090 1091 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 1092 } 1093 } 1094 </div> 1095 } 1096 <div class="mt-2"> 1097 <button class="btn btn-primary btn-sm" onclick="event.preventDefault(); new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()">@Translate("Read more")</button> 1098 </div> 1099 </div> 1100 </div> 1101 </div> 1102 <div class="h-100 g-col-lg-5 g-col-12 overflow-hidden rounded-7"> 1103 <a class="btn btn-link p-0 w-100" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@speakerId')).show()"> 1104 <img src="@speakerProfilePicture" class="w-100 img-fluid rounded-7"></img> 1105 </a> 1106 </div> 1107 </div> 1108 </li> 1109 } 1110 </ul> 1111 1112 foreach (var speaker in speakers) 1113 { 1114 string speakerId = speaker.id; 1115 string viewSpeakerInfoTranslate = Translate("View") + " " + speaker.fullName + " " + Translate("info"); 1116 string speakerName = speaker.fullName != null ? speaker.fullName.ToString() : ""; 1117 string speakerBio = speaker.bio != null ? speaker.bio.ToString() : ""; 1118 string speakerTagLine = speaker.tagLine != null ? speaker.tagLine.ToString() : ""; 1119 string speakerProfilePicture = speaker.profilePicture != null ? speaker.profilePicture.ToString() : ""; 1120 string speakerCategories = speaker.categoryItems != null ? String.Join(",", speaker.categoryItems) : ""; 1121 var sessionsTranslate = speaker.sessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 1122 var speakerTypeList = speaker.categories.Where(cat => cat.name == "SpeakerType") ?? null; 1123 1124 <div class="modal fade modal-xl" id="SpeakerModal_@speakerId"> 1125 <div class="modal-dialog"> 1126 <div class="modal-content @theme rounded-7"> 1127 <div class="modal-body p-0" id="SpeakerModalBodyContainer_@speakerId"> 1128 <div class="close-container position-absolute p-3 end-0 m-3 bg-white rounded-7 z-index-9"> 1129 <button type="button" class="btn-close bg-dark z-index-9" data-bs-dismiss="modal" aria-label="Close"></button> 1130 </div> 1131 <div class="grid @theme gap-0 rounded-7"> 1132 <div class="h-100 g-col-lg-7 g-col-12 order-last order-md-first"> 1133 <div class="h-100 p-4 overflow-auto max-h-30-em"> 1134 <div> 1135 <h5>@makeStringReadable(speakerName)</h5> 1136 <p>@speakerTagLine</p> 1137 </div> 1138 <div class="d-flex flex-column gap-3 justify-content-between overflow-auto max-h-15-em"> 1139 <p class="m-0">@makeStringReadable(speakerBio)</p> 1140 </div> 1141 <div class="mt-4 d-grid"> 1142 <p class="m-0 fw-bold">@sessionsTranslate</p> 1143 @foreach (var session in speaker.sessions) 1144 { 1145 if (!string.IsNullOrEmpty(sessionDetailsPage)) 1146 { 1147 var sessionLink = sessionDetailsPage.IndexOf("?") > 0 ? sessionDetailsPage + "&session=" + session.id : sessionDetailsPage + "?session=" + session.id; 1148 <a class="btn btn-link text-start p-0 mb-2" title="@makeStringReadable(session.name)" href="@sessionLink"> 1149 @makeStringReadable(session.name) 1150 </a> 1151 } 1152 else 1153 { 1154 <p class="mb-2">@makeStringReadable(session.name)</p> 1155 } 1156 } 1157 </div> 1158 @if (speakerTypeList != null) 1159 { 1160 <div class="d-flex gap-2"> 1161 @foreach (var cat in speakerTypeList) 1162 { 1163 foreach (var c in cat.categoryItems) 1164 { 1165 string badgePath = "/Files/Images/"; 1166 1167 if (c.name.Equals("Microsoft")) 1168 { 1169 badgePath += "microsoftIconBadge.png"; 1170 } 1171 else if (c.name.Equals("Sponsor")) 1172 { 1173 badgePath += "sponsorIconBadge.png"; 1174 } 1175 else if (c.name.Equals("MVP")) 1176 { 1177 badgePath += "mvpIconBadge.png"; 1178 } 1179 else if (c.name.Equals("Directions")) 1180 { 1181 badgePath += "directionsIconBadge.png"; 1182 } 1183 else 1184 { 1185 badgePath = badgePath; 1186 } 1187 1188 <img height="@iconBadgeHeight" width="@iconBadgeWidth" src="@badgePath" class="rounded-0"></img> 1189 } 1190 } 1191 </div> 1192 } 1193 </div> 1194 </div> 1195 <div class="h-100 g-col-lg-5 g-col-12"> 1196 <img src="@speakerProfilePicture" class="h-100 w-100 img-fluid rounded-7"></img> 1197 </div> 1198 </div> 1199 </div> 1200 </div> 1201 </div> 1202 </div> 1203 } 1204 } 1205 } 1206 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.css" integrity="sha512-ijXMfMV6D0xH0UfHpPnqrwbw9cjd4AbjtWbdfVd204tXEtJtvL3TTNztvqqr9AbLcCiuNTvqHL5c9v2hOjdjpA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> 1207 <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> 1208 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 1209 <link rel="stylesheet" type="text/css" href="/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css"></link>