first commit

This commit is contained in:
2025-04-24 13:11:28 +08:00
commit ff9c54d5e4
5960 changed files with 834111 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
.fat-footer-base
.fat-footer-base-section.fat-footer-base-meta
.fat-footer-base-item
.fat-footer-base-copyright © #{new Date().getFullYear()} Overleaf
a(href="/legal") #{translate('privacy_and_terms')}
a(href="https://www.digital-science.com/security-certifications/") #{translate('compliance')}
ul.fat-footer-base-item.list-unstyled.fat-footer-base-language
if bootstrapVersion === 5
include language-picker-bootstrap-5
else
include language-picker
.fat-footer-base-section.fat-footer-base-social
.fat-footer-base-item
a.fat-footer-social.x-logo(href="https://x.com/overleaf")
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1227" height="25")
path(d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z")
span.visually-hidden #{translate("app_on_x", {social: "X"})}
a.fat-footer-social.facebook-logo(href="https://www.facebook.com/overleaf.editor")
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 666.66668 666.66717" height="25")
defs
clipPath(id="a" clipPathUnits="userSpaceOnUse")
path(d="M0 700h700V0H0Z")
g(clip-path="url(#a)" transform="matrix(1.33333 0 0 -1.33333 -133.333 800)")
path.background(d="M0 0c0 138.071-111.929 250-250 250S-500 138.071-500 0c0-117.245 80.715-215.622 189.606-242.638v166.242h-51.552V0h51.552v32.919c0 85.092 38.508 124.532 122.048 124.532 15.838 0 43.167-3.105 54.347-6.211V81.986c-5.901.621-16.149.932-28.882.932-40.993 0-56.832-15.528-56.832-55.9V0h81.659l-14.028-76.396h-67.631v-171.773C-95.927-233.218 0-127.818 0 0" fill="#0866ff" transform="translate(600 350)")
path.text(d="m0 0 14.029 76.396H-67.63v27.019c0 40.372 15.838 55.899 56.831 55.899 12.733 0 22.981-.31 28.882-.931v69.253c-11.18 3.106-38.509 6.212-54.347 6.212-83.539 0-122.048-39.441-122.048-124.533V76.396h-51.552V0h51.552v-166.242a250.559 250.559 0 0 1 60.394-7.362c10.254 0 20.358.632 30.288 1.831V0Z" fill="#fff" transform="translate(447.918 273.604)")
span.visually-hidden #{translate("app_on_x", {social: "Facebook"})}
a.fat-footer-social.linkedin-logo(href="https://www.linkedin.com/company/writelatex-limited")
svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72" height="25")
g(fill="none" fill-rule="evenodd")
path.background(fill="#0B66C3" d="M8 72h56a8 8 0 0 0 8-8V8a8 8 0 0 0-8-8H8a8 8 0 0 0-8 8v56a8 8 0 0 0 8 8")
path.text(fill="#FFF" d="M62 62H51.316V43.802c0-4.99-1.896-7.777-5.845-7.777-4.296 0-6.54 2.901-6.54 7.777V62H28.632V27.333H38.93v4.67s3.096-5.729 10.453-5.729c7.353 0 12.617 4.49 12.617 13.777zM16.35 22.794c-3.508 0-6.35-2.864-6.35-6.397C10 12.864 12.842 10 16.35 10c3.507 0 6.347 2.864 6.347 6.397 0 3.533-2.84 6.397-6.348 6.397ZM11.032 62h10.736V27.333H11.033V62")
span.visually-hidden #{translate("app_on_x", {social: "LinkedIn"})}

View File

@@ -0,0 +1 @@
#footer-container

View File

@@ -0,0 +1,84 @@
footer.fat-footer.hidden-print.website-redesign-fat-footer
.fat-footer-container(role="navigation" aria-label=translate('footer_navigation'))
.fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined)
.footer-section#footer-brand
a(href='/', aria-label=settings.appName).footer-brand
.footer-section
h2.footer-section-heading #{translate('About')}
ul.list-unstyled
li
a(href="/about") #{translate('footer_about_us')}
li
a(href="/about/values") #{translate('our_values')}
li
a(href="/about/careers") #{translate('careers')}
li
a(href="/for/press") !{translate('press_and_awards')}
li
a(href="/blog") #{translate('blog')}
.footer-section
h2.footer-section-heading #{translate('learn')}
ul.list-unstyled
li
a(href="/learn/latex/Learn_LaTeX_in_30_minutes") #{translate('latex_in_thirty_minutes')}
li
a(href="/latex/templates") #{translate('templates')}
li
a(href="/events/webinars") #{translate('webinars')}
li
a(href="/learn/latex/Tutorials") #{translate('tutorials')}
li
a(href="/learn/latex/Inserting_Images") #{translate('how_to_insert_images')}
li
a(href="/learn/latex/Tables") #{translate('how_to_create_tables')}
.footer-section
h2.footer-section-heading !{translate('footer_plans_and_pricing')}
ul.list-unstyled
li
a(href="/learn/how-to/Overleaf_premium_features") #{translate('premium_features')}
li
a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')}
li
a(href="/for/enterprises") #{translate('for_business')}
li
a(href="/for/universities") #{translate('for_universities')}
li
a(
data-ol-for-students-link
href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
) #{translate('for_students')}
li
a(href="/for/government") #{translate('for_government')}
.footer-section
h2.footer-section-heading #{translate('get_involved')}
ul.list-unstyled
li
a(href="/for/community/advisors") #{translate('become_an_advisor')}
li
a(href="https://forms.gle/67PSpN1bLnjGCmPQ9") #{translate('let_us_know_what_you_think')}
if user
li
a(href="/beta/participate") #{translate('join_beta_program')}
.footer-section
h2.footer-section-heading #{translate('help')}
ul.list-unstyled
li
a(href="/about/why-latex") #{translate('why_latex')}
li
a(href="/learn") #{translate('Documentation')}
li
a(href="/contact") #{translate('footer_contact_us')}
li
a(href="https://status.overleaf.com/") #{translate('website_status')}
include fat-footer-base

