7-9 May 2025
Directions ASIA 2025
Directions ASIA is expanding to a 3-day conference in 2025, with an even greater focus on learning and growth. Join us again in Bangkok, where you’ll enjoy exceptional hospitality and a culinary experience like no other, for the latest updates from Microsoft and the ecosystem. Connect with the entire Dynamics community, including resellers, add-on providers, Microsoft, CSPs, MVPs, developers, consultants, sales and marketing professionals and business leaders. Fuel your motivation, inspiration, and success through sharing and collaboration.
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>