Skip to content

Commit 196b944

Browse files
committed
Merge branch 'dev'
2 parents 84e02f9 + ac0580c commit 196b944

File tree

2 files changed

+86
-22
lines changed

2 files changed

+86
-22
lines changed

package.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@
44
"description": "A simple server-side-render component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
55
"keywords": [
66
"server-side-render",
7-
"cocreate",
8-
"low-code-framework",
9-
"no-code-framework",
10-
"cocreatejs",
11-
"cocreatejs-component",
12-
"cocreate-framework",
13-
"no-code",
147
"low-code",
15-
"collaborative-framework",
168
"realtime",
179
"realtime-framework",
1810
"collaboration",

src/index.js

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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,9 +20,7 @@ class CoCreateServerSideRender {
2020
let dep = [];
2121
let dbCache = new Map();
2222

23-
async function render(html, lastKey) {
24-
const dom = parse(html);
25-
23+
async function render(dom, lastKey) {
2624
// Handle elements with [array][key][object]
2725
for (let el of dom.querySelectorAll("[array][key][object]")) {
2826
let meta = el.attributes;
@@ -32,14 +30,7 @@ class CoCreateServerSideRender {
3230
if (el.closest(".template, [template], template, [render]"))
3331
continue;
3432

35-
if (
36-
el.hasAttribute("render-selector") ||
37-
el.hasAttribute("render-closest") ||
38-
el.hasAttribute("render-parent") ||
39-
el.hasAttribute("render-next") ||
40-
el.hasAttribute("render-previous")
41-
)
42-
continue;
33+
if (el.hasAttribute("render-query")) continue;
4334

4435
if (el.hasAttribute("component") || el.hasAttribute("plugin"))
4536
continue;
@@ -149,10 +140,91 @@ class CoCreateServerSideRender {
149140
return dom;
150141
}
151142

152-
let result = await render(html, "root");
143+
let dom = parse(file.src);
144+
dom = await render(dom, "root");
145+
if (file.langRegion || file.lang) {
146+
dom = translate(dom, file);
147+
let langLinkTags = createLanguageLinkTags(file);
148+
const head = dom.querySelector("head");
149+
if (head && langLinkTags) {
150+
const linksFragment = parse(
151+
`<fragment>${langLinkTags}</fragment>`
152+
);
153+
for (const link of linksFragment.childNodes) {
154+
head.appendChild(link);
155+
}
156+
}
157+
}
153158
dep = [];
154159
dbCache.clear();
155-
return result.toString();
160+
return dom.toString();
161+
}
162+
163+
createLanguageLinkTags(file) {
164+
let xDefault = file.path;
165+
166+
if (file.name !== "index.html") {
167+
if (xDefault.endsWith("/")) {
168+
xDefault += file.name;
169+
} else {
170+
xDefault += "/" + file.name;
171+
}
172+
}
173+
let generatedLinksString = `<link rel="alternate" hreflang="x-default" href="${xDefault}">\n`;
174+
175+
// Step 1: Create a lookup object that maps base language to its path.
176+
// This is done once for efficiency.
177+
const paths = {};
178+
for (const p of file.pathname) {
179+
const secondSlashIndex = p.indexOf("/", 1);
180+
const langKey = p.substring(1, secondSlashIndex); // e.g., 'en', 'es', 'pt'
181+
const restOfPath = p.substring(secondSlashIndex);
182+
paths[langKey] = restOfPath;
183+
}
184+
185+
// Step 2: Iterate through all supported languages and build the HTML string.
186+
for (const language of file.languages) {
187+
// Use the base language to find the correct path in our map
188+
const path = paths[language] || paths[language.split("-")[0]];
189+
190+
// If a valid path exists, construct the full link
191+
if (path) {
192+
// Construct the full href URL using the full language code from the array
193+
const hrefUrl = `https://${file.urlObject.hostname}/${language}${path}`;
194+
195+
// Append the HTML string. The hreflang and the URL path are now in sync.
196+
generatedLinksString += `<link rel="alternate" hreflang="${language}" href="${hrefUrl}">\n`;
197+
}
198+
}
199+
return generatedLinksString;
200+
}
201+
202+
async translate(dom, file) {
203+
let langRegion = file.langRegion;
204+
let lang = file.lang;
205+
if (file.translations & (langRegion || lang)) {
206+
for (let translation of file.translations) {
207+
let el = dom.querySelectorAll(translation.selector);
208+
if (translation.innerHTML) {
209+
let content =
210+
translation.innerHTML[langRegion] ||
211+
translation.innerHTML[lang];
212+
if (content) {
213+
el.innerHTML = content;
214+
}
215+
}
216+
if (translation.attributes) {
217+
for (let [key, language] of Object.entries(
218+
translation.attributes
219+
)) {
220+
let value = language[langRegion] || language[lang];
221+
if (value) {
222+
el.setAttribute(key, value);
223+
}
224+
}
225+
}
226+
}
227+
}
156228
}
157229
}
158230

0 commit comments

Comments
 (0)