View File

@@ -0,0 +1,84 @@
footer.fat-footer.hidden-print
.fat-footer-container(role="navigation" aria-label=translate('footer_navigation'))
.fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined)
.footer-section#footer-brand
a(href='/', aria-label=settings.appName).footer-brand
.footer-section
h2.footer-section-heading #{translate('About')}
ul.list-unstyled
li
a(href="/about") #{translate('footer_about_us')}
li
a(href="/about/values") #{translate('our_values')}
li
a(href="/about/careers") #{translate('careers')}
li
a(href="/for/press") !{translate('press_and_awards')}
li
a(href="/blog") #{translate('blog')}
.footer-section
h2.footer-section-heading #{translate('learn')}
ul.list-unstyled
li
a(href="/learn/latex/Learn_LaTeX_in_30_minutes") #{translate('latex_in_thirty_minutes')}
li
a(href="/latex/templates") #{translate('templates')}
li
a(href="/events/webinars") #{translate('webinars')}
li
a(href="/learn/latex/Tutorials") #{translate('tutorials')}
li
a(href="/learn/latex/Inserting_Images") #{translate('how_to_insert_images')}
li
a(href="/learn/latex/Tables") #{translate('how_to_create_tables')}
.footer-section
h2.footer-section-heading !{translate('footer_plans_and_pricing')}
ul.list-unstyled
li
a(href="/learn/how-to/Overleaf_premium_features") #{translate('premium_features')}
li
a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')}
li
a(href="/for/enterprises") #{translate('for_enterprise')}
li
a(href="/for/universities") #{translate('for_universities')}
li
a(
data-ol-for-students-link
href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
) #{translate('for_students')}
li
a(href="/for/government") #{translate('for_government')}
.footer-section
h2.footer-section-heading #{translate('get_involved')}
ul.list-unstyled
li
a(href="/for/community/advisors") #{translate('become_an_advisor')}
li
a(href="https://forms.gle/67PSpN1bLnjGCmPQ9") #{translate('let_us_know_what_you_think')}
if user
li
a(href="/beta/participate") #{translate('join_beta_program')}
.footer-section
h2.footer-section-heading #{translate('help')}
ul.list-unstyled
li
a(href="/about/why-latex") #{translate('why_latex')}
li
a(href="/learn") #{translate('Documentation')}
li
a(href="/contact") #{translate('footer_contact_us')}
li
a(href="https://status.overleaf.com/") #{translate('website_status')}
include fat-footer-base

View File

