@cmo-so/cli 0.12.14 → 0.12.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cmo.mjs +66 -7
- package/package.json +1 -1
package/dist/cmo.mjs
CHANGED
|
@@ -15205,6 +15205,47 @@ async function partSet(site, slug, change) {
|
|
|
15205
15205
|
counts.social = (counts.social ?? 0) + links2.length;
|
|
15206
15206
|
}
|
|
15207
15207
|
}
|
|
15208
|
+
if (change.footer_links && slug === "footer") {
|
|
15209
|
+
const isRow = (b) => String(b.attrs.className ?? "").split(/\s+/).includes("maggie-footer-links");
|
|
15210
|
+
const items3 = change.footer_links.filter((l) => l?.label && l?.url).slice(0, 20).map(
|
|
15211
|
+
(l) => `<!-- wp:paragraph {"fontSize":"small"} -->
|
|
15212
|
+
<p class="has-small-font-size"><a href="${escAttr(l.url)}">${escAttr(l.label)}</a></p>
|
|
15213
|
+
<!-- /wp:paragraph -->`
|
|
15214
|
+
).join("\n\n");
|
|
15215
|
+
const row = items3 ? blockOf(
|
|
15216
|
+
`<!-- wp:group {"className":"maggie-footer-links","style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}},"layout":{"type":"flex","flexWrap":"wrap"}} -->
|
|
15217
|
+
<div class="wp-block-group maggie-footer-links" style="margin-bottom:var(--wp--preset--spacing--40)">${items3}</div>
|
|
15218
|
+
<!-- /wp:group -->`
|
|
15219
|
+
) : null;
|
|
15220
|
+
const old = find(blocks, isRow);
|
|
15221
|
+
if (old) {
|
|
15222
|
+
const top = blocks.indexOf(old);
|
|
15223
|
+
if (top >= 0) blocks.splice(top, 1, ...row ? [row] : []);
|
|
15224
|
+
else {
|
|
15225
|
+
const parent = find(blocks, (b) => b.inner.includes(old));
|
|
15226
|
+
const k = parent.inner.indexOf(old);
|
|
15227
|
+
if (row) parent.inner[k] = row;
|
|
15228
|
+
else {
|
|
15229
|
+
parent.inner.splice(k, 1);
|
|
15230
|
+
let seen = -1;
|
|
15231
|
+
const at = parent.content.findIndex((c) => c === null && ++seen === k);
|
|
15232
|
+
parent.content.splice(at, parent.content[at + 1] === "\n\n" ? 2 : 1);
|
|
15233
|
+
}
|
|
15234
|
+
touchPath(blocks, parent);
|
|
15235
|
+
}
|
|
15236
|
+
} else if (row) {
|
|
15237
|
+
const outer = blocks.find((b) => b.name === "core/group");
|
|
15238
|
+
if (outer?.inner.length) {
|
|
15239
|
+
const k = outer.inner.length - 1;
|
|
15240
|
+
outer.inner.splice(k, 0, row);
|
|
15241
|
+
let seen = -1;
|
|
15242
|
+
const at = outer.content.findIndex((c) => c === null && ++seen === k);
|
|
15243
|
+
outer.content.splice(at, 0, null, "\n\n");
|
|
15244
|
+
touchPath(blocks, outer);
|
|
15245
|
+
} else blocks.push(row);
|
|
15246
|
+
} else throw new Error("footer_links: give at least one { label, url }.");
|
|
15247
|
+
counts.footer_links = change.footer_links.length;
|
|
15248
|
+
}
|
|
15208
15249
|
const content = serialize(blocks);
|
|
15209
15250
|
if (content === p.content) return { slug, changed: false, counts };
|
|
15210
15251
|
await call(site, { method: "POST", path: `/wp/v2/template-parts/${p.id}`, body: { content } });
|
|
@@ -17433,6 +17474,11 @@ async function linksPlan(site, o = {}) {
|
|
|
17433
17474
|
);
|
|
17434
17475
|
const footer = await partGet(site, "footer").catch(() => null);
|
|
17435
17476
|
const footerPaths = footer ? contentLinks(footer.content, base) : /* @__PURE__ */ new Set();
|
|
17477
|
+
const rowHtml = /maggie-footer-links[^>]*>([\s\S]*?)<\/div>\s*<!-- \/wp:group -->/.exec(footer?.content ?? "")?.[1] ?? "";
|
|
17478
|
+
const footerRow = [...rowHtml.matchAll(/<a[^>]+href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/g)].map((m) => ({
|
|
17479
|
+
url: m[1],
|
|
17480
|
+
label: strip(m[2])
|
|
17481
|
+
}));
|
|
17436
17482
|
const header = await partGet(site, "header").catch(() => null);
|
|
17437
17483
|
const headerPaths = header ? contentLinks(header.content, base) : /* @__PURE__ */ new Set();
|
|
17438
17484
|
const chrome = /* @__PURE__ */ new Set([...menuPaths, ...footerPaths, ...headerPaths]);
|
|
@@ -17495,14 +17541,16 @@ async function linksPlan(site, o = {}) {
|
|
|
17495
17541
|
type: "menu",
|
|
17496
17542
|
why: "Main pages every visitor should reach in one click.",
|
|
17497
17543
|
add: wantMenu.slice(0, 6).map((d) => ({ label: d.title, url: d.url })),
|
|
17498
|
-
tool: "wp_menu_set"
|
|
17544
|
+
tool: "wp_menu_set",
|
|
17545
|
+
args: { add: wantMenu.slice(0, 6).map((d) => ({ label: d.title, url: d.path })) }
|
|
17499
17546
|
});
|
|
17500
17547
|
if (postDocs.length && blogPage && !chrome.has(blogPage.path))
|
|
17501
17548
|
actions.push({
|
|
17502
17549
|
type: "menu",
|
|
17503
17550
|
why: "The blog isn't reachable from the menu.",
|
|
17504
17551
|
add: [{ label: blogPage.title || "Blog", url: blogPage.url }],
|
|
17505
|
-
tool: "wp_menu_set"
|
|
17552
|
+
tool: "wp_menu_set",
|
|
17553
|
+
args: { add: [{ label: blogPage.title || "Blog", url: blogPage.path }] }
|
|
17506
17554
|
});
|
|
17507
17555
|
const legal = pageDocs.filter(
|
|
17508
17556
|
(d) => /privacy|terms|cookie|legal|impressum|datenschutz|accessib/i.test(`${d.path} ${d.title}`)
|
|
@@ -17514,7 +17562,14 @@ async function linksPlan(site, o = {}) {
|
|
|
17514
17562
|
type: "footer",
|
|
17515
17563
|
why: "Legal, contact and about pages belong in the footer of every page (trust, and Google's quality raters look for them).",
|
|
17516
17564
|
add: footerMissing.slice(0, 8).map((d) => ({ label: d.title, url: d.url })),
|
|
17517
|
-
tool: "wp_footer_set"
|
|
17565
|
+
tool: "wp_footer_set",
|
|
17566
|
+
// The footer's own row (if this tool made one) plus the missing pages, ready for wp_footer_set.
|
|
17567
|
+
args: {
|
|
17568
|
+
footer_links: [
|
|
17569
|
+
...footerRow,
|
|
17570
|
+
...footerMissing.slice(0, 8).filter((d) => !footerRow.some((r) => sitePath(r.url, base) === d.path)).map((d) => ({ label: d.title, url: d.path }))
|
|
17571
|
+
]
|
|
17572
|
+
}
|
|
17518
17573
|
});
|
|
17519
17574
|
for (const hub of hubs) {
|
|
17520
17575
|
const kids = pageDocs.filter((c) => c.parent === hub.id);
|
|
@@ -17637,8 +17692,8 @@ function relatedBlock(heading2, links2) {
|
|
|
17637
17692
|
const items3 = links2.map((l) => `<!-- wp:list-item -->
|
|
17638
17693
|
<li><a href="${esc(l.url)}">${esc(l.label)}</a></li>
|
|
17639
17694
|
<!-- /wp:list-item -->`).join("\n");
|
|
17640
|
-
return `<!-- wp:group {"metadata":{"name":"Related links","maggie":{"type":"related-links","version":1}},"align":"wide","className":"maggie-related-links","layout":{"type":"constrained"}} -->
|
|
17641
|
-
<div class="wp-block-group alignwide maggie-related-links"><!-- wp:heading {"level":2} -->
|
|
17695
|
+
return `<!-- wp:group {"metadata":{"name":"Related links","maggie":{"type":"related-links","version":1}},"align":"wide","className":"maggie-related-links","style":{"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60"}}},"layout":{"type":"constrained","contentSize":"var(--wp--style--global--wide-size)"}} -->
|
|
17696
|
+
<div class="wp-block-group alignwide maggie-related-links" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"><!-- wp:heading {"level":2} -->
|
|
17642
17697
|
<h2 class="wp-block-heading">${esc(heading2)}</h2>
|
|
17643
17698
|
<!-- /wp:heading -->
|
|
17644
17699
|
|
|
@@ -19601,12 +19656,16 @@ var elementTools = [
|
|
|
19601
19656
|
}),
|
|
19602
19657
|
tool({
|
|
19603
19658
|
name: "wp_footer_set",
|
|
19604
|
-
description: "Change the footer: any text (address, hours, copyright), link or picture, social profile links by service; reset goes back to the theme's own footer.",
|
|
19659
|
+
description: "Change the footer: any text (address, hours, copyright), link or picture, social profile links by service, the row of page links (footer_links); reset goes back to the theme's own footer.",
|
|
19605
19660
|
parameters: {
|
|
19606
19661
|
type: "object",
|
|
19607
19662
|
properties: {
|
|
19608
19663
|
...EDITS.properties ?? {},
|
|
19609
19664
|
social: obj('Social links by service: { "facebook": "https://\u2026", "instagram": "" (remove) }.'),
|
|
19665
|
+
footer_links: arr(
|
|
19666
|
+
"The footer's row of page links, in order (replaces the row set before; [] removes it): legal, contact, about, main pages.",
|
|
19667
|
+
obj("", { label: str2(""), url: str2("Relative for own pages: /contact/.") })
|
|
19668
|
+
),
|
|
19610
19669
|
reset: bool("Drop the site's changes: back to the theme's footer.")
|
|
19611
19670
|
}
|
|
19612
19671
|
},
|
|
@@ -23900,7 +23959,7 @@ var program = new Command();
|
|
|
23900
23959
|
// package.json
|
|
23901
23960
|
var package_default = {
|
|
23902
23961
|
name: "@cmo-so/cli",
|
|
23903
|
-
version: "0.12.
|
|
23962
|
+
version: "0.12.15",
|
|
23904
23963
|
description: "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
23905
23964
|
type: "module",
|
|
23906
23965
|
license: "MIT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmo-so/cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.15",
|
|
4
4
|
"description": "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|