@contentrain/emitter-astro 0.15.0 → 0.16.1

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
@@ -1548,6 +1548,8 @@ export interface SeoInput {
1548
1548
  author?: string
1549
1549
  authorUrl?: string
1550
1550
  profile?: AuthorProfile
1551
+ /** An archive page's own feed, site-root-relative — the Seo component links it. */
1552
+ feed?: { path: string; title?: string }
1551
1553
  noindex?: boolean
1552
1554
  nofollow?: boolean
1553
1555
  openGraph?: SocialOverride
@@ -3985,21 +3987,35 @@ function hostRedirectFiles(config, host) {
3985
3987
  //#endregion
3986
3988
  //#region src/seo-entry.ts
3987
3989
  /**
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.
3990
+ * A plugin's unrendered template, in its own syntax: Yoast `%%title%%`,
3991
+ * SEOPress `%%post_title%%`, Rank Math `%title%` / `%customfield(name)%`,
3992
+ * AIOSEO `#post_title`. Printed as-is it would be a literal
3993
+ * `%%title%% %%sep%%` in the search result, so such a value is dropped and
3994
+ * the page's own falls in. AIOSEO's tags are matched by name, not as any
3995
+ * `#word`: a title can hold a hashtag.
3993
3996
  */
3994
3997
  const TEMPLATE_RE = {
3995
3998
  yoast: /%%[a-z0-9_-]+%%/i,
3999
+ seopress: /%%[a-z0-9_-]+%%/i,
3996
4000
  rank_math: /%[a-z_]+(?:\([^)]*\))?%/i,
3997
4001
  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
4002
  };
4003
+ /**
4004
+ * Whether a string holds a template token. Percent-encoding is decoded first
4005
+ * when it decodes: `%E4%B8%AD` in a CJK URL is text, not Rank Math's `%AD%`.
4006
+ * A real token never decodes (`%ti…` is no escape), so it is tested as it is.
4007
+ */
4008
+ function hasToken(value, template) {
4009
+ let decoded = value;
4010
+ try {
4011
+ decoded = decodeURI(value);
4012
+ } catch {}
4013
+ return template.test(decoded);
4014
+ }
3999
4015
  const text = (value, template) => {
4000
4016
  const v = value?.trim();
4001
4017
  if (!v) return void 0;
4002
- return template?.test(v) ? void 0 : v;
4018
+ return template && hasToken(v, template) ? void 0 : v;
4003
4019
  };
4004
4020
  const addressKey = (url) => url.trim().replace(/^https?:\/\//i, "//").replace(/\/+(?=[?#]|$)/, "");
4005
4021
  function social(value, template) {
@@ -4015,16 +4031,39 @@ function social(value, template) {
4015
4031
  if (card) out.card = card;
4016
4032
  return Object.keys(out).length ? out : void 0;
4017
4033
  }
4034
+ /** Share-card values: the rendered ones, each missing one from the block. */
4035
+ function merged(rendered, stored) {
4036
+ if (!rendered) return stored;
4037
+ if (!stored) return rendered;
4038
+ return {
4039
+ ...stored,
4040
+ ...rendered
4041
+ };
4042
+ }
4018
4043
  /**
4019
4044
  * 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.
4045
+ * plugin's block wins; without one the first plugin (Yoast, Rank Math,
4046
+ * AIOSEO, SEOPress) that has data does. Its values are read, in order, from:
4047
+ *
4048
+ * 1. the block itself when the running plugin rendered it (`resolved`);
4049
+ * 2. `rendered` — the exporter's own rendering of the plugin's templates, for
4050
+ * a plugin that is not the one serving the head. Final text: a variable it
4051
+ * could not render is already out of the string, and only listed in
4052
+ * `unresolved` for a person to read;
4053
+ * 3. the stored values, with the plugin's unrendered templates dropped.
4054
+ *
4055
+ * 2 and 3 are taken field by field: a value the rendering does not carry
4056
+ * falls back to the block's stored literal.
4057
+ *
4058
+ * Whatever the source, a string that still holds a template token in the
4059
+ * plugin's syntax is dropped: a token is never printed. The same holds for
4060
+ * the JSON-LD: a resolved block's graph is the plugin's rendering; any other
4061
+ * block's graph — the exporter's rendered nodes, else its own top-level graph
4062
+ * — is read node by node, and a node still holding a token is left out.
4024
4063
  *
4025
4064
  * 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.
4065
+ * WordPress and the plugin reconciled their settings — then `rendered.robots`,
4066
+ * then the plugin's own `robots`.
4028
4067
  */
4029
4068
  function seoFromRawEntry(blocks, options = {}) {
4030
4069
  if (!blocks) return {};
@@ -4032,26 +4071,51 @@ function seoFromRawEntry(blocks, options = {}) {
4032
4071
  if (!provider) return {};
4033
4072
  const entry = blocks[provider];
4034
4073
  const template = entry.resolved === true ? void 0 : TEMPLATE_RE[provider];
4074
+ const rendered = entry.resolved === true ? void 0 : entry.rendered;
4035
4075
  const out = {};
4036
- const title = text(entry.title, template);
4076
+ const title = text(rendered?.title, template) ?? text(entry.title, template);
4037
4077
  if (title) out.seo_title = title;
4038
- const description = text(entry.description, template);
4078
+ const description = text(rendered?.description, template) ?? text(entry.description, template);
4039
4079
  if (description) out.description = description;
4040
- const canonical = entry.canonical?.trim();
4080
+ const canonical = (rendered?.canonical ?? entry.canonical)?.trim();
4041
4081
  if (canonical && !(options.url && addressKey(canonical) === addressKey(options.url))) out.canonical = canonical;
4042
4082
  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";
4083
+ const robots = rendered?.robots ?? entry.robots;
4084
+ const noindex = served ? served.includes("noindex") : robots?.index === "noindex";
4085
+ const nofollow = served ? served.includes("nofollow") : robots?.follow === "nofollow";
4045
4086
  if (noindex) out.noindex = true;
4046
4087
  if (nofollow) out.nofollow = true;
4047
- const og = social(entry.open_graph, template);
4088
+ const og = merged(social(rendered?.open_graph, template), social(entry.open_graph, template));
4048
4089
  if (og) out.open_graph = og;
4049
- const tw = social(entry.twitter, template);
4090
+ const tw = merged(social(rendered?.twitter, template), social(entry.twitter, template));
4050
4091
  if (tw) out.twitter = tw;
4051
- const graph = entry.schema?.graph;
4052
- if (graph && typeof graph === "object") out.schema = graph;
4092
+ if (entry.resolved === true) {
4093
+ const graph = entry.schema?.graph;
4094
+ if (graph && typeof graph === "object") out.schema = graph;
4095
+ } else if (template) {
4096
+ const top = entry.schema?.graph;
4097
+ const nodes = (Array.isArray(rendered?.schema?.graph) ? rendered.schema.graph : ldNodes(top)).filter((node) => !holdsToken(node, template));
4098
+ if (nodes.length) out.schema = {
4099
+ "@context": "https://schema.org",
4100
+ "@graph": nodes
4101
+ };
4102
+ }
4053
4103
  return out;
4054
4104
  }
4105
+ /** A JSON-LD value's nodes: a @graph object's graph, a node array, or one node. */
4106
+ function ldNodes(value) {
4107
+ if (!value || typeof value !== "object") return [];
4108
+ if (Array.isArray(value)) return value;
4109
+ const graph = value["@graph"];
4110
+ return Array.isArray(graph) ? graph : [value];
4111
+ }
4112
+ /** Whether any string anywhere in a JSON value holds a template token. */
4113
+ function holdsToken(value, template) {
4114
+ if (typeof value === "string") return hasToken(value, template);
4115
+ if (Array.isArray(value)) return value.some((v) => holdsToken(v, template));
4116
+ if (value && typeof value === "object") return Object.values(value).some((v) => holdsToken(v, template));
4117
+ return false;
4118
+ }
4055
4119
  //#endregion
4056
4120
  //#region src/index.ts
4057
4121
  /**