@@ -0,0 +1,25 @@
li.dropdown.dropup.subdued(dropdown).language-picker
button#language-picker-toggle.btn.btn-link.btn-inline-link(
dropdown-toggle,
data-ol-lang-selector-tooltip,
data-bs-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false",
aria-label="Select " + translate('language'),
tooltip=translate('language')
title=translate('language')
)
span.material-symbols(aria-hidden="true") translate
|  
span.language-picker-text #{settings.translatedLanguages[currentLngCode]}
ul.dropdown-menu.dropdown-menu-sm-width(role="menu" aria-labelledby="language-picker-toggle")
li.dropdown-header #{translate("language")}
each subdomainDetails, subdomain in settings.i18n.subdomainLang
if !subdomainDetails.hide
- let isActive = subdomainDetails.lngCode === currentLngCode
li.lng-option
a.menu-indent(href=subdomainDetails.url+currentUrlWithQueryParams, role="menuitem", class=isActive ? 'dropdown-item active' : 'dropdown-item', aria-selected=isActive ? 'true' : 'false')
| #{settings.translatedLanguages[subdomainDetails.lngCode]}
if subdomainDetails.lngCode === currentLngCode
span.material-symbols.dropdown-item-trailing-icon(aria-hidden="true") check

View File

@@ -0,0 +1,24 @@
li.dropdown.dropup.subdued(dropdown).language-picker
a.dropdown-toggle#language-picker-toggle(
href="#",
dropdown-toggle,
data-ol-lang-selector-tooltip,
data-toggle="dropdown",
role="button"
aria-haspopup="true",
aria-expanded="false",
aria-label="Select " + translate('language'),
tooltip=translate('language')
title=translate('language')
)
i.fa.fa-fw.fa-language
|
| #{settings.translatedLanguages[currentLngCode]}
ul.dropdown-menu(role="menu" aria-labelledby="language-picker-toggle")
li.dropdown-header #{translate("language")}
each subdomainDetails, subdomain in settings.i18n.subdomainLang
if !subdomainDetails.hide
li.lng-option
a.menu-indent(href=subdomainDetails.url+currentUrlWithQueryParams role="menuitem")
| #{settings.translatedLanguages[subdomainDetails.lngCode]}

View File

