@adobe/helix-html-pipeline 6.27.30 → 6.28.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [6.28.0](https://github.com/adobe/helix-html-pipeline/compare/v6.27.30...v6.28.0) (2026-03-31)
2
+
3
+
4
+ ### Features
5
+
6
+ * process section metadata on the server side ([#1058](https://github.com/adobe/helix-html-pipeline/issues/1058)) ([e9efcc2](https://github.com/adobe/helix-html-pipeline/commit/e9efcc2156f6b2154abee74c8175168ceb0c1c9a))
7
+
1
8
  ## [6.27.30](https://github.com/adobe/helix-html-pipeline/compare/v6.27.29...v6.27.30) (2026-03-25)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "6.27.30",
3
+ "version": "6.28.0",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -86,7 +86,7 @@
86
86
  "js-yaml": "4.1.1",
87
87
  "jsdom": "28.1.0",
88
88
  "junit-report-builder": "5.1.1",
89
- "lint-staged": "16.3.2",
89
+ "lint-staged": "16.4.0",
90
90
  "mocha": "11.7.5",
91
91
  "mocha-multi-reporters": "1.5.1",
92
92
  "mocha-suppress-logs": "0.6.0",
package/src/html-pipe.js CHANGED
@@ -15,6 +15,7 @@ import createPageBlocks from './steps/create-page-blocks.js';
15
15
  import createPictures from './steps/create-pictures.js';
16
16
  import { contentSecurityPolicyOnCode } from './steps/csp.js';
17
17
  import extractMetaData from './steps/extract-metadata.js';
18
+ import extractSectionMetadata from './steps/extract-section-metadata.js';
18
19
  import fetchContent from './steps/fetch-content.js';
19
20
  import fetch404 from './steps/fetch-404.js';
20
21
  import initConfig from './steps/init-config.js';
@@ -167,6 +168,7 @@ export async function htmlPipe(state, req) {
167
168
  await rewriteUrls(state);
168
169
  await fixSections(state);
169
170
  await createPageBlocks(state);
171
+ await extractSectionMetadata(state);
170
172
  await createPictures(state);
171
173
  await extractMetaData(state, req);
172
174
  await rewriteIcons(state);
@@ -32,6 +32,19 @@ export interface PipelineSiteConfig {
32
32
  }
33
33
  cdn?: ProjectCDNConfig;
34
34
  access?: SiteAccessConfig;
35
+ features?: SiteFeatures;
36
+ /**
37
+ * ISO date string of when the site was created
38
+ */
39
+ created?: string;
40
+ }
41
+ export interface SiteFeatures {
42
+ rendering?: {
43
+ /**
44
+ * Rendering version. Version 2 enables server-side section metadata processing.
45
+ */
46
+ version?: number;
47
+ };
35
48
  }
36
49
  export interface ModifiersSheet {
37
50
  data: Modifiers;
@@ -0,0 +1,73 @@
1
+ /*
2
+ * Copyright 2026 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ import { toString } from 'hast-util-to-string';
13
+ import { SKIP, visit } from 'unist-util-visit';
14
+ import { toMetaName } from '../utils/modifiers.js';
15
+ import { toBlockCSSClassNames } from './utils.js';
16
+
17
+ /**
18
+ * Checks whether section metadata processing is enabled for the current site.
19
+ * It is enabled if the rendering version is >= 2, or if no version is set
20
+ * and the site was created on or after April 15, 2026.
21
+ * @param {PipelineSiteConfig} config
22
+ * @returns {boolean}
23
+ */
24
+ function isSectionMetadataEnabled(config) {
25
+ const { version } = config.features?.rendering ?? {};
26
+ if (version !== undefined) {
27
+ return version >= 2;
28
+ }
29
+ return new Date(config.created) >= new Date('2026-04-15');
30
+ }
31
+
32
+ /**
33
+ * Processes section metadata blocks by applying their key/value pairs
34
+ * as data attributes on the parent section div, with special handling
35
+ * for the "style" key (added as class names).
36
+ * @type PipelineStep
37
+ * @param {PipelineState} state
38
+ */
39
+ export default function extractSectionMetadata(state) {
40
+ if (!isSectionMetadataEnabled(state.config)) {
41
+ return;
42
+ }
43
+
44
+ const { hast } = state.content;
45
+
46
+ const isSectionMetadata = (node) => node.tagName === 'div'
47
+ && node.properties?.className?.includes('section-metadata');
48
+
49
+ visit(hast, isSectionMetadata, (node, index, parent) => {
50
+ // extract metadata from rows
51
+ for (const $row of node.children) {
52
+ if ($row.tagName === 'div' && $row.children?.[1]) {
53
+ const [$name, $value] = $row.children;
54
+ const name = toMetaName(toString($name));
55
+ if (name) {
56
+ const value = toString($value).trim();
57
+ if (name === 'style') {
58
+ if (!parent.properties.className) {
59
+ parent.properties.className = [];
60
+ }
61
+ parent.properties.className.push(...toBlockCSSClassNames(value));
62
+ } else {
63
+ parent.properties[`data-${name}`] = value;
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ // remove the section-metadata block from the section
70
+ parent.children.splice(index, 1);
71
+ return SKIP;
72
+ });
73
+ }