@uniweb/core 0.4.6 → 0.4.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/core",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Core classes for the Uniweb platform - Uniweb, Website, Page, Block",
5
5
  "type": "module",
6
6
  "exports": {
package/src/page.js CHANGED
@@ -26,8 +26,9 @@ export default class Page {
26
26
  this.hideInHeader = pageData.hideInHeader || false
27
27
  this.hideInFooter = pageData.hideInFooter || false
28
28
 
29
- // Layout options (per-page overrides for header/footer/panels)
29
+ // Layout options (named layout + per-page overrides for header/footer/panels)
30
30
  this.layout = {
31
+ name: pageData.layout?.name || null,
31
32
  header: pageData.layout?.header !== false,
32
33
  footer: pageData.layout?.footer !== false,
33
34
  leftPanel: pageData.layout?.leftPanel !== false,
@@ -143,6 +144,15 @@ export default class Page {
143
144
  return this.dynamicContext?.paramValue || null
144
145
  }
145
146
 
147
+ /**
148
+ * Get the resolved layout name for this page.
149
+ * Cascade: page.layout.name > foundation defaultLayout > null
150
+ * @returns {string|null}
151
+ */
152
+ getLayoutName() {
153
+ return this.layout.name || this.website?.getDefaultLayoutName() || null
154
+ }
155
+
146
156
  /**
147
157
  * Get all block groups (for Layout component)
148
158
  * @returns {Object} { header, body, footer, left, right }
@@ -227,7 +237,7 @@ export default class Page {
227
237
  */
228
238
  getHeaderBlocks() {
229
239
  if (!this.hasHeader()) return null
230
- return this.website.getHeaderBlocks()
240
+ return this.website.getHeaderBlocks(this.getLayoutName())
231
241
  }
232
242
 
233
243
  /**
@@ -236,7 +246,7 @@ export default class Page {
236
246
  */
237
247
  getFooterBlocks() {
238
248
  if (!this.hasFooter()) return null
239
- return this.website.getFooterBlocks()
249
+ return this.website.getFooterBlocks(this.getLayoutName())
240
250
  }
241
251
 
242
252
  /**
@@ -245,7 +255,7 @@ export default class Page {
245
255
  */
246
256
  getLeftBlocks() {
247
257
  if (!this.hasLeftPanel()) return null
248
- return this.website.getLeftBlocks()
258
+ return this.website.getLeftBlocks(this.getLayoutName())
249
259
  }
250
260
 
251
261
  /**
@@ -254,7 +264,7 @@ export default class Page {
254
264
  */
255
265
  getRightBlocks() {
256
266
  if (!this.hasRightPanel()) return null
257
- return this.website.getRightBlocks()
267
+ return this.website.getRightBlocks(this.getLayoutName())
258
268
  }
259
269
 
260
270
  /**
package/src/website.js CHANGED
@@ -11,15 +11,30 @@ import singularize from './singularize.js'
11
11
 
12
12
  export default class Website {
13
13
  constructor(websiteData) {
14
- const { pages = [], theme = {}, config = {}, header, footer, left, right, notFound, versionedScopes = {} } = websiteData
14
+ const { pages = [], theme = {}, config = {}, layouts, header, footer, left, right, notFound, versionedScopes = {} } = websiteData
15
15
 
16
16
  // Site metadata
17
17
  this.name = config.name || ''
18
18
  this.description = config.description || ''
19
19
  this.url = config.url || ''
20
20
 
21
+ // Named layout section sets (when site has layout subdirectories)
22
+ if (layouts && typeof layouts === 'object') {
23
+ this._layoutSets = {}
24
+ for (const [name, panelData] of Object.entries(layouts)) {
25
+ this._layoutSets[name] = {
26
+ headerPage: panelData.header ? new Page(panelData.header, `layout-${name}-header`, this) : null,
27
+ footerPage: panelData.footer ? new Page(panelData.footer, `layout-${name}-footer`, this) : null,
28
+ leftPage: panelData.left ? new Page(panelData.left, `layout-${name}-left`, this) : null,
29
+ rightPage: panelData.right ? new Page(panelData.right, `layout-${name}-right`, this) : null,
30
+ }
31
+ }
32
+ } else {
33
+ this._layoutSets = null
34
+ }
35
+
21
36
  // Layout panels as Page objects (header, footer, left, right)
22
- // They build their own blocks lazily, just like regular pages
37
+ // Flat fields for backward compatibility (used when no named layouts)
23
38
  this.headerPage = header ? new Page(header, 'header', this) : null
24
39
  this.footerPage = footer ? new Page(footer, 'footer', this) : null
25
40
  this.leftPage = left ? new Page(left, 'left', this) : null
@@ -458,35 +473,63 @@ export default class Website {
458
473
 
459
474
  /**
460
475
  * Get remote layout component from foundation config
476
+ * @param {string|null} layoutName - Named layout to look up (null = default)
477
+ */
478
+ getRemoteLayout(layoutName) {
479
+ const config = globalThis.uniweb?.foundationConfig
480
+ if (!config) return null
481
+ // Named layouts map
482
+ if (layoutName && config.layouts?.[layoutName]) {
483
+ return config.layouts[layoutName]
484
+ }
485
+ // Single Layout (backward compat)
486
+ return config.Layout || null
487
+ }
488
+
489
+ /**
490
+ * Get default layout name from foundation config
491
+ * @returns {string|null}
461
492
  */
462
- getRemoteLayout() {
463
- return globalThis.uniweb?.foundationConfig?.Layout || null
493
+ getDefaultLayoutName() {
494
+ return globalThis.uniweb?.foundationConfig?.defaultLayout || null
464
495
  }
465
496
 
466
497
  /**
467
498
  * Get default block type from foundation config
468
499
  */
469
500
  getDefaultBlockType() {
470
- return globalThis.uniweb?.foundationConfig?.defaultType || 'Section'
501
+ return globalThis.uniweb?.foundationConfig?.defaultSection || 'Section'
471
502
  }
472
503
 
473
504
  // ─────────────────────────────────────────────────────────────────
474
505
  // Layout Blocks (from layout panel pages)
475
506
  // ─────────────────────────────────────────────────────────────────
476
507
 
477
- getHeaderBlocks() {
508
+ getHeaderBlocks(layoutName) {
509
+ if (layoutName && this._layoutSets?.[layoutName]) {
510
+ return this._layoutSets[layoutName].headerPage?.bodyBlocks || null
511
+ }
478
512
  return this.headerPage?.bodyBlocks || null
479
513
  }
480
514
 
481
- getFooterBlocks() {
515
+ getFooterBlocks(layoutName) {
516
+ if (layoutName && this._layoutSets?.[layoutName]) {
517
+ return this._layoutSets[layoutName].footerPage?.bodyBlocks || null
518
+ }
482
519
  return this.footerPage?.bodyBlocks || null
483
520
  }
484
521
 
485
- getLeftBlocks() {
522
+ getLeftBlocks(layoutName) {
523
+ if (layoutName && this._layoutSets?.[layoutName]) {
524
+ return this._layoutSets[layoutName].leftPage?.bodyBlocks || null
525
+ }
486
526
  return this.leftPage?.bodyBlocks || null
487
527
  }
488
528
 
489
- getRightBlocks() {
529
+ getRightBlocks(layoutName) {
530
+ if (layoutName && this._layoutSets?.[layoutName]) {
531
+ return this._layoutSets[layoutName].rightPage?.bodyBlocks || null
532
+ }
490
533
  return this.rightPage?.bodyBlocks || null
491
534
  }
492
535