57 lines
2.8 KiB
TypeScript
57 lines
2.8 KiB
TypeScript
/**
|
||
* # 脚本 导入内嵌 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, <postId>, '_elementor_data', …)。
|
||
* 写入 contents:type=template,slug=`template-<postId>`,legacy_id=<postId>,
|
||
* 供路由按 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<string, unknown>[] | 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<string, unknown>[]) : 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();
|