There was a problem with a Velocity script
Page/httpd/prestosports/site-public/WEB-INF/themes/generic/bio-template
ErrorInvocation of method 'include' in class com.prestosports.render.ContentEngineInvoker threw exception java.lang.RuntimeException: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet successfully received from the server was 103 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago. at /httpd/prestosports/site-public/WEB-INF/themes/generic/bio-template[line 9, column 10]
Page source:
1: $website.addCss($website.cdn("/info/photo-gallery.css"))
2: <script src="${website.cdn("/info/klass.min.js")}"></script>
3: <script src="${website.cdn("/info/code.photoswipe.jquery-3.0.5.min.js")}"></script>
4: <script src="${website.cdn("/info/masonry.pkgd.min.js")}"></script>
5: <script src="${website.cdn("/info/imagesloaded.pkgd.min.js")}"></script>
6: <script src="${website.cdn("/info/photogallery/photogallery.js")}"></script>
7: 
8: ## PICK UP OPTIONS
9: $website.include("options")
10: #set ($options = $request.getAttribute("options"))
11: #set ($locale = "en_us")
12: #set ($locale = $options.get("locale"))
13: 
14: ## HACK TO GET STATS URL FROM RENDERER... NEEDS SERVER CHANGE
15: #set ($bioObject = $page.getDataAsObject())
16: #set ($statsURL = $bioObject.statsURL)
17: 
18: #if ($statsURL.length() > 0)
19:   $website.includeAgain("${statsURL}?tmpl=bio-stats-template")
20:   ## various settings to get the variables set
21:   #set ($events = $request.getAttribute("bio_events"))
22:   #set ($seasons = $request.getAttribute("bio_seasons"))
23:   #set ($career = $request.getAttribute("bio_career"))
24:   #set ($labels = $request.getAttribute("bio_labels"))
25:   #set ($briefs = $request.getAttribute("bio_briefs"))
26:   #set ($gamelogs = $request.getAttribute("bio_gamelogs"))
27:   #set ($splits = $request.getAttribute("bio_splits"))
28:   #set ($statPosition = $request.getAttribute("bio_position"))
29:   #set ($positions = $request.getAttribute("bio_positions"))
30:   #set ($playerId = $request.getAttribute("bio_player_id"))
31:   #set ($highlights = $request.getAttribute("bio_highlights"))
32:   #set ($formats = $request.getAttribute("bio_formats"))
33:   #set ($gamelogsCategoriesLabels = $request.getAttribute("bio_gamelogs_labels"))
34:   #set ($briefsCategoriesLabels = $request.getAttribute("bio_briefs_labels"))
35:   #set ($gamesResults = $request.getAttribute("bio_games_results"))
36:   #set ($monthsPlayed = $request.getAttribute("bio_months_played"))
37: #end
38: 
39: #set ($pos = "")
40: #if($attributes.get("position_stat"))
41:   #set ($pos = $attributes.get("position_stat"))
42: #else
43:   #set ($pos = $attributes.get("position"))
44:   #set ($pos = $statPosition)
45:   #set ($posVec = $pos.split("/"))
46:   #set ($pos = $posVec[0])
47: #end
48: #set ($pos = $pos.toLowerCase())
49: #set ($statPos = $positions.get($pos))
50: #set ($paramPos = $request.getParameter("pos"))
51: 
52: #set ($playerId = $attributes.get("playerId"))
53: #set ($stats = $splits.overall)
54: #set ($highlights = $highlights.get($statPos))
55: 
56: #set ($showHighlights = true)
57: #if ($options.get("bio_show_highlights") && $options.get("bio_show_highlights") == false)
58: 	#set ($showHighlights = false)
59: #end
60: 
61: #set ($enhancedLayout = false)
62: #if (($options.get("bio_enhanced_layout") == "yes") || ($request.getParameter("bio_enhanced_layout") == true))
63: 	#set ($enhancedLayout = true)
64: 	$website.addCss($website.cdn("/info/bio-styles-enhanced.css"))
65: #end
66: 
67: #set ($showActionShots = true)
68: #if ($options.get("bio_show_action_shots") && $options.get("bio_show_action_shots") == false)
69: 	#set ($showActionShots = false)
70: #end
71: 
72: #set ($actionShotsLimit = 5)
73: #set ($actionShotsLimit = $tool.math.toInteger($options.get("bio_action_shots_limit")))
74: 
75: #set ($showCareer = $wiki.valid() && $seasons)
76: #if ("yes" == $options.get("stats_show_career") && $seasons)
77:   #set ($showCareer = true)
78: #end
79: 
80: #set ($hasEvents = $events.size() > 0)
81: #set ($hasSynopsis = $synopsis.trim().length() > 0)
82: #set ($htmlStatsURL = "${page.url}-stats")
83: #set ($hasHTMLStats = $website.exists($htmlStatsURL))
84: #set ($bioBriefURL = "${page.url}-brief")
85: #set ($hasBioBrief = $website.exists("$bioBriefURL"))
86: #set ($showRoster = ($page.contentType == "loki/bio" && $page.headlinesFeatured.size() > 0) || ($page.contentType == "loki/bio-network" && $page.sectionPage.children.size() > 1))
87: #if ($options.get("bio_hide_roster") == true)
88:   #set ($showRoster = false)
89: #end
90: 
91: #set ($view = "")
92: #if ($hasSynopsis || $hasBioBrief)
93:   #set ($view = "bio")
94: #elseif ($statsURL.length() > 0)
95:   #set ($view = "profile")
96: #elseif ($hasHTMLStats)
97:   #set ($view = "htmlstats")
98: #elseif ($releases.size() > 0)
99:   #set ($view = "news")
100: #elseif ($playerPhotos.size() > 0)
101:   #set ($view = "photos")
102: #elseif ($playerVideos.size() > 0)
103:   #set ($view = "videos")
104: #end
105: 
106: #if ($options.get("bio_default_view").length() > 0)
107:   #set ($checkView = $options.get("bio_default_view"))
108: #end
109: 
110: #if ($request.getParameter("view"))
111:   #set ($checkView = $request.getParameter("view"))
112: #end
113: 
114: #if ($checkView == "profile" && $statsURL.length() > 0)
115:   #set ($view = "profile")
116: #elseif ($checkView == "bio" && ($hasSynopsis || $hasBioBrief))
117:   #set ($view = "bio")
118: #elseif ($checkView == "gamelog" && $statsURL.length() > 0)
119:   #set ($view = "gamelog")
120: #elseif ($checkView == "career" && $showCareer)
121:   #set ($view = "career")
122: #elseif ($checkView == "splits" && $statsURL.length() > 0)
123:   #set ($view = "splits")
124: #elseif ($checkView == "htmlstats" && $hasHTMLStats)
125:   #set ($view = "htmlstats")
126: #elseif ($checkView == "news" && $releases.size() > 0)
127:   #set ($view = "news")
128: #elseif ($checkView == "photos" && $playerPhotos.size() > 0)
129:   #set ($view = "photos")
130: #elseif ($checkView == "videos" && $playerVideos.size() > 0)
131:     #set ($view = "videos")
132: #end
133: 
134: #macro (printResultAriaLabel $event)
135:     #set ($ariaLabel = "${event.sport} event: ${formatter.formatDate($event.date, 'MMMM d hh:mm a:')}")
136:     #if ($event.neutralSite.length() > 0 || $event.home)
137:     	#set ($ariaLabel = "${ariaLabel} vs.")
138:     #else
139:     	#set ($ariaLabel = "${ariaLabel} at")
140:     #end
141:     #set ($ariaLabel = "${ariaLabel} ${event.opponent.name}:")
142:     #if ($event.neutralSite.length() > 0)
143:     	#set ($ariaLabel = "${ariaLabel} @ ${event.neutralSite}:")
144:     #end
145:     #set ($ariaLabel = "${ariaLabel} Box Score")
146:     aria-label="$ariaLabel"
147: #end
148: 
149: #macro (printGrid $items $type)
150: <div class="news-layout grid">
151:     <div class="stories">
152:         <ul>
153:         #foreach ($item in $items)
154:             #if ($item.title.length() > 0)
155: 
156:                 <li class="story ${type}">
157:                 	<div class="clearfix">
158:                 	<a href="$item.url" class="title-box">
159:                         <span class="thumb">
160:                         #if ($item.thumbnailURL)
161:                         	<img src="$website.cdn("/info/images/spacer.gif")" data-src="${item.thumbnailURL}?max_width=300" alt="" class="lazyload" />
162: 						#elseif ($item.contentType == "loki/youtube")
163: 							<img src="$website.cdn("/info/images/spacer.gif")" data-src="http://img.youtube.com/vi/${item.dataAsString}/0.jpg" alt="" class="lazyload" />
164:                         #else
165:                         	<img src="$website.cdn("/info/images/spacer.gif")" data-src="/images/setup/thumbnail_default.jpg?max_width=300" alt="" class="lazyload" />
166:                         #end
167:                         </span>
168:                 		<span class="title">$item.title</span>
169:                 	</a>
170:                 	</div>
171:                 </li>
172:             #end
173:         #end ## foreach
174:         </ul>
175:     </div>
176: </div>
177: #end ## ends macro
178: 
179: #macro (gamelogData $p)
180: 
181: #set ($p = $positions.get($p))
182: #set ($gamelogs = $gamelogs.get($p))
183: 
184: #if ($hasEvents)
185: <div class="stats-box full clearfix">
186: <div class="scrollable">
187: <div>
188: <table>
189:   <tr class="thead">
190:     <th class="text">Date</th>
191:     <th class="pinned-col text">Opponent</th>
192:     <th>Score</th>
193:     #foreach ($gamelog in $gamelogs)
194:       <th>$gamelog</th>
195:     #end
196:   </tr>
197: #foreach ($event in $events)
198:   <tr>
199:     <td class="text">$formatter.formatDate($event.event.date, "MMM d")</td>
200:     <td class="pinned-col text">
201:       #if ($event.event.neutralSite.length() > 0) vs. #elseif (!$event.event.home) at #end
202:       $event.event.opponent.name
203:     </td>
204:     <td>
205:     #if ($event.event.statusCode >= 0)
206:       #if ($event.event.eventId.length() > 0 && $event.stats.size() > 0)
207:           <a #printResultAriaLabel($event.event) href="../boxscores/${formatter.formatBoxScoreLink($event.event)}">${event.event.APResult}</a>
208:       #else
209:       ${event.event.APResult}
210:       #end
211:     #else &nbsp; #end
212:     </td>
213:     #foreach ($gamelog in $gamelogs.keySet())
214:       #set ($value = "-")
215:       #set ($value = $formatter.formatNumber($event.stats.get($gamelog), $formats.get($gamelog)))
216:       <td>$value</td>
217:     #end
218:   </tr>
219: #end
220: </table>
221: </div>
222: </div> ## scrollable
223: </div> ## stats-box
224: #end
225: 
226: #end ## macro gamelogData
227: 
228: #macro (split $statPosBriefs $label $stats)
229:   <tr>
230:     <td class="pinned-col text">${label}</td>
231: 
232:     #if($rosterTransactions && $view == "career")
233:         #set($keys =  $stats.names())
234:         #set($array = $keys.toString().replace('"','').split(","))
235:         #foreach ($brief in $statPosBriefs.keySet())
236:             #set ($value = "-")
237:             #if($array.contains($brief))
238:                 #set ($value = $!formatter.formatNumber($tool.math.toDouble($stats.get($brief)), $formats.get($brief)))
239:              #end
240:             <td>#if ($value.length() > 0) $value #else - #end</td>
241:         #end
242:     #else
243:         #foreach ($brief in $statPosBriefs.keySet())
244:           #set ($value = "-")
245:           #set ($value = $!formatter.formatNumber($stats.get($brief), $formats.get($brief)))
246:           <td>#if ($value.length() > 0) $value #else - #end</td>
247:         #end
248:     #end
249:   </tr>
250: #end
251: 
252: #macro (careerData $p)
253: #set ($p = $positions.get($p))
254: #set ($statPosBriefs = $briefs.get($p))
255: 
256: <div class="stats-box full clearfix">
257: <div class="scrollable">
258: <div>
259: <table>
260: <tr class="thead">
261:   <th class="pinned-col">&nbsp;</th>
262:   #foreach ($brief in $statPosBriefs)
263:     <th>$brief</th>
264:   #end
265: </tr>
266: 
267: #if($rosterTransactions)
268:     #set ($seasonLength = $career.seasons.length())
269:     #foreach ($index in [0..$tool.math.sub($seasonLength, 1)])
270:         #set($season = $career.seasons[$index])
271:         #if($season.seasonStatsURL != "null")
272:           #set ($label = "<a href='${season.seasonStatsURL}?view=profile'>$season.seasonName.replaceAll('^[^0-9-]*','') - $season.team.teamName</a>")
273:         #else
274:           #set ($label = "$season.seasonName.replaceAll('^[^0-9-]*','') - $season.team.teamName ")
275:         #end
276:         #split($statPosBriefs, $label, $season.player.stats)
277:     #end
278:     #split($statPosBriefs, "Total", $career.totals)
279: #else
280:     #set ($careerTotals = $request.getAttribute("careerTotals"))
281:     #set ($careerMap = $request.getAttribute("careerMap"))
282: 
283:     #foreach ($season in $seasons)
284:       ## Check if we did not get stats for this season
285:       #if ($careerMap.get($season.seasonName))
286:         #set ($label = "<a href='${season.path}?view=profile'>$season.seasonName</a>")
287:         #split($statPosBriefs, $label, $careerMap[$season.seasonName])
288:       #elseif ($wiki.valid())
289:         <tr>
290:           <td class="text">${season.seasonName}</td>
291:           <td colspan="${statPosBriefs.size()}">We could not find the "players" page in the ${season.seasonName} section.</td>
292:         </tr>
293:       #end
294:     #end
295: 
296:     #split($statPosBriefs, "Total", $request.getAttribute("careerTotals").overall)
297: #end
298: 
299: </table>
300: </div>
301: </div> ## scrollable
302: </div> ## stats-box
303: 
304: #end ## macro careerData
305: 
306: #macro (splitsData $p)
307: 
308: #set ($p = $positions.get($p))
309: #set ($statPosBriefs = $briefs.get($p))
310: #set ($colspan = $tool.math.add($statPosBriefs.size(), 1))
311: 
312: #if ($statPosBriefs.size() > 0)
313: <div class="stats-box full clearfix">
314: <div class="scrollable">
315: <div>
316: <table>
317:   <tr>
318:     <th class="pinned-col">&nbsp;</th>
319:     #foreach ($brief in $statPosBriefs)
320:       <th>$brief</th>
321:     #end
322:   </tr>
323: 
324: #split($statPosBriefs, "Total", $splits.overall)
325: #split($statPosBriefs, "Conference", $splits.conference)
326: #split($statPosBriefs, "Exhibition", $splits.exhibition)
327: 
328: <tr class="empty-row"><td colspan="$colspan"><div class="empty-cell">-</div></td></tr>
329: 
330: #split($statPosBriefs, "Home", $splits.home)
331: #split($statPosBriefs, "Away", $splits.away)
332: #split($statPosBriefs, "Neutral", $splits.neutral)
333: 
334: <tr class="empty-row"><td colspan="$colspan"><div class="empty-cell">-</div></td></tr>
335: 
336: #foreach($gameResult in $gamesResults.entrySet())
337:   #if ($gameResult.key == "wins")
338:     #set ($splitGameResult = $splits.inWins)
339:   #elseif ($gameResult.key == "losses")
340:     #set ($splitGameResult = $splits.inLosses)
341:   #elseif ($gameResult.key == "ties")
342:     #set ($splitGameResult = $splits.inTies)
343:   #end
344: 
345:   #split($statPosBriefs, $gameResult.value, $splitGameResult)
346: #end
347: 
348: <tr class="empty-row"><td colspan="$colspan"><div class="empty-cell">-</div></td></tr>
349: 
350: #if ($monthsPlayed and $monthsPlayed.size() > 0)
351:   #foreach($month in $monthsPlayed)
352:     #if ($month == 'January')
353:       #set ($splitMonth = $splits.january)
354:     #elseif ($month == 'February')
355:       #set ($splitMonth = $splits.february)
356:     #elseif ($month == 'March')
357:       #set($splitMonth = $splits.march)
358:     #elseif ($month == 'April')
359:       #set($splitMonth = $splits.april)
360:     #elseif ($month == 'May')
361:       #set ($splitMonth = $splits.may)
362:     #elseif ($month == 'June')
363:       #set ($splitMonth = $splits.june)
364:     #elseif ($month == 'July')
365:       #set($splitMonth = $splits.july)
366:     #elseif ($month == 'August')
367:       #set ($splitMonth = $splits.august)
368:     #elseif ($month == 'September')
369:       #set($splitMonth = $splits.september)
370:     #elseif ($month == 'October')
371:       #set($splitMonth = $splits.october)
372:     #elseif ($month == 'November')
373:       #set ($splitMonth = $splits.november)
374:     #elseif ($month == 'December')
375:       #set($splitMonth = $splits.december)
376:     #end
377: 
378:     #split($statPosBriefs, $month, $splitMonth)
379:   #end ## foreach
380: #end
381: </table>
382: </div>
383: </div> ## scrollable
384: </div> ## srollable-table
385: #end
386: 
387: #end ## macro splitsData
388: 
389: #macro (printRecentGames)
390: #if ($hasEvents)
391: <table>
392:   <tr class="thead accent-bg"><th colspan="3">Recent Games</th></tr>
393: 
394: #set ($eventEnd = -1)
395: #foreach ($event in $events)
396:   #if ($event.event.result.resolved)
397:     #set ($eventEnd = $velocityCount)
398:   #end
399: #end
400: 
401: #set ($eventStart = $eventEnd - 5)
402: #if ($eventStart < 0) #set ($eventStart = 0) #end
403: 
404: #foreach ($event in $events)
405: #if ($velocityCount >= $eventStart and $velocityCount <= $eventEnd)
406:   <tr>
407:     <td class="text">$formatter.formatDate($event.event.date, "MMM d")</td>
408:     <td class="text">
409:       #if ($event.event.neutralSite.length() > 0) vs.
410:       #elseif (!$event.event.home) at
411:       #else ## nothing for a home game
412:       #end
413:       $event.event.opponent.name
414:     </td>
415:     <td class="text">
416:     #if ($event.event.statusCode >= 0)
417:       #if ($event.event.eventId.length() > 0 && $event.stats.size() > 0)
418:           <a #printResultAriaLabel($event.event) href="../boxscores/${formatter.formatBoxScoreLink($event.event)}">${event.event.APResult}</a>
419:       #else
420:       ${event.event.APResult}
421:       #end
422: 	#end
423: 	</td>
424:   </tr>
425: #end ## if
426: #end
427: </table>
428: #end
429: #end ## macro printRecentGames
430: 
431: #macro (printCategories $briefCategoryLabels $v $ariaLabel)
432: 
433: <div class="tab-container secondary clearfix" data-module="stats/tabs" data-type="secondary">
434: <div class="tab-nav" data-module="jscroll" data-momentum="false">
435: <div>
436: <ul class="clearfix">
437: #foreach($briefCat in $briefCategoryLabels.entrySet())
438:   #set ($briefCatLabel = $briefCat.value)
439:   #set ($briefCatKey = $briefCat.key)
440: 
441:   #if ($locale == "en_gb" && $briefCatLabel == "Defense")
442:     #set ($briefCatLabel = "Defence")
443:   #end
444: 
445:   <li #if ($activePos == $briefCatKey) class="active" #end><a href="${page.url}?view=${v}&pos=${briefCatKey}" role="button" aria-label="${ariaLabel}: ${briefCatLabel}">$briefCatLabel</a></li>
446: #end
447: </ul>
448: </div>
449: </div>
450: <div class="tab-panels">
451: #foreach ($briefCat in $briefCategoryLabels.entrySet())
452:   #set ($class = "tab-panel clearfix")
453:   #if ($briefCat.key == $activePos)
454:     #set ($class = "tab-panel active clearfix")
455:   #end
456:   <div class="$class">
457:     <div class="stats-wrap clearfix">
458:     #if ($v == "splits")
459:       #splitsData($briefCat.key)
460:     #elseif ($v == "career")
461:       #careerData($briefCat.key)
462:     #end
463:     </div>
464:   </div>
465: #end
466: </div>
467: </div> ## tab-container
468: 
469: #end ## macro printCategories
470: 
471: #macro (printHeadshot)
472: #if ($enhancedLayout)
473: 
474:   #if ($headshot.url)
475:     <img src="$headshot.url?max_width=600&max_height=800" alt="$fullName" />
476:   #else
477:     #if ($website.exists("/images/setup/headshot_default.jpg"))
478:       <img src="/images/setup/headshot_default.jpg?max_width=600&max_height=800" alt="$fullName" />
479:     #else
480:       <img src="$website.cdn("/info/images/default_headshot.jpg?max_width=600&max_height=800")" alt="$fullName" />
481:     #end
482:   #end
483: 
484: #else
485: 
486:   #if ($!attributes.get("number").length() > 0)<span class="number">$!attributes.get("number")</span>#end
487: 
488:   #if ($headshot.url)
489:     <img src="$headshot.url?max_width=600&max_height=800" alt="$fullName" />
490:   #else
491:     #if ($website.exists("/images/setup/headshot_default.jpg"))
492:       <img src="/images/setup/headshot_default.jpg?max_width=600&max_height=800" alt="" />
493:     #else
494:       <img src="$website.cdn("/info/images/default_headshot.jpg?max_width=600&max_height=800")" alt="" />
495:     #end
496:   #end
497: 
498: #end ## ## enhancedLayout check
499: #end ## macro printHeadshot
500: 
501: #set ($socialBrands = ["facebook", "twitter", "instagram", "youtube", "twitch", "tiktok"])
502: #macro (buildSocialLink $brand $handle $icons $class)
503:   #if($brand == "facebook")
504:     #set($socialHost = "https://www.facebook.com")
505:   #elseif($brand == "twitter")
506:     #set($socialHost = "https://twitter.com")
507:   #elseif($brand == "instagram")
508:     #set($socialHost = "https://www.instagram.com")
509:   #elseif($brand == "tikTok")
510:     #set($socialHost = "https://www.tiktok.com")
511:   #elseif($brand == "twitch")
512:     #set($socialHost = "https://www.twitch.tv")
513:   #elseif($brand == "youtube")
514:     #set($socialHost = "https://www.youtube.com")
515:   #end
516:   #if($socialHost.length() > 0 )
517:     #set($url = "${socialHost}/${handle}")
518:   #else
519:     #set($url = "")
520:   #end
521:   #set($icons = $Boolean.parseBoolean($icons))
522:   #if($icons == true)
523:   <a href="$url" class="$class" target="_blank"><span aria-label="$brand" class="icon gicon-$brand.toLowerCase()"></span></a>
524:   #else
525:   <a href="$url" class="$class" target="_blank">$handle</a>
526:   #end
527: #end
528: 
529: #macro (printBioInfo)
530: #if ($enhancedLayout)
531: 
532: <h2 class="player-heading">
533:   #if ($!attributes.get("number").length() > 0)<span class="number accent-bg">$!attributes.get("number")</span>#end
534:   <span class="name">$fullName</span>
535:   <span class="social-handle-link inline-block p-0">
536:       <ul class="d-flex align-content-center h-100 gap-2 list-unstyled m-0 p-0 flex-nowrap">
537:         #foreach ($field in $fields)
538:           #if ($socialBrands.contains($field.key.toLowerCase()) && $attributes.get($field.key).length() > 0)
539:             <li class="d-flex flex-column align-content-center justify-content-center w-auto p-0">
540:               #buildSocialLink($field.value.toLowerCase(), $!attributes.get($field.key), true, "btn btn-lg btn-link text-white p-0 fs-1")
541:             </li>
542:           #end
543:         #end
544:       </ul>
545:   </span>
546: </h2>
547: 
548: <ul>
549: #foreach ($i in [1..10])
550:   #set ($stickyKey = "bio_custom${i}_sticky")
551:   #if ($options.get($stickyKey).length() > 0 && $attributes.get("custom${i}").length() > 0)
552:     <li>
553:       <dl>
554:         <dt class="label">$options.get($stickyKey): </dt>
555:         <dd class="value">$!attributes.get("custom${i}")</dd>
556:       </dl>
557:     </li>
558:   #end
559: #end
560: 
561: #foreach ($field in $fields)
562:   #if (!$field.key.startsWith("custom"))
563:     #if ($attributes.get($field.key).length() > 0 && ($field.key != "first_name" && $field.key != "last_name" && $field.key != "number" && $field.key != "full_name"))
564:       #if ($field.key == "phone1" || $field.key == "phone2")
565:         <li>
566:           <dl>
567:             <dt class="label">Phone: </dt>
568:             <dd class="value">$!attributes.get($field.key)</dd>
569:           </dl>
570:         </li>
571:       #elseif ($field.key == "email_address")
572:         #set ($emailAdd = $attributes.get($field.key))
573:         <li>
574:           <dl>
575:             <dt class="label">Email: </dt>
576:             <dd class="value"><a href="mailto:${emailAdd}">$emailAdd</a></dd>
577:           </dl>
578:         </li>
579:       #elseif ($field.key == "weight_class")
580:         <li>
581:           <dl>
582:             <dt class="label">Class: </dt>
583:             <dd class="value">$!attributes.get($field.key)</dd>
584:           </dl>
585:         </li>
586:       #elseif ($socialBrands.contains($field.value.toLowerCase()))
587:         <li>
588:           <dl>
589:             <dt class="label">$field.value: </dt>
590:             <dd class="value">#buildSocialLink($field.value.toLowerCase(), $!attributes.get($field.key), false, "")</dd>
591:           </dl>
592:         </li>
593:       #elseif ($field.key != "position_abbr")
594:         <li>
595:           <dl>
596:             <dt class="label">$field.value: </dt>
597:             <dd class="value">$!attributes.get($field.key)</dd>
598:           </dl>
599:         </li>
600:       #end
601:     #end
602:   #end
603: #end
604: 
605: #foreach ($i in [1..10])
606:   #set ($customKey = "bio_custom${i}")
607:   #if ($options.get($customKey).length() > 0 && $attributes.get("custom${i}"))
608:     <li>
609:       <dl>
610:         <dt class="label">$options.get($customKey): </dt>
611:         <dd class="value">$!attributes.get("custom${i}")</dd>
612:       </dl>
613:     </li>
614:   #end
615: #end
616: </ul>
617: 
618: #else
619: ## default layout
620: 
621: <div class="player-name">
622:   #if ($!attributes.get("number").length() > 0)<span class="number">$!attributes.get("number")</span><span class="sep"> - </span>#end
623:   <span class="name">$fullName</span>
624:   <span class="social-handle-link inline-block p-0">
625:       <ul class="d-flex align-content-center h-100 gap-3 list-unstyled m-0">
626:         #foreach ($field in $fields)
627:           #if ($socialBrands.contains($field.key.toLowerCase()) && $attributes.get($field.key).length() > 0)
628:             <li class="d-flex flex-column align-content-center justify-content-center">
629:               #buildSocialLink($field.value.toLowerCase(), $!attributes.get($field.key), true, "btn btn-lg btn-link text-white p-0 fs-1")
630:             </li>
631:           #end
632:         #end
633:       </ul>
634:   </span>
635: </div>
636: 
637: <table role="presentation">
638: #foreach ($i in [1..10])
639:   #set ($stickyKey = "bio_custom${i}_sticky")
640:   #if ($options.get($stickyKey).length() > 0 && $attributes.get("custom${i}").length() > 0)
641:     <tr>
642:       <td class="label">$options.get($stickyKey): </td>
643:       <td class="value">$!attributes.get("custom${i}")</td>
644:     </tr>
645:   #end
646: #end
647: 
648: #foreach ($field in $fields)
649:   #if (!$field.key.startsWith("custom"))
650:     #if ($attributes.get($field.key).length() > 0 && ($field.key != "first_name" && $field.key != "last_name" && $field.key != "number" && $field.key != "full_name"))
651:       #if ($field.key == "phone1" || $field.key == "phone2")
652:         <tr>
653:           <td class="label">Phone: </td>
654:           <td class="value">$!attributes.get($field.key)</td>
655:         </tr>
656:       #elseif ($field.key == "email_address")
657:         #set ($emailAdd = $attributes.get($field.key))
658:         <tr>
659:           <td class="label">Email: </td>
660:           <td class="value"><a href="mailto:${emailAdd}">$emailAdd</a></td>
661:         </tr>
662:       #elseif ($field.key == "weight_class")
663:         <tr>
664:           <td class="label">Class: </td>
665:           <td class="value">$!attributes.get($field.key)</td>
666:         </tr>
667:       #elseif ($socialBrands.contains($field.value.toLowerCase()))
668:         <tr>
669:           <td class="label">$field.value: </td>
670:           <td class="value">#buildSocialLink($field.value.toLowerCase(), $!attributes.get($field.key), false, "")</td>
671:         </tr>
672:       #elseif ($field.key != "position_abbr")
673:         <tr>
674:           <td class="label">$field.value: </td>
675:           <td class="value">$!attributes.get($field.key)</td>
676:         </tr>
677:       #end
678:     #end
679:   #end
680: #end
681: 
682: #foreach ($i in [1..10])
683:   #set ($customKey = "bio_custom${i}")
684:   #if ($options.get($customKey).length() > 0 && $attributes.get("custom${i}"))
685:     <tr>
686:       <td class="label">$options.get($customKey): </td>
687:       <td class="value">$!attributes.get("custom${i}")</td>
688:     </tr>
689:   #end
690: #end
691: </table>
692: #end ## enhancedLayout check
693: #end ## macro printBioInfo
694: 
695: #macro (printActionShots)
696: #if ($showActionShots)
697: 	## BANNERS SLIDER
698:     #set ($slickSettings = {
699: 		"autoplay": true,
700:         "fade": true,
701:         "arrows": false,
702:         "slidesToShow": 1,
703:         "slidesToScroll": 1,
704:         "lazyLoad": "ondemand",
705:         "responsive": "none"
706:     })
707:     #set ($slickSettings = $slickSettings.toString().replace("=", ":"))
708:     <div class="action-shots clearfix" data-player-photo-count="$playerPhotos.size()">
709:         <div class="slider" data-module="slick-slider-init" data-slick-settings="$slickSettings">
710:             #set ($playerPhotos = $tool.sorter.sort($playerPhotos, "lastUpdated:desc"))
711:             #foreach ($photo in $playerPhotos)
712: 				#if ($velocityCount <= $actionShotsLimit)
713:                     #set ($imgAlt = "Action shot for ${page.title} image ${velocityCount}")
714:                     #if ($photo.altText.length() > 0)
715:                         #set ($imgAlt = $photo.altText)
716:                     #elseif( $photo.title.length() > 0 )
717:                         #set ($imgAlt = $photo.title)
718:                     #end
719:             		<div class="image">
720:             			<img data-lazy="$photo.url" alt="$imgAlt" data-lastupdated="$photo.lastUpdated"/>
721:             	    </div>
722: 				#end
723:     	    #end
724: 	    </div>
725:     </div>
726: #end
727: #end ## macro printActionShots
728: 
729: #macro (printHighlights)
730: #if ($highlights && $showHighlights)
731:   <div class="highlights #if ($enhancedLayout) highlights-bio-enhanced #else highlights-bio #end clearfix">
732:     #foreach ($highlight in $highlights.keySet())
733:       #set ($value = "-")
734:       #set ($value = $formatter.formatNumber($stats.get($highlight), $formats.get($highlight)))
735:       <div class="stat clearfix">
736:         <span class="stat-title">$!highlights.get($highlight)</span>
737:         <span class="stat-value">$value</span>
738:       </div>
739:     #end
740:   </div>
741: #end
742: #end ## macro printHighlights
743: #macro (printRoster)
744: #if ($enhancedLayout)
745:   $website.includeAgain("${page.url}?tmpl=roster-switcher-template&id=roster-list")
746: #else
747: #if ($page.contentType == "loki/bio")
748:   #set ($headlinesFeaturedSize = 0)
749:   #foreach ($featuredPage in $page.headlinesFeatured)
750:     #if ($featuredPage.contentType == "loki/headlines")
751:       #set ($headlinesFeaturedSize = $headlinesFeaturedSize + 1)
752:     #end
753:   #end
754:   #if ($headlinesFeaturedSize > 0)
755:       <select class="roster-select-list" aria-label="Select a player to view its full bio from the list of options below.">
756:         <option selected="selected">Related Bios</option>
757:         #foreach ($featuredPage in $page.headlinesFeatured)
758:           #if ($featuredPage.contentType == "loki/headlines")
759:             $website.includeAgain("${featuredPage.url}?tmpl=roster-list-template&current_url=${page.url}")
760: 		  #end
761: 	    #end
762:       </select>
763:   #end
764: #elseif ($page.contentType == "loki/bio-network")
765:   #set ($relatedPlayers = $page.sectionPage.children)
766:   #set ($teamNames = {})
767:   #foreach ($relatedPlayer in $relatedPlayers)
768:     #if ($relatedPlayer.contentType == "loki/bio-network")
769:       #set ($relatedPlayerObj = $relatedPlayer.getDataAsObject().getAttributes())
770:       #set ($teamName = $relatedPlayerObj.get("team"))
771:       #if ($teamName.length() > 0)
772:         #if (!$teamNames.containsValue($teamName))
773:           $!teamNames.put($tool.math.add($teamNames.size(), 1), $teamName)
774:         #end
775:       #end
776:     #end
777:   #end
778: 
779:   <select class="roster-select-list" aria-label="Select a player to view its full bio from the list of options below.">
780:   #foreach ($i in [1..$teamNames.size()])
781:     #if ($teamNames.size() > 1)
782:       <optgroup label="$teamNames.get($i)">
783:     #end
784: 
785:     #foreach ($relatedPlayer in $relatedPlayers)
786:       #if ($relatedPlayer.contentType == "loki/bio-network")
787:         #set ($relatedPlayerObj = $relatedPlayer.getDataAsObject().getAttributes())
788:         #set ($teamName = $relatedPlayerObj.get("team"))
789:         #if ($teamName.length() > 0 && $teamName == $teamNames.get($i))
790:           #set ($playerFirstName = $relatedPlayerObj.get("first_name"))
791:           #set ($playerLastName = $relatedPlayerObj.get("last_name"))
792:           #if ($page.url == $relatedPlayer.url)
793:             <option value="$relatedPlayer.url" selected="selected">${playerFirstName} ${playerLastName}</option>
794:           #else
795:             <option value="$relatedPlayer.url">${playerFirstName} ${playerLastName}</option>
796:           #end
797:         #end
798:       #end
799:     #end
800: 
801:     #if ($teamNames.size() > 1)
802:       </optgroup>
803:     #end
804:   #end
805:   </select>
806: #end
807: #end ## enhancedLayout check
808: #end ## macro printRoster
809: 
810: ################################################## END MACROS  #############################################################
811: 
812: #if ($attributes.get("full_name").length() > 0)
813:   #set ($fullName = $attributes.get("full_name"))
814: #else
815:   #set ($firstName = $!attributes.get("first_name"))
816:   #set ($lastName = $!attributes.get("last_name"))
817:   #set ($fullName = "${firstName} ${lastName}")
818: #end
819: 
820: #set ($actionShots = false)
821: #if ($enhancedLayout && $playerPhotos.size() > 0)
822:   #set ($actionShots = true)
823: #end
824: 
825: #if ($enhancedLayout)
826:   #set ($rootClass = "bio-enhanced")
827:   #if ($actionShots && $showActionShots)
828:   	#set ($rootClass = "${rootClass} action")
829:   #else
830:   	#set ($rootClass = "${rootClass} plain")
831:   #end
832: #else
833:   #set ($rootClass = "bio-wrap")
834: #end
835: 
836: ## FULL ROSTER
837: <div class="${rootClass} #if ($highlights) bio-wrap-has-highlights #end clearfix" data-module="stats/responsive-container">
838: 
839: ## RELATED BIOS
840: #if ($showRoster)
841:   <div class="related-bios clearfix">#printRoster</div>
842: #end
843: 
844: #if ($actionShots)
845:   #printActionShots
846: #end
847: 
848: <div class="head clearfix">
849: <div class="clearfix">
850: 
851: <div class="player-about clearfix">
852:   <div class="player-headshot">#printHeadshot</div>
853:   <div class="player-info">#printBioInfo</div>
854: </div>
855: 
856: #printHighlights
857: 
858: </div>
859: </div> ## head
860: 
861: #if ($view.length() > 0)
862: <div class="body clearfix">
863: 
864: <div class="tab-container primary clearfix" data-module="stats/tabs" data-type="primary">
865: <div class="tab-nav" data-module="jscroll" data-momentum="false">
866:   <div>
867:   <ul class="clearfix">
868:   #if ($hasSynopsis || $hasBioBrief)
869:     <li #if ($view == "bio") class="active" #end><a href="${page.url}?view=bio">Bio</a></li>
870:   #end
871: 
872:   #if ($statsURL.length() > 0)
873:     <li #if ($view == "profile") class="active" #end><a href="${page.url}?view=profile">Player Profile</a></li>
874:     <li #if ($view == "gamelog") class="active" #end><a href="${page.url}?view=gamelog">Game Log</a></li>
875:     #if ($showCareer)
876:       <li #if ($view == "career") class="active" #end><a href="${page.url}?view=career">Career Stats</a></li>
877:     #end
878:     <li #if ($view == "splits") class="active" #end><a href="${page.url}?view=splits">Split Stats</a></li>
879:   #end
880: 
881:   #if ($hasHTMLStats)
882:     <li #if ($view == "htmlstats") class="active" #end><a href="${page.url}?view=htmlstats">HTML Stats</a></li>
883:   #end
884: 
885:   #if ($releases.size() > 0)
886: 	<li #if ($view == "news") class="active" #end><a href="${page.url}?view=news">News</a></li>
887:   #end
888: 
889:   #if ($playerPhotos.size() > 0)
890: 	<li #if ($view == "photos") class="active" #end><a href="${page.url}?view=photos">Photos</a></li>
891:   #end
892: 
893:   #if ($playerVideos.size() > 0)
894:     <li #if ($view == "videos") class="active" #end><a href="${page.url}?view=videos">Videos</a></li>
895:   #end
896:   </ul>
897:   </div>
898: </div> ## tab-nav
899: 
900: <div class="tab-panels clearfix">
901: 
902: ## BIO
903: #if ($hasSynopsis || $hasBioBrief)
904: 
905: #set ($class = "tab-panel clearfix")
906: #if ($view == "bio")
907:   #set ($class = "tab-panel active clearfix")
908: #end
909: <div class="${class}">
910: 
911: <div class="synopsis clearfix">
912: #if ($hasSynopsis)
913:   $synopsis
914: #elseif ($hasBioBrief)
915:   $website.include("$bioBriefURL")
916: #end
917: </div>
918: 
919: </div> ## tab-panel
920: #end
921: ## BIO
922: 
923: ## STATS
924: #if ($statsURL.length() > 0)
925: 
926: ## PROFILE
927: #set ($class = "tab-panel clearfix")
928: #if ($view == "profile")
929:   #set ($class = "tab-panel active clearfix")
930: #end
931: <div class="${class}">
932: <div class="stats-wrap clearfix">
933: 
934: ## LAST SIX GAMES
935: <div class="stats-box half">
936: #printRecentGames()
937: </div>
938: 
939: ## RANKING
940: <div class="stats-box half">
941: #if ($statPos.length() > 0)
942:   $website.include("players?tmpl=stats-bios-rank-template&rank=${playerId}&pos=${statPos}")
943: #end
944: </div>
945: 
946: </div> ## stats-wrap
947: </div> ## tab-content
948: ## PROFILE
949: 
950: ## GAMELOG
951: #set ($class = "tab-panel clearfix")
952: #if ($view == "gamelog")
953:   #set ($class = "tab-panel active clearfix")
954: #end
955: 
956: #set ($activePos = $statPos)
957: #if ($view == "gamelog" && $paramPos.length() > 0)
958:   #if ($positions.get($paramPos).length() > 0)
959:     #set ($activePos = $positions.get($paramPos))
960:   #end
961: #end
962: 
963: <div class="${class}">
964: 
965: #if ($gamelogsCategoriesLabels)
966: <div class="tab-container clearfix secondary" data-module="stats/tabs" data-type="secondary">
967:   <div class="tab-nav" data-module="jscroll" data-momentum="false">
968:     <div>
969:     <ul class="clearfix">
970:     #foreach($gamelogsCatLabel in $gamelogsCategoriesLabels.entrySet())
971:       #set($gamelogsCatLabelVal = $gamelogsCatLabel.value)
972: 
973:       #if ($locale == "en_gb" && $gamelogsCatLabelVal == "Defense")
974:         #set($gamelogsCatLabelVal = "Defence")
975:       #end
976: 
977:       <li #if ($activePos == $gamelogsCatLabel.key) class="active" #end><a href="${page.url}?view=gamelog&pos=${gamelogsCatLabel.key}" role="button" aria-label="Game Log: ${gamelogsCatLabelVal}">$gamelogsCatLabelVal</a></li>
978:     #end
979:     </ul>
980: 	</div>
981:   </div>
982:   <div class="tab-panels">
983:   #foreach($gamelogsCatLabel in $gamelogsCategoriesLabels.entrySet())
984:     #set ($class = "tab-panel clearfix")
985:     #if ($gamelogsCatLabel.key == $activePos)
986:       #set ($class = "tab-panel active clearfix")
987:     #end
988:     <div class="${class}">
989:       <div class="stats-wrap clearfix">#gamelogData($gamelogsCatLabel.key)</div>
990: 	</div>
991:   #end
992:   </div>
993: </div>
994: #else
995:   <div class="stats-wrap clearfix">#gamelogData($pos)</div>
996: #end
997: 
998: </div> ## tab-panel
999: ## GAMELOG
1000: 
1001: 
1002: ## CAREER
1003: #if ($showCareer)
1004: 
1005: #set ($activePos = $statPos)
1006: #if ($view == "career" && $paramPos.length() > 0)
1007:   #if ($positions.get($paramPos).length() > 0)
1008:     #set ($activePos = $positions.get($paramPos))
1009:   #end
1010: #end
1011: 
1012: #set ($class = "tab-panel clearfix")
1013: #if ($view == "career")
1014:   #set ($class = "tab-panel active clearfix")
1015: #end
1016: 
1017: <div class="${class}">
1018: 
1019: #if ($briefsCategoriesLabels)
1020:   #printCategories($briefsCategoriesLabels "career" "Career Stats")
1021: #else
1022:   <div class="stats-wrap clearfix">#careerData($activePos)</div>
1023: #end
1024: 
1025: </div> ## tab-panel
1026: #end
1027: ## CAREER
1028: 
1029: ## SPLITS
1030: #set ($class = "tab-panel clearfix")
1031: #if ($view == "splits")
1032: 	#set ($class = "tab-panel active clearfix")
1033: #end
1034: 
1035: #set ($activePos = $statPos)
1036: #if ($view == "splits" && $paramPos.length() > 0)
1037:   #if ($positions.get($paramPos).length() > 0)
1038:     #set ($activePos = $positions.get($paramPos))
1039:   #end
1040: #end
1041: 
1042: <div class="${class}">
1043: 
1044: #if ($briefsCategoriesLabels)
1045:   #printCategories($briefsCategoriesLabels "splits" "Splits Stats")
1046: #else
1047:   <div class="stats-wrap clearfix">#splitsData($pos)</div>
1048: #end
1049: 
1050: </div> ## tab-panel
1051: ## SPLITS
1052: 
1053: #end
1054: ## STATS
1055: 
1056: ## HTML STATS
1057: #if ($hasHTMLStats)
1058: 
1059: #set ($class = "tab-panel clearfix")
1060: #if ($view == "htmlstats")
1061:   #set ($class = "tab-panel active clearfix")
1062: #end
1063: <div class="${class}">
1064:   <a href="${htmlStatsURL}" class="bio-htmlstats-identifier">Click to view HTML Stats</a>
1065: </div>
1066: 
1067: #end
1068: ## HTML STATS
1069: 
1070: ## NEWS
1071: #if ($releases.size() > 0)
1072: #set ($class = "tab-panel clearfix")
1073: #if ($view == "news")
1074:   #set ($class = "tab-panel active clearfix")
1075: #end
1076: <div class="${class}">
1077: 	#printGrid($releases, "article")
1078: </div> ## tab-content
1079: #end
1080: ## NEWS
1081: 
1082: ## PHOTOS
1083: #if ($playerPhotos.size() > 0)
1084: #set ($class = "tab-panel clearfix")
1085: #if ($view == "photos")
1086:   #set ($class = "tab-panel active clearfix")
1087: #end
1088: <div class="${class}">
1089:     $website.includeAgain("${page.url}?tmpl=bio-photos-template")
1090: </div> ## tab-content
1091: #end
1092: ## PHOTOS
1093: 
1094: ## VIDEOS
1095: #if ($playerVideos.size() > 0)
1096:   #set ($class = "tab-panel clearfix")
1097:   #if ($view == "videos")
1098:     #set ($class = "tab-panel active clearfix")
1099:   #end
1100: <div class="${class}">
1101: 	#printGrid($playerVideos, "video")
1102: </div> ## tab-content
1103: #end
1104: ## VIDEOS
1105: 
1106: </div> ## tab-panels
1107: </div> ## tab-container
1108: </div> ## body
1109: #end
1110: 
1111: $wiki
1112: </div> ## ends bio-wrap
1113: 
1114: ## GLOBAL ADS SERVER
1115: #if ($website.ads.isAdvertisingEnabled('BIOS'))
1116:         $website.includeAgain("global-adserver-slots?adSlot=bios")
1117: #end