@@ -6,7 +6,7 @@ class CoCreateServerSideRender {
66 this . crud = crud ;
77 }
88
9- async HTML ( html , organization_id , url ) {
9+ async HTML ( file ) {
1010 const self = this ;
1111 let ignoreElement = {
1212 INPUT : true ,
@@ -20,8 +20,17 @@ class CoCreateServerSideRender {
2020 let dep = [ ] ;
2121 let dbCache = new Map ( ) ;
2222
23- async function render ( html , lastKey ) {
24- const dom = parse ( html ) ;
23+ async function render ( dom , lastKey ) {
24+ let langLinks = self . createLanguageLinkTags ( file ) ;
25+
26+ // Insert language link tags into <head>
27+ const head = dom . querySelector ( "head" ) ;
28+ if ( head && langLinks ) {
29+ const linksFragment = parse ( `<fragment>${ langLinks } </fragment>` ) ;
30+ for ( const link of linksFragment . childNodes ) {
31+ head . appendChild ( link ) ;
32+ }
33+ }
2534
2635 // Handle elements with [array][key][object]
2736 for ( let el of dom . querySelectorAll ( "[array][key][object]" ) ) {
@@ -32,10 +41,7 @@ class CoCreateServerSideRender {
3241 if ( el . closest ( ".template, [template], template, [render]" ) )
3342 continue ;
3443
35- if (
36- el . hasAttribute ( "render-query" )
37- )
38- continue ;
44+ if ( el . hasAttribute ( "render-query" ) ) continue ;
3945
4046 if ( el . hasAttribute ( "component" ) || el . hasAttribute ( "plugin" ) )
4147 continue ;
@@ -145,11 +151,84 @@ class CoCreateServerSideRender {
145151 return dom ;
146152 }
147153
148- let result = await render ( html , "root" ) ;
154+ let dom = parse ( file . src ) ;
155+ dom = await render ( dom , "root" ) ;
156+ dom = translate ( dom , file ) ;
157+ let langLinkTags = createLanguageLinkTags ( file ) ;
158+ langLinkTags = parse ( langLinkTags ) ;
159+ langLinkTags = await render ( langLinkTags , "root" ) ;
160+
149161 dep = [ ] ;
150162 dbCache . clear ( ) ;
151163 return result . toString ( ) ;
152164 }
165+
166+ createLanguageLinkTags ( file ) {
167+ let xDefault = file . path ;
168+
169+ if ( file . name !== "index.html" ) {
170+ if ( xDefault . endsWith ( "/" ) ) {
171+ xDefault += file . name ;
172+ } else {
173+ xDefault += "/" + file . name ;
174+ }
175+ }
176+ let generatedLinksString = `<link rel="alternate" hreflang="x-default" href="${ xDefault } ">\n` ;
177+
178+ // Step 1: Create a lookup object that maps base language to its path.
179+ // This is done once for efficiency.
180+ const paths = { } ;
181+ for ( const p of file . pathnames ) {
182+ const secondSlashIndex = p . indexOf ( "/" , 1 ) ;
183+ const langKey = p . substring ( 1 , secondSlashIndex ) ; // e.g., 'en', 'es', 'pt'
184+ const restOfPath = p . substring ( secondSlashIndex ) ;
185+ paths [ langKey ] = restOfPath ;
186+ }
187+
188+ // Step 2: Iterate through all supported languages and build the HTML string.
189+ for ( const language of file . languages ) {
190+ // Use the base language to find the correct path in our map
191+ const path = paths [ language ] || paths [ language . split ( "-" ) [ 0 ] ] ;
192+
193+ // If a valid path exists, construct the full link
194+ if ( path ) {
195+ // Construct the full href URL using the full language code from the array
196+ const hrefUrl = `https://${ file . urlObject . hostname } /${ language } ${ path } ` ;
197+
198+ // Append the HTML string. The hreflang and the URL path are now in sync.
199+ generatedLinksString += `<link rel="alternate" hreflang="${ language } " href="${ hrefUrl } ">\n` ;
200+ }
201+ }
202+ return generatedLinksString ;
203+ }
204+
205+ async translate ( dom , file ) {
206+ let langRegion = file . langRegion ;
207+ let lang = file . lang ;
208+ if ( file . translations & ( langRegion || lang ) ) {
209+ for ( let translation of file . translations ) {
210+ let el = dom . querySelectorAll ( translation . selector ) ;
211+ if ( translation . innerHTML ) {
212+ let content =
213+ translation . innerHTML [ langRegion ] ||
214+ translation . innerHTML [ lang ] ;
215+ if ( content ) {
216+ el . innerHTML = content ;
217+ }
218+ }
219+ if ( translation . attributes ) {
220+ for ( let [ key , language ] of Object . entries (
221+ translation . attributes
222+ ) ) {
223+ let value = language [ langRegion ] || language [ lang ] ;
224+ if ( value ) {
225+ el . setAttribute ( key , value ) ;
226+ }
227+ }
228+ }
229+ }
230+ }
231+ }
153232}
154233
155234module . exports = CoCreateServerSideRender ;
0 commit comments