@contentrain/emitter-astro 0.15.0 → 0.16.0

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/README.md CHANGED
@@ -114,9 +114,10 @@ chunk, or drop them at capture.
114
114
 
115
115
  `seoFromRawEntry(blocks, { serving, url })` maps one page's `RawSeo.entries[address]` — what each SEO plugin holds for it — to the fields above (`seo_title`, `description`, `canonical`, `noindex`/`nofollow`, `open_graph`, `twitter`, `schema`), ready to spread into an `EmitPost` or `QueryPage`:
116
116
 
117
- - The serving plugin's block is read (`RawSeo.serving`), else the first of Yoast, Rank Math and AIOSEO that has one.
118
- - A block not marked `resolved` holds stored values: its unrendered templates, in that plugin's own syntax (Yoast `%%title%%`, Rank Math `%title%`, AIOSEO's named tags such as `#post_title` — not any `#word`, so a hashtag survives), are dropped so the page's own values fall in, and its literal values are kept.
119
- - Robots come from `robots_served` — what the page actually carried — and from the plugin's setting only without it.
117
+ - The serving plugin's block is read (`RawSeo.serving`), else the first of Yoast, Rank Math, AIOSEO and SEOPress that has one.
118
+ - Its values come from the block itself when the running plugin rendered it (`resolved`); else from `rendered` — the exporter's own rendering of the plugin's templates (the Bridge's, `rendered_by`), final text whose unrenderable variables are already out of the string and only listed in `unresolved`; else from the stored values. The last two are taken field by field — a value the rendering does not carry falls back to the stored literal. The JSON-LD is the graph the running plugin rendered — from a `resolved` block only; any other block's graph is read node by node — else the schema nodes the exporter rendered (`rendered.schema.graph`, Rank Math), less any node that still holds a template token (a percent-encoded address — a Turkish or CJK slug — is decoded before it is checked, so `%E4%B8%AD` is not read as Rank Math's `%AD%`). Without a rendering, the block's own graph is read the same way, node by node. The home page's blocks, when it lists posts, are `RawSeo.home`; they read the same way.
119
+ - Outside a `resolved` block, a string that still holds a template token in the plugin's own syntax (Yoast and SEOPress `%%title%%`, Rank Math `%title%`, AIOSEO's named tags such as `#post_title` — not any `#word`, so a hashtag survives) is dropped so the page's own value falls in; a token is never printed. Literal values are kept.
120
+ - Robots come from `robots_served` — what the page actually carried — then `rendered.robots`, then the plugin's setting. The Twitter card is a setting and stays with the block.
120
121
  - A canonical equal to the page's own `url` is left out; only one that points elsewhere becomes an override.
121
122
 
122
123
  `options.seo: false` turns all of this off: the source head travels verbatim and
package/dist/index.d.mts CHANGED
@@ -531,14 +531,28 @@ interface SeoFromRawOptions {
531
531
  }
532
532
  /**
533
533
  * One page's SEO fields from the blocks each plugin holds for it. The serving
534
- * plugin's block wins; without one the first plugin (Yoast, Rank Math, AIOSEO)
535
- * that has data does. A block not marked `resolved` holds stored values and
536
- * templates, so its template strings — in that plugin's syntax — are dropped
537
- * and its literal values kept.
534
+ * plugin's block wins; without one the first plugin (Yoast, Rank Math,
535
+ * AIOSEO, SEOPress) that has data does. Its values are read, in order, from:
536
+ *
537
+ * 1. the block itself when the running plugin rendered it (`resolved`);
538
+ * 2. `rendered` — the exporter's own rendering of the plugin's templates, for
539
+ * a plugin that is not the one serving the head. Final text: a variable it
540
+ * could not render is already out of the string, and only listed in
541
+ * `unresolved` for a person to read;
542
+ * 3. the stored values, with the plugin's unrendered templates dropped.
543
+ *
544
+ * 2 and 3 are taken field by field: a value the rendering does not carry
545
+ * falls back to the block's stored literal.
546
+ *
547
+ * Whatever the source, a string that still holds a template token in the
548
+ * plugin's syntax is dropped: a token is never printed. The same holds for
549
+ * the JSON-LD: a resolved block's graph is the plugin's rendering; any other
550
+ * block's graph — the exporter's rendered nodes, else its own top-level graph
551
+ * — is read node by node, and a node still holding a token is left out.
538
552
  *
539
553
  * Robots come from `robots_served` — what the page actually carried after
540
- * WordPress and the plugin reconciled their settings — and from the plugin's
541
- * own `robots` only when that is missing.
554
+ * WordPress and the plugin reconciled their settings — then `rendered.robots`,
555
+ * then the plugin's own `robots`.
542
556
  */
543
557
  declare function seoFromRawEntry(blocks: Partial<Record<SeoProvider, RawSeoEntry>> | undefined, options?: SeoFromRawOptions): SeoFields;
544
558
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/css.ts","../src/feed.ts","../src/util.ts","../src/layouts.ts","../src/components.ts","../src/seo.ts","../src/seo-entry.ts","../src/alternates.ts","../src/embed.ts","../src/ui-strings.ts","../src/balance.ts","../src/noindex.ts","../src/redirects.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/css.ts","../src/feed.ts","../src/util.ts","../src/layouts.ts","../src/components.ts","../src/seo.ts","../src/seo-entry.ts","../src/alternates.ts","../src/embed.ts","../src/ui-strings.ts","../src/balance.ts","../src/noindex.ts","../src/redirects.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -3985,21 +3985,35 @@ function hostRedirectFiles(config, host) {
3985
3985
  //#endregion
3986
3986
  //#region src/seo-entry.ts
3987
3987
  /**
3988
- * A plugin's unrendered template, in its own syntax: Yoast \`%%title%%\`,
3989
- * Rank Math \`%title%\` / \`%customfield(name)%\`, AIOSEO \`#post_title\`.
3990
- * Printed as-is it would be a literal \`%%title%% %%sep%%\` in the search
3991
- * result, so such a value is dropped and the page's own falls in. AIOSEO's
3992
- * tags are matched by name, not as any \`#word\`: a title can hold a hashtag.
3988
+ * A plugin's unrendered template, in its own syntax: Yoast `%%title%%`,
3989
+ * SEOPress `%%post_title%%`, Rank Math `%title%` / `%customfield(name)%`,
3990
+ * AIOSEO `#post_title`. Printed as-is it would be a literal
3991
+ * `%%title%% %%sep%%` in the search result, so such a value is dropped and
3992
+ * the page's own falls in. AIOSEO's tags are matched by name, not as any
3993
+ * `#word`: a title can hold a hashtag.
3993
3994
  */
3994
3995
  const TEMPLATE_RE = {
3995
3996
  yoast: /%%[a-z0-9_-]+%%/i,
3997
+ seopress: /%%[a-z0-9_-]+%%/i,
3996
3998
  rank_math: /%[a-z_]+(?:\([^)]*\))?%/i,
3997
3999
  aioseo: /#(?:(?:alt|archive|attachment|author|category|current|custom_field|page|parent|post|search|separator|site|tax|taxonomy)_[a-z0-9_-]+|categories|permalink|tagline)\b/i
3998
4000
  };
4001
+ /**
4002
+ * Whether a string holds a template token. Percent-encoding is decoded first
4003
+ * when it decodes: `%E4%B8%AD` in a CJK URL is text, not Rank Math's `%AD%`.
4004
+ * A real token never decodes (`%ti…` is no escape), so it is tested as it is.
4005
+ */
4006
+ function hasToken(value, template) {
4007
+ let decoded = value;
4008
+ try {
4009
+ decoded = decodeURI(value);
4010
+ } catch {}
4011
+ return template.test(decoded);
4012
+ }
3999
4013
  const text = (value, template) => {
4000
4014
  const v = value?.trim();
4001
4015
  if (!v) return void 0;
4002
- return template?.test(v) ? void 0 : v;
4016
+ return template && hasToken(v, template) ? void 0 : v;
4003
4017
  };
4004
4018
  const addressKey = (url) => url.trim().replace(/^https?:\/\//i, "//").replace(/\/+(?=[?#]|$)/, "");
4005
4019
  function social(value, template) {
@@ -4015,16 +4029,39 @@ function social(value, template) {
4015
4029
  if (card) out.card = card;
4016
4030
  return Object.keys(out).length ? out : void 0;
4017
4031
  }
4032
+ /** Share-card values: the rendered ones, each missing one from the block. */
4033
+ function merged(rendered, stored) {
4034
+ if (!rendered) return stored;
4035
+ if (!stored) return rendered;
4036
+ return {
4037
+ ...stored,
4038
+ ...rendered
4039
+ };
4040
+ }
4018
4041
  /**
4019
4042
  * One page's SEO fields from the blocks each plugin holds for it. The serving
4020
- * plugin's block wins; without one the first plugin (Yoast, Rank Math, AIOSEO)
4021
- * that has data does. A block not marked `resolved` holds stored values and
4022
- * templates, so its template strings — in that plugin's syntax — are dropped
4023
- * and its literal values kept.
4043
+ * plugin's block wins; without one the first plugin (Yoast, Rank Math,
4044
+ * AIOSEO, SEOPress) that has data does. Its values are read, in order, from:
4045
+ *
4046
+ * 1. the block itself when the running plugin rendered it (`resolved`);
4047
+ * 2. `rendered` — the exporter's own rendering of the plugin's templates, for
4048
+ * a plugin that is not the one serving the head. Final text: a variable it
4049
+ * could not render is already out of the string, and only listed in
4050
+ * `unresolved` for a person to read;
4051
+ * 3. the stored values, with the plugin's unrendered templates dropped.
4052
+ *
4053
+ * 2 and 3 are taken field by field: a value the rendering does not carry
4054
+ * falls back to the block's stored literal.
4055
+ *
4056
+ * Whatever the source, a string that still holds a template token in the
4057
+ * plugin's syntax is dropped: a token is never printed. The same holds for
4058
+ * the JSON-LD: a resolved block's graph is the plugin's rendering; any other
4059
+ * block's graph — the exporter's rendered nodes, else its own top-level graph
4060
+ * — is read node by node, and a node still holding a token is left out.
4024
4061
  *
4025
4062
  * Robots come from `robots_served` — what the page actually carried after
4026
- * WordPress and the plugin reconciled their settings — and from the plugin's
4027
- * own `robots` only when that is missing.
4063
+ * WordPress and the plugin reconciled their settings — then `rendered.robots`,
4064
+ * then the plugin's own `robots`.
4028
4065
  */
4029
4066
  function seoFromRawEntry(blocks, options = {}) {
4030
4067
  if (!blocks) return {};
@@ -4032,26 +4069,51 @@ function seoFromRawEntry(blocks, options = {}) {
4032
4069
  if (!provider) return {};
4033
4070
  const entry = blocks[provider];
4034
4071
  const template = entry.resolved === true ? void 0 : TEMPLATE_RE[provider];
4072
+ const rendered = entry.resolved === true ? void 0 : entry.rendered;
4035
4073
  const out = {};
4036
- const title = text(entry.title, template);
4074
+ const title = text(rendered?.title, template) ?? text(entry.title, template);
4037
4075
  if (title) out.seo_title = title;
4038
- const description = text(entry.description, template);
4076
+ const description = text(rendered?.description, template) ?? text(entry.description, template);
4039
4077
  if (description) out.description = description;
4040
- const canonical = entry.canonical?.trim();
4078
+ const canonical = (rendered?.canonical ?? entry.canonical)?.trim();
4041
4079
  if (canonical && !(options.url && addressKey(canonical) === addressKey(options.url))) out.canonical = canonical;
4042
4080
  const served = entry.robots_served?.map((d) => d.trim().toLowerCase());
4043
- const noindex = served ? served.includes("noindex") : entry.robots?.index === "noindex";
4044
- const nofollow = served ? served.includes("nofollow") : entry.robots?.follow === "nofollow";
4081
+ const robots = rendered?.robots ?? entry.robots;
4082
+ const noindex = served ? served.includes("noindex") : robots?.index === "noindex";
4083
+ const nofollow = served ? served.includes("nofollow") : robots?.follow === "nofollow";
4045
4084
  if (noindex) out.noindex = true;
4046
4085
  if (nofollow) out.nofollow = true;
4047
- const og = social(entry.open_graph, template);
4086
+ const og = merged(social(rendered?.open_graph, template), social(entry.open_graph, template));
4048
4087
  if (og) out.open_graph = og;
4049
- const tw = social(entry.twitter, template);
4088
+ const tw = merged(social(rendered?.twitter, template), social(entry.twitter, template));
4050
4089
  if (tw) out.twitter = tw;
4051
- const graph = entry.schema?.graph;
4052
- if (graph && typeof graph === "object") out.schema = graph;
4090
+ if (entry.resolved === true) {
4091
+ const graph = entry.schema?.graph;
4092
+ if (graph && typeof graph === "object") out.schema = graph;
4093
+ } else if (template) {
4094
+ const top = entry.schema?.graph;
4095
+ const nodes = (Array.isArray(rendered?.schema?.graph) ? rendered.schema.graph : ldNodes(top)).filter((node) => !holdsToken(node, template));
4096
+ if (nodes.length) out.schema = {
4097
+ "@context": "https://schema.org",
4098
+ "@graph": nodes
4099
+ };
4100
+ }
4053
4101
  return out;
4054
4102
  }
4103
+ /** A JSON-LD value's nodes: a @graph object's graph, a node array, or one node. */
4104
+ function ldNodes(value) {
4105
+ if (!value || typeof value !== "object") return [];
4106
+ if (Array.isArray(value)) return value;
4107
+ const graph = value["@graph"];
4108
+ return Array.isArray(graph) ? graph : [value];
4109
+ }
4110
+ /** Whether any string anywhere in a JSON value holds a template token. */
4111
+ function holdsToken(value, template) {
4112
+ if (typeof value === "string") return hasToken(value, template);
4113
+ if (Array.isArray(value)) return value.some((v) => holdsToken(v, template));
4114
+ if (value && typeof value === "object") return Object.values(value).some((v) => holdsToken(v, template));
4115
+ return false;
4116
+ }
4055
4117
  //#endregion
4056
4118
  //#region src/index.ts
4057
4119
  /**