/** * # 脚本 导入内嵌 Elementor 模板([elementor-template id="N"] 短代码引用的 post) * 背景:落地页/产品页里的 shortcode widget 会引用 elementor_library 模板 * (如 smart-gateways 的 a36c301 → [elementor-template id="27143"],含 * “Dusun Updates” 标题 + posts 卡片列表)。原导入管线未迁移 elementor_library, * 这些模板在本地缺失,导致内嵌区块为空。 * 数据源:legacy/dusuniot-db-20261029.sql 的 (meta_id, , '_elementor_data', …)。 * 写入 contents:type=template,slug=`template-`,legacy_id=, * 供路由按 legacy_id 查询后用 ElementorRenderer 递归渲染。 * 运行:bun scripts/import-embedded-templates.ts [postId...] */ import { SQL } from "bun"; const DUMP = "/home/bigcode/data/dev/sites/dusuniot/legacy/dusuniot-db-20261029.sql"; const db = new SQL("postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot"); /** # 成员变量 需要导入的模板 post id(默认:落地页 smart-gateways 内嵌的 27143) **/ const ids = process.argv.slice(2).map(Number).filter((n) => Number.isFinite(n)); const targets = ids.length ? ids : [27143]; const text = await Bun.file(DUMP).text(); /** # 函数 从 dump 提取指定 post 的 _elementor_data(同 import-shop-template 的解析方式) */ function extract(postId: number): Record[] | null { const re = new RegExp("\\(\\d+," + postId + ",'_elementor_data','((?:[^'\\\\]|\\\\.)*)'\\)"); const m = text.match(re); if (!m) return null; const json = m[1]!.replace(/\\'/g, "'").replace(/\\"/g, '"').replace(/\\\\/g, "\\"); const data = JSON.parse(json); return Array.isArray(data) ? (data as Record[]) : null; } for (const id of targets) { const elements = extract(id); if (!elements) { console.error(`post ${id} 未找到 _elementor_data,跳过`); continue; } const slug = `template-${id}`; const title = `Elementor Template ${id}`; const meta = JSON.stringify({ elementor: elements }); const existing = await db`SELECT id FROM contents WHERE legacy_id=${id} OR (slug=${slug} AND type='template')`; if (existing.length) { await db`UPDATE contents SET meta=${meta}::text::jsonb, status='published', updated_at=now() WHERE id=${existing[0]!.id}`; console.log(`已更新 ${slug},contents.id = ${existing[0]!.id}`); } else { const inserted = await db` INSERT INTO contents (type, slug, title, status, meta, legacy_id, published_at) VALUES ('template', ${slug}, ${title}, 'published', ${meta}::text::jsonb, ${id}, now()) RETURNING id`; console.log(`已插入 ${slug},contents.id = ${inserted[0]!.id}`); } const top = elements.map((el) => String(el.id)).join(", "); console.log(` post ${id} 顶层节: ${top}`); } await db.end();