diff --git a/services/web/app/src/infrastructure/ExpressLocals.mjs b/services/web/app/src/infrastructure/ExpressLocals.mjs
index c9dddc8ec0..99b32ea06e 100644
--- a/services/web/app/src/infrastructure/ExpressLocals.mjs
+++ b/services/web/app/src/infrastructure/ExpressLocals.mjs
@@ -413,7 +413,7 @@ export default async function (webRouter, privateApiRouter, publicApiRouter) {
labsEnabled: Settings.labs && Settings.labs.enable,
wikiEnabled: Settings.overleaf != null || Settings.proxyLearn,
templatesEnabled:
- Settings.overleaf != null || Boolean(Settings.moduleImportSequence.includes('template-gallery')),
+ Settings.overleaf != null || Boolean(Settings.templates),
cioWriteKey: Settings.analytics?.cio?.writeKey,
cioSiteId: Settings.analytics?.cio?.siteId,
linkedInInsightsPartnerId: Settings.analytics?.linkedIn?.partnerId,
diff --git a/services/web/app/src/infrastructure/Features.mjs b/services/web/app/src/infrastructure/Features.mjs
index 193cc3c658..a26705f880 100644
--- a/services/web/app/src/infrastructure/Features.mjs
+++ b/services/web/app/src/infrastructure/Features.mjs
@@ -68,7 +68,7 @@ const Features = {
case 'oauth':
return Boolean(Settings.oauth)
case 'templates-server-pro':
- return Boolean(Settings.moduleImportSequence.includes('template-gallery'))
+ return Boolean(Settings.templates)
case 'affiliations':
case 'analytics':
return Boolean(_.get(Settings, ['apis', 'v1', 'url']))
diff --git a/services/web/app/views/layout/navbar-marketing.pug b/services/web/app/views/layout/navbar-marketing.pug
index fd5d90ec52..42830c6a41 100644
--- a/services/web/app/views/layout/navbar-marketing.pug
+++ b/services/web/app/views/layout/navbar-marketing.pug
@@ -152,15 +152,16 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(
// logged out
if !getSessionUser()
// templates link
- li
- a(
- href="/templates"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'templates', location: 'top-menu' }
- ) #{translate('templates')}
+ if settings.templates
+ li
+ a(
+ href="/templates"
+ event-tracking="menu-click"
+ event-tracking-action="clicked"
+ event-tracking-trigger="click"
+ event-tracking-mb="true"
+ event-segmentation={ page: currentUrl, item: 'templates', location: 'top-menu' }
+ ) #{translate('templates')}
// register link
if hasFeature('registration-page')
diff --git a/services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx b/services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx
index 9ab098ddab..2e5d847d23 100644
--- a/services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx
+++ b/services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx
@@ -5,6 +5,8 @@ export default function GalleryPopularTags() {
const { t } = useTranslation()
const { templateLinks } = getMeta('ol-ExposedSettings') || []
+ if(!templateLinks || templateLinks.length < 2) return null
+
return (
{t('categories')}
diff --git a/services/web/frontend/js/features/template/components/template-root.tsx b/services/web/frontend/js/features/template/components/template-root.tsx
index bbdd3ed92a..ff15511202 100644
--- a/services/web/frontend/js/features/template/components/template-root.tsx
+++ b/services/web/frontend/js/features/template/components/template-root.tsx
@@ -29,7 +29,7 @@ function TemplatePageContent() {
const footerProps = getMeta('ol-footer')
const { template } = useTemplateContext()
const { templateLinks } = getMeta('ol-ExposedSettings') || []
- const categoryName = templateLinks?.find(link => link.url === template.category)?.name || t('all_templates')
+ const categoryName = templateLinks?.find(link => link.url === template.category)?.name
return (
<>
@@ -38,15 +38,15 @@ function TemplatePageContent() {
-
+
arrow_left_alt
- {categoryName}
+ {t('all_templates')}
- {template.category !== '/templates/all' && (
+ {categoryName && template.category !== '/templates/all' && (
<>
/
-
- {t('all_templates')}
+
+ {categoryName}
>
)}
diff --git a/services/web/frontend/js/shared/components/navbar/logged-in-items.tsx b/services/web/frontend/js/shared/components/navbar/logged-in-items.tsx
index 614bc11dd9..be45dabcf1 100644
--- a/services/web/frontend/js/shared/components/navbar/logged-in-items.tsx
+++ b/services/web/frontend/js/shared/components/navbar/logged-in-items.tsx
@@ -4,6 +4,7 @@ import type { NavbarSessionUser } from '@/shared/components/types/navbar'
import NavLinkItem from '@/shared/components/navbar/nav-link-item'
import { AccountMenuItems } from './account-menu-items'
import { useSendProjectListMB } from '@/features/project-list/components/project-list-events'
+import getMeta from '@/utils/meta'
export default function LoggedInItems({
sessionUser,
@@ -14,14 +15,18 @@ export default function LoggedInItems({
}) {
const { t } = useTranslation()
const sendProjectListMB = useSendProjectListMB()
+ const { templatesEnabled } = getMeta('ol-ExposedSettings')
+
return (
<>
{t('projects')}
-
- {t('templates')}
-
+ {templatesEnabled && (
+
+ {t('templates')}
+
+ )}
-
- {t('templates')}
-
+ {templatesEnabled && (
+
+ {t('templates')}
+
+ )}
{showSignUpLink ? (
{
- const envKeyBase = key.toUpperCase().replace(/-/g, "_")
- const name = process.env[`TEMPLATE_${envKeyBase}_NAME`]
- const description = process.env[`TEMPLATE_${envKeyBase}_DESCRIPTION`]
-
- return {
- name: name || key,
- url: `/templates/${key}`,
- description: description || "Templates category"
+if (process.env.OVERLEAF_TEMPLATE_GALLERY === 'true') {
+ TemplateGalleryModule = {
+ router: TemplateGalleryRouter,
}
-})
+
+ Settings.templates = {
+ nonAdminCanManage: boolFromEnv(process.env.OVERLEAF_NON_ADMIN_CAN_PUBLISH_TEMPLATES)
+ }
+
+ const templateKeys = process.env.OVERLEAF_TEMPLATE_CATEGORIES
+ ? process.env.OVERLEAF_TEMPLATE_CATEGORIES + ' all'
+ : 'all'
+
+ Settings.templateLinks = templateKeys.split(/\s+/).map(key => {
+ const envKeyBase = key.toUpperCase().replace(/-/g, "_")
+ const name = process.env[`TEMPLATE_${envKeyBase}_NAME`] || ( key === 'all' ? 'All templates' : key)
+ const description = process.env[`TEMPLATE_${envKeyBase}_DESCRIPTION`] || ''
+
+ return {
+ name,
+ url: `/templates/${key}`,
+ description
+ }
+ })
+}
export default TemplateGalleryModule