11import type { Context , Page } from '@/types'
22import type { LinkData } from '@/article-api/transformers/types'
33import { resolvePath } from './resolve-path'
4+ import { renderLiquid } from '@/content-render/liquid/index'
45
56interface PageWithChildren extends Page {
67 children ?: string [ ]
78 category ?: string [ ]
9+ rawTitle : string
10+ rawIntro ?: string
811}
912
1013interface TocItem extends LinkData {
@@ -26,14 +29,11 @@ export async function getAllTocItems(
2629 page : Page ,
2730 context : Context ,
2831 options : {
29- recurse ?: boolean
30- renderIntros ?: boolean
3132 /** Only recurse into children whose resolved path starts with this prefix.
3233 * Prevents cross-product traversal (e.g. /en/rest listing /enterprise-admin). */
3334 basePath ?: string
3435 } = { } ,
3536) : Promise < TocItem [ ] > {
36- const { recurse = true , renderIntros = true } = options
3737 const pageWithChildren = page as PageWithChildren
3838 const languageCode = page . languageCode || 'en'
3939
@@ -70,19 +70,15 @@ export async function getAllTocItems(
7070 )
7171 const href = childPermalink ? childPermalink . href : childHref
7272
73- const title = await childPage . renderTitle ( context , { unwrap : true } )
74-
75- let intro = ''
76- if ( renderIntros && childPage . intro ) {
77- intro = await childPage . renderProp ( 'intro' , context , { textOnly : true } )
78- }
73+ const title = await renderPropFast ( childPage , 'title' , context )
74+ const intro = await renderPropFast ( childPage , 'intro' , context )
7975
8076 const category = childPage . category || [ ]
8177
8278 // Only recurse if the child is within the same product section
8379 const withinSection = href . startsWith ( basePath )
8480 const childTocItems =
85- recurse && withinSection && childPage . children && childPage . children . length > 0
81+ withinSection && childPage . children && childPage . children . length > 0
8682 ? await getAllTocItems ( childPage , context , { ...options , basePath } )
8783 : [ ]
8884
@@ -139,3 +135,38 @@ export function flattenTocItems(
139135 recurse ( tocItems )
140136 return result
141137}
138+
139+ /**
140+ * Check whether a string contains markdown link syntax that would need
141+ * processing by the unified pipeline (e.g. link rewriting, AUTOTITLE).
142+ *
143+ * Use this to short-circuit expensive rendering when the text is
144+ * Liquid-only and contains no markdown that needs transformation.
145+ */
146+ function hasMarkdownLinks ( text : string ) : boolean {
147+ return text . includes ( '[' ) && text . includes ( '](/' )
148+ }
149+
150+ const RAW_PROP_MAP = {
151+ title : 'rawTitle' ,
152+ intro : 'rawIntro' ,
153+ } as const
154+
155+ /**
156+ * Fast-path rendering for page properties. Renders Liquid only, skipping
157+ * the full unified pipeline. Falls back to page.renderProp() when the
158+ * Liquid output contains markdown links that need rewriting.
159+ */
160+ async function renderPropFast (
161+ page : PageWithChildren ,
162+ prop : keyof typeof RAW_PROP_MAP ,
163+ context : Context ,
164+ ) : Promise < string > {
165+ const raw = page [ RAW_PROP_MAP [ prop ] ]
166+ if ( ! raw ) return ''
167+ const rendered = await renderLiquid ( raw , context )
168+ if ( hasMarkdownLinks ( rendered ) ) {
169+ return page . renderProp ( prop , context , { textOnly : true } )
170+ }
171+ return rendered . trim ( )
172+ }
0 commit comments