Setting the file. One moment. Generate Repeater Cms · Wix Headless Replatform · wix/skills · Skills Docs28.10
Workflow
Next
Script Generate Route Plan
scripts/generate-repeater-cms.mjs
JavaScript·22 lines·5 KB
=>
(page.repeaters
||
[]).
filter
((
r
)
=>
r.kind
===
"accordion-repeater"
).
map
((
r
,
index
)
=>
plan
(page, r, index)));
7 const docs = docsDir(outputDir);
8 await writeJson(path.join(docs, "repeater-cms.json"), { version: 1, collections });
9 await writeText(path.join(docs, "repeater-cms.md"), `# CMS repeater plan\n\n${collections.map((c) => `## ${c.displayName}\n\n- id: \`${c.id}\`\n- rows: ${c.items.length}\n- state: \`${JSON.stringify(c.state)}\`\n- fields: \`label\`, \`body\`, \`imagesJson\`, \`linksJson\`, \`sortOrder\`, \`initialExpanded\`, \`itemStructure\``).join("\n\n") || "No accordion repeaters extracted."}\n`);
10 if (collections.length) await install(outputDir);
11 return { collections };
12}
13function plan(page, repeater, index) { const id = `rpAccordion${slug(`${page.area}-${repeater.label || index + 1}`).split("-").map((p) => p[0]?.toUpperCase() + p.slice(1)).join("")}`; return { id, displayName: `RePlatform Accordion: ${repeater.label || index + 1}`, sourceUrl: page.url, state: repeater.state || {}, items: (repeater.items || []).map((item, i) => ({ sourceKey: `${id}-${i + 1}`, label: item.heading || `Item ${i + 1}`, body: (item.paragraphs || []).join("\n\n"), imagesJson: JSON.stringify(item.images || []), linksJson: JSON.stringify(item.links || []), sortOrder: i, initialExpanded: Boolean(item.initialExpanded), itemStructure: item.itemStructure || "text-only" })) }; }
14async function install(outputDir) {
15 const lib = path.join(outputDir, "src", "lib"), components = path.join(outputDir, "src", "components");
16 await ensureDir(lib); await ensureDir(components);
17 await generated(path.join(lib, "rp-repeater-cms.ts"), `// @generated-source wix-headless-replatform\nexport async function loadAccordionRows(itemsApi:any,dataCollectionId:string){const r=await itemsApi.queryDataItems({dataCollectionId}).ascending("data.sortOrder").find();return (r.items||[]).map((x:any)=>x.data||x).sort((a:any,b:any)=>a.sortOrder-b.sortOrder)}\n`);
18 await generated(path.join(components, "RpAccordion.astro"), `---\n// @generated-source wix-headless-replatform\nconst { rows, dataCollectionId, singleOpen = true } = Astro.props;\n---\n<section data-rp-accordion={singleOpen?'single':'multiple'} data-rp-collection={dataCollectionId}>{rows.map((row)=><details open={row.initialExpanded}><summary>{row.label}</summary><div>{row.body.split('\\n\\n').map((p)=><p>{p}</p>)}</div></details>)}</section>\n<script>\nimport { items } from '@wix/data';\nconst escapeHtml=(value)=>String(value).replace(/[&<>'\\"]/g,(char)=>({'&':'&','<':'<','>':'>',\"'\":''','\\"':'"'}[char]));\nconst renderRows=(root,rows)=>root.replaceChildren(...rows.map((row)=>{const detail=document.createElement('details');detail.open=Boolean(row.initialExpanded);detail.innerHTML=\`<summary>\${escapeHtml(row.label)}</summary><div>\${String(row.body||'').split('\\\\n\\\\n').map((paragraph)=>\`<p>\${escapeHtml(paragraph)}</p>\`).join('')}</div>\`;return detail;}));\ndocument.querySelectorAll('[data-rp-collection]').forEach(async(root)=>{try{const result=await items.queryDataItems({dataCollectionId:root.dataset.rpCollection}).ascending('data.sortOrder').find();const cmsRows=(result.items||[]).map((item)=>item.data||item).sort((a,b)=>a.sortOrder-b.sortOrder);if(cmsRows.length){renderRows(root,cmsRows);root.dataset.rpCmsBound='true';}}catch(error){console.warn('RePlatform accordion CMS read failed; using extracted fallback content.',error);}});\ndocument.querySelectorAll('[data-rp-accordion=\"single\"]').forEach((root)=>root.addEventListener('toggle',(event)=>{const current=event.target;if(current.tagName==='DETAILS'&¤t.open)root.querySelectorAll('details[open]').forEach((item)=>{if(item!==current)item.open=false;});},true));\n</script>\n`, migrateLegacyAccordion);
19}
20async function generated(file,text,migrate) { try { const existing = await readFile(file,"utf8"); if (!existing.includes("@generated-source wix-headless-replatform")) { const migrated = migrate?.(existing); if (migrated && migrated !== existing) await writeText(file,migrated); return; } } catch {} await writeText(file,text); }
21function migrateLegacyAccordion(text) { const legacyImport = "import { createClient, OAuthStrategy } from '@wix/sdk';\nimport { items } from '@wix/data';"; const legacyQuery = "const client=createClient({modules:{items},auth:OAuthStrategy({clientId:import.meta.env.WIX_CLIENT_ID})});const result=await client.items.queryDataItems"; if (!text.includes(legacyImport) || !text.includes(legacyQuery)) return text; return text.replace(legacyImport, "import { items } from '@wix/data';").replace(legacyQuery, "const result=await items.queryDataItems"); }
22function slug(v) { return String(v).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"") || "accordion"; }