@@ -0,0 +1,18 @@
doctype html
html(lang="en")
- metadata = metadata || {}
block vars
head
if (metadata && metadata.title)
title= metadata.title
if metadata && metadata.viewport
meta(name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes")
link(rel="icon", href="/favicon.ico")
if buildCssPath
link(rel="stylesheet", href=buildCssPath())
block body

View File

@@ -0,0 +1,201 @@
include ../_mixins/navbar
nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
'website-redesign-navbar': isWebsiteRedesign
})
.container-fluid.navbar-container
.navbar-header
if settings.nav.custom_logo
a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
else if (nav.title)
a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
else
a(href='/', aria-label=settings.appName).navbar-brand
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
if (enableUpgradeButton)
a.btn.btn-primary.me-2.d-md-none(
href="/user/subscription/plans"
event-tracking="upgrade-button-click"
event-tracking-mb="true"
event-tracking-label="upgrade"
event-tracking-trigger="click"
event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
) #{translate("upgrade")}
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
if (typeof suppressNavbarRight === "undefined")
button.navbar-toggler.collapsed(
type="button",
data-bs-toggle="collapse",
data-bs-target="#navbar-main-collapse"
aria-controls="navbar-main-collapse"
aria-expanded="false"
aria-label="Toggle " + translate('navigation')
)
i.fa.fa-bars(aria-hidden="true")
.navbar-collapse.collapse#navbar-main-collapse
ul.nav.navbar-nav.navbar-right.ms-auto(role="menubar")
if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
+nav-item.dropdown.subdued
button.dropdown-toggle(
aria-haspopup="true",
aria-expanded="false",
data-bs-toggle="dropdown"
role="menuitem"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "admin", "location": "top-menu"}
)
| Admin
span.caret
+dropdown-menu.dropdown-menu-end
if canDisplayAdminMenu
+dropdown-menu-link-item()(href="/admin") Manage Site
+dropdown-menu-link-item()(href="/admin/user") Manage Users
+dropdown-menu-link-item()(href="/admin/project") Project URL Lookup
if canDisplayAdminRedirect
+dropdown-menu-link-item()(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
+dropdown-menu-link-item()(href="/admin/split-test") Manage Feature Flags
if canDisplaySurveyMenu
+dropdown-menu-link-item()(href="/admin/survey") Manage Surveys
if canDisplayScriptLogMenu
+dropdown-menu-link-item()(href="/admin/script-logs") View Script Logs
// loop over header_extras
each item in nav.header_extras
-
if ((item.only_when_logged_in && getSessionUser())
|| (item.only_when_logged_out && (!getSessionUser()))
|| (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages)
|| (item.only_content_pages && (typeof suppressNavContentLinks === "undefined" || !suppressNavContentLinks))
){
var showNavItem = true
} else {
var showNavItem = false
}
if showNavItem
if item.dropdown
+nav-item.dropdown(class=item.class)
button.dropdown-toggle(
aria-haspopup="true",
aria-expanded="false",
data-bs-toggle="dropdown"
role="menuitem"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": item.trackingKey, "location": "top-menu"}
)
| !{translate(item.text)}
span.caret
+dropdown-menu.dropdown-menu-end
each child in item.dropdown
if child.divider
+dropdown-menu-divider
else if child.isContactUs
+dropdown-menu-link-item()(data-ol-open-contact-form-modal="contact-us" data-bs-target="#contactUsModal" href data-bs-toggle="modal" event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
span
| #{translate("contact_us")}
else
if child.url
+dropdown-menu-link-item()(
href=child.url,
class=child.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={ item: child.trackingKey, location: 'top-menu' }
) !{translate(child.text)}
else
+dropdown-menu-item !{translate(child.text)}
else
+nav-item(class=item.class)
if item.url
+nav-link(
href=item.url,
class=item.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={ item: item.trackingKey, location: 'top-menu' }
) !{translate(item.text)}
else
| !{translate(item.text)}
// logged out
if !getSessionUser()
// register link
if hasFeature('registration-page')
+nav-item.primary
+nav-link(
href="/register"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
) #{translate('sign_up')}
// login link
+nav-item
+nav-link(
href="/login"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
+nav-item
+nav-link(href="/project") #{translate('Projects')}
+nav-item.dropdown
button.dropdown-toggle(
aria-haspopup="true",
aria-expanded="false",
data-bs-toggle="dropdown"
role="menuitem"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "account", "location": "top-menu"}
)
| #{translate('Account')}
span.caret
+dropdown-menu.dropdown-menu-end
+dropdown-menu-item
div.disabled.dropdown-item #{getSessionUser().email}
+dropdown-menu-divider
+dropdown-menu-link-item()(href="/user/settings") #{translate('Account Settings')}
if nav.showSubscriptionLink
+dropdown-menu-link-item()(href="/user/subscription") #{translate('subscription')}
+dropdown-menu-divider
+dropdown-menu-item
//-
The button is outside the form but still belongs to it via the form attribute. The reason to do
this is that if the button is inside the form, screen readers will not count it in the total
number of menu items.
button.btn-link.text-left.dropdown-menu-button.dropdown-item(
role="menuitem",
tabindex="-1"
form="logOutForm"
)
| #{translate('log_out')}
form(
method="POST",
action="/logout",
id="logOutForm"
)
input(name='_csrf', type='hidden', value=csrfToken)

View File

@@ -0,0 +1 @@
#navbar-container

View File

@@ -0,0 +1,197 @@
nav.navbar.navbar-default.navbar-main(class={
'website-redesign-navbar': isWebsiteRedesign
})
.container-fluid
.navbar-header
if (typeof(suppressNavbarRight) == "undefined")
button.navbar-toggle.collapsed(
type="button",
data-toggle="collapse",
data-target="#navbar-main-collapse"
aria-label="Toggle " + translate('navigation')
)
i.fa.fa-bars(aria-hidden="true")
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
if (enableUpgradeButton)
a.btn.btn-primary.pull-right.me-2.visible-xs(
href="/user/subscription/plans"
event-tracking="upgrade-button-click"
event-tracking-mb="true"
event-tracking-label="upgrade"
event-tracking-trigger="click"
event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
) #{translate("upgrade")}
if settings.nav.custom_logo
a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
else if (nav.title)
a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
else
a(href='/', aria-label=settings.appName).navbar-brand
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
if (typeof(suppressNavbarRight) == "undefined")
.navbar-collapse.collapse#navbar-main-collapse
ul.nav.navbar-nav.navbar-right
if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
li.dropdown.subdued
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "admin", "location": "top-menu"}
)
| Admin
span.caret
ul.dropdown-menu
if canDisplayAdminMenu
li
a(href="/admin") Manage Site
li
a(href="/admin/user") Manage Users
li
a(href="/admin/project") Project URL Lookup
if canDisplayAdminRedirect
li
a(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
li
a(href="/admin/split-test") Manage Feature Flags
if canDisplaySurveyMenu
li
a(href="/admin/survey") Manage Surveys
if canDisplayScriptLogMenu
li
a(href="/admin/script-logs") View Script Logs
// loop over header_extras
each item in nav.header_extras
-
if ((item.only_when_logged_in && getSessionUser())
|| (item.only_when_logged_out && (!getSessionUser()))
|| (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages)
|| (item.only_content_pages && (typeof(suppressNavContentLinks) == "undefined" || !suppressNavContentLinks))
){
var showNavItem = true
} else {
var showNavItem = false
}
if showNavItem
if item.dropdown
li.dropdown(class=item.class)
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": item.trackingKey, "location": "top-menu"}
)
| !{translate(item.text)}
span.caret
ul.dropdown-menu
each child in item.dropdown
if child.divider
li.divider
else if child.isContactUs
li
a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
span
| #{translate("contact_us")}
else
li
if child.url
a(
href=child.url,
class=child.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={item: item.trackingKey, location: 'top-menu'}
) !{translate(child.text)}
else
| !{translate(child.text)}
else
li(class=item.class)
if item.url
a(
href=item.url,
class=item.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={ item: item.trackingKey, location: 'top-menu' }
) !{translate(item.text)}
else
| !{translate(item.text)}
// logged out
if !getSessionUser()
// register link
if hasFeature('registration-page')
li.primary
a(
href="/register"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
) #{translate('sign_up')}
// login link
li
a(
href="/login"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
li
a(href="/project") #{translate('Projects')}
li.dropdown
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "account", "location": "top-menu"}
)
| #{translate('Account')}
span.caret
ul.dropdown-menu
li
div.subdued #{getSessionUser().email}
li.divider.hidden-xs.hidden-sm
li
a(href="/user/settings") #{translate('Account Settings')}
if nav.showSubscriptionLink
li
a(href="/user/subscription") #{translate('subscription')}
li.divider.hidden-xs.hidden-sm
li
form(method="POST" action="/logout")
input(name='_csrf', type='hidden', value=csrfToken)
button.btn-link.text-left.dropdown-menu-button #{translate('log_out')}

