layout-base.pug 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. include ./_mixins/foot_scripts
  2. doctype html
  3. html(
  4. lang=currentLngCode || 'en'
  5. class=fixedSizeDocument ? 'fixed-size-document' : undefined
  6. )
  7. - metadata = metadata || {}
  8. - let bootstrap5PageStatus = 'enabled' // One of 'disabled' and 'enabled'
  9. - let bootstrap5PageSplitTest = '' // Limits Bootstrap 5 usage on this page to users with an assignment of "enabled" for the specified split test. If left empty and bootstrap5PageStatus is "enabled", the page always uses Bootstrap 5.
  10. - let isWebsiteRedesign = false
  11. - let isApplicationPage = false
  12. - let enableIeeeBranding = true
  13. block entrypointVar
  14. block isApplicationPageVar
  15. block vars
  16. head
  17. include ./_metadata.pug
  18. - const bootstrapVersion = bootstrap5PageStatus !== 'disabled' && (bootstrap5Override || bootstrap5PageSplitTest === '' || splitTestVariants[bootstrap5PageSplitTest] === 'enabled') ? 5 : 3
  19. //- Stylesheet
  20. link(
  21. rel='stylesheet'
  22. href=buildCssPath(getCssThemeModifier(userSettings, brandVariation, enableIeeeBranding), bootstrapVersion)
  23. id='main-stylesheet'
  24. )
  25. block css
  26. each file in entrypointStyles(entrypoint)
  27. link(rel='stylesheet' href=file)
  28. block _headLinks
  29. if typeof suppressRelAlternateLinks == 'undefined'
  30. if settings.i18n.subdomainLang
  31. each subdomainDetails in settings.i18n.subdomainLang
  32. if !subdomainDetails.hide
  33. link(
  34. rel='alternate'
  35. href=subdomainDetails.url + currentUrl
  36. hreflang=subdomainDetails.lngCode
  37. )
  38. if entrypoint !== 'marketing'
  39. link(
  40. rel='preload'
  41. href=buildJsPath(currentLngCode + '-json.js')
  42. as='script'
  43. nonce=scriptNonce
  44. )
  45. //- Scripts
  46. if typeof suppressAnalytics == 'undefined'
  47. include _google_analytics
  48. block meta
  49. meta(name='ol-csrfToken' content=csrfToken)
  50. //- Configure dynamically loaded assets (via webpack) to be downloaded from CDN
  51. //- See: https://webpack.js.org/guides/public-path/#on-the-fly
  52. meta(name='ol-baseAssetPath' content=buildBaseAssetPath())
  53. meta(name='ol-mathJaxPath' content=mathJaxPath)
  54. meta(name='ol-dictionariesRoot' content=dictionariesRoot)
  55. meta(name='ol-usersEmail' content=getUserEmail())
  56. meta(name='ol-ab' data-type='json' content={})
  57. meta(name='ol-user_id' content=getLoggedInUserId())
  58. //- Internationalisation settings
  59. meta(
  60. name='ol-i18n'
  61. data-type='json'
  62. content={
  63. currentLangCode: currentLngCode,
  64. }
  65. )
  66. //- Expose some settings globally to the frontend
  67. meta(name='ol-ExposedSettings' data-type='json' content=ExposedSettings)
  68. meta(
  69. name='ol-splitTestVariants'
  70. data-type='json'
  71. content=splitTestVariants || {}
  72. )
  73. meta(name='ol-splitTestInfo' data-type='json' content=splitTestInfo || {})
  74. if typeof settings.algolia != 'undefined'
  75. meta(
  76. name='ol-algolia'
  77. data-type='json'
  78. content={
  79. appId: settings.algolia.app_id,
  80. apiKey: settings.algolia.read_only_api_key,
  81. indexes: settings.algolia.indexes,
  82. }
  83. )
  84. meta(
  85. name='ol-isManagedAccount'
  86. data-type='boolean'
  87. content=isManagedAccount
  88. )
  89. each restriction in userRestrictions || []
  90. meta(name='ol-cannot-' + restriction data-type='boolean' content)
  91. meta(name='ol-bootstrapVersion' data-type='json' content=bootstrapVersion)
  92. block head-scripts
  93. body(
  94. class={
  95. 'thin-footer': showThinFooter,
  96. 'website-redesign': isWebsiteRedesign === true || websiteRedesignOverride,
  97. 'application-page': isApplicationPage,
  98. }
  99. data-theme='default'
  100. )
  101. if settings.recaptcha && settings.recaptcha.siteKeyV3
  102. script(
  103. type='text/javascript'
  104. nonce=scriptNonce
  105. src='https://www.recaptcha.net/recaptcha/api.js?render=' + settings.recaptcha.siteKeyV3
  106. defer=deferScripts
  107. )
  108. if typeof suppressSkipToContent == 'undefined'
  109. a(class='skip-to-content' href='#main-content') #{translate('skip_to_content')}
  110. block body
  111. if settings.devToolbar.enabled
  112. #dev-toolbar
  113. block foot-scripts
  114. +foot-scripts
  115. include _customer_io
  116. script(type='text/javascript' nonce=scriptNonce).
  117. window.addEventListener('DOMContentLoaded', function () {
  118. //- Look for bundle
  119. var cdnBlocked = typeof Frontend === 'undefined'
  120. //- Prevent loops
  121. var noCdnAlreadyInUrl = window.location.href.indexOf('nocdn=true') != -1
  122. if (cdnBlocked && !noCdnAlreadyInUrl && navigator.userAgent.indexOf('Googlebot') == -1) {
  123. //- Set query param, server will not set CDN url
  124. window.location.search += '&nocdn=true'
  125. }
  126. })