View File

@@ -0,0 +1,195 @@
nav.navbar.navbar-default.navbar-main.website-redesign-navbar
.container-fluid
.navbar-header
if (typeof(suppressNavbarRight) == "undefined")
button.navbar-toggle.collapsed(
type="button",
data-toggle="collapse",
data-target="#navbar-main-collapse"
aria-label="Toggle " + translate('navigation')
)
i.fa.fa-bars(aria-hidden="true")
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
if (enableUpgradeButton)
a.btn.btn-primary.pull-right.me-2.visible-xs(
href="/user/subscription/plans"
event-tracking="upgrade-button-click"
event-tracking-mb="true"
event-tracking-label="upgrade"
event-tracking-trigger="click"
event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
) #{translate("upgrade")}
if settings.nav.custom_logo
a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
else if (nav.title)
a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
else
a(href='/', aria-label=settings.appName).navbar-brand
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
if (typeof(suppressNavbarRight) == "undefined")
.navbar-collapse.collapse#navbar-main-collapse
ul.nav.navbar-nav.navbar-right
if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
li.dropdown.subdued
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "admin", "location": "top-menu"}
)
| Admin
span.caret
ul.dropdown-menu
if canDisplayAdminMenu
li
a(href="/admin") Manage Site
li
a(href="/admin/user") Manage Users
li
a(href="/admin/project") Project URL Lookup
if canDisplayAdminRedirect
li
a(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
li
a(href="/admin/split-test") Manage Feature Flags
if canDisplaySurveyMenu
li
a(href="/admin/survey") Manage Surveys
if canDisplayScriptLogMenu
li
a(href="/admin/script-logs") View Script Logs
// loop over header_extras
each item in nav.header_extras
-
if ((item.only_when_logged_in && getSessionUser())
|| (item.only_when_logged_out && (!getSessionUser()))
|| (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages)
|| (item.only_content_pages && (typeof(suppressNavContentLinks) == "undefined" || !suppressNavContentLinks))
){
var showNavItem = true
} else {
var showNavItem = false
}
if showNavItem
if item.dropdown
li.dropdown(class=item.class)
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": item.trackingKey, "location": "top-menu"}
)
| !{translate(item.text)}
span.caret
ul.dropdown-menu
each child in item.dropdown
if child.divider
li.divider
else if child.isContactUs
li
a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
span
| #{translate("contact_us")}
else
li
if child.url
a(
href=child.url,
class=child.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={item: child.trackingKey, location: 'top-menu'}
) !{translate(child.text)}
else
| !{translate(child.text)}
else
li(class=item.class)
if item.url
a(
href=item.url,
class=item.class,
event-tracking="menu-click"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={ item: item.trackingKey, location: 'top-menu' }
) !{translate(item.text)}
else
| !{translate(item.text)}
// logged out
if !getSessionUser()
// register link
if hasFeature('registration-page')
li.primary
a(
href="/register"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
) #{translate('sign_up')}
// login link
li.secondary
a(
href="/login"
event-tracking="menu-click"
event-tracking-action="clicked"
event-tracking-trigger="click"
event-tracking-mb="true"
event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
li.secondary
a(href="/project") #{translate('Projects')}
li.secondary.dropdown
a.dropdown-toggle(
href="#",
role="button",
aria-haspopup="true",
aria-expanded="false",
data-toggle="dropdown"
event-tracking="menu-expand"
event-tracking-mb="true"
event-tracking-trigger="click"
event-segmentation={"item": "account", "location": "top-menu"}
)
| #{translate('Account')}
span.caret
ul.dropdown-menu
li
div.subdued #{getSessionUser().email}
li.divider.hidden-xs.hidden-sm
li
a(href="/user/settings") #{translate('Account Settings')}
if nav.showSubscriptionLink
li
a(href="/user/subscription") #{translate('subscription')}
li.divider.hidden-xs.hidden-sm
li
form(method="POST" action="/logout")
input(name='_csrf', type='hidden', value=csrfToken)
button.btn-link.text-left.dropdown-menu-button #{translate('log_out')}

View File

@@ -0,0 +1,38 @@
footer.site-footer
- var showLanguagePicker = Object.keys(settings.i18n.subdomainLang).length > 1
- var hasCustomLeftNav = nav.left_footer && nav.left_footer.length > 0
.site-footer-content.hidden-print
.row
ul.site-footer-items.col-lg-9
if !settings.nav.hide_powered_by
li
//- year of Server Pro release, static
| © 2025
|
a(href='https://www.overleaf.com/for/enterprises') Powered by Overleaf
if showLanguagePicker || hasCustomLeftNav
li
strong.text-muted |
if showLanguagePicker
include language-picker-bootstrap-5
if showLanguagePicker && hasCustomLeftNav
li
strong.text-muted |
each item in nav.left_footer
li
if item.url
a(href=item.url, class=item.class) !{translate(item.text)}
else
| !{item.text}
ul.site-footer-items.col-lg-3.text-end
each item in nav.right_footer
li
if item.url
a(href=item.url, class=item.class, aria-label=item.label) !{item.text}
else
| !{item.text}

View File

@@ -0,0 +1,40 @@
footer.site-footer
- var showLanguagePicker = Object.keys(settings.i18n.subdomainLang).length > 1
- var hasCustomLeftNav = nav.left_footer && nav.left_footer.length > 0
.site-footer-content.hidden-print
.row
ul.col-md-9
if hasFeature('saas')
li © #{new Date().getFullYear()} Overleaf
else if !settings.nav.hide_powered_by
li
//- year of Server Pro release, static
| © 2025
|
a(href='https://www.overleaf.com/for/enterprises') Powered by Overleaf
if showLanguagePicker || hasCustomLeftNav
li
strong.text-muted |
if showLanguagePicker
include language-picker
if showLanguagePicker && hasCustomLeftNav
li
strong.text-muted |
each item in nav.left_footer
li
if item.url
a(href=item.url, class=item.class) !{translate(item.text)}
else
| !{item.text}
ul.col-md-3.text-right
each item in nav.right_footer
li
if item.url
a(href=item.url, class=item.class, aria-label=item.label) !{item.text}
else
| !{item.text}