### Install @podium/layout Source: https://github.com/podium-lib/layout/blob/main/README.md Installs the @podium/layout module using npm. This is the first step to integrate the layout server into your project. ```bash npm install @podium/layout ``` -------------------------------- ### Process HTTP Request with Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Example of using the `.process()` method to handle an incoming HTTP request. It integrates context parsing and proxy mounting, returning a Promise that resolves with the processed HttpIncoming object or undefined if a proxy endpoint matched. ```js import { HttpIncoming } from '@podium/utils'; import Layout from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/', }); app.use(async (req, res, next) => { const incoming = new HttpIncoming(req, res, res.locals); try { const result = await layout.process(incoming); if (result) { res.locals.podium = result; next(); } } catch (error) { next(error); } }); ``` -------------------------------- ### Get Layout Pathname Source: https://github.com/podium-lib/layout/blob/main/README.md A helper method to retrieve the pathname configured in the Layout constructor. This is useful for defining routes that must match the layout's root path. ```javascript const layout = new Layout({ name: 'myLayout', pathname: '/foo' }); app.get(layout.pathname(), (req, res, next) => { // ... }); app.get(`${layout.pathname()}/bar`, (req, res, next) => { // ... }); app.get(`${layout.pathname()}/bar/:id`, (req, res, next) => { // ... }); ``` -------------------------------- ### Simple Layout Server with Express.js Source: https://github.com/podium-lib/layout/blob/main/README.md Demonstrates building a basic layout server using Express.js and @podium/layout. It shows how to register a podlet, fetch its content, and render a full HTML page. ```javascript import express from 'express'; import Layout, { html } from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/', }); const podlet = layout.client.register({ name: 'myPodlet', uri: 'http://localhost:7100/manifest.json', }); const app = express(); app.use(layout.middleware()); app.get('/', (req, res, next) => { const ctx = res.locals.podium.context; Promise.all([podlet.fetch(ctx)]).then((result) => { res.status(200).send(html`
${result[0]}
`); }); }); app.listen(7000); ``` -------------------------------- ### Register and Fetch Podlet with .client Source: https://github.com/podium-lib/layout/blob/main/README.md Illustrates using the .client property to interact with podlets. It shows how to register a podlet with its manifest URI and then fetch its content. Full documentation is available in the @podium/client library. ```javascript const layout = new Layout({ name: 'myLayout', pathname: '/', }); const podlet = layout.client.register({ name: 'myPodlet', uri: 'http://localhost:7100/manifest.json', }); podlet.fetch({}).then((result) => { console.log(result); }); ``` -------------------------------- ### Layout Constructor and Options Source: https://github.com/podium-lib/layout/blob/main/README.md Details the constructor for the Podium Layout module and its configuration options. This includes essential parameters like name and pathname, as well as optional logging and internal component configurations. ```APIDOC Layout(options) Creates a new Layout instance. options: name: string (required) - Name that the layout identifies itself by. Must be in camelCase. Example: 'myLayoutName' pathname: string (required) - Pathname of where a Layout is mounted in a http server. This value is used to mount the proxy and tell podlets where they are mounted. If mounted at root: '/' If mounted at /foo: '/foo' logger: object (optional) - A logger which conform to a log4j interface. Defaults to null. Console is also supported. Example: console context: object (optional) - Options to be passed on to the internal @podium/context constructor. Defaults to null. client: object (optional) - Options to be passed on to the internal @podium/client constructor. Defaults to null. proxy: object (optional) - Options to be passed on to the internal @podium/proxy constructor. Defaults to null. pathname examples: Mounting at root: const layout = new Layout({ name: 'myLayout', pathname: '/' }); app.use(layout.middleware()); app.get('/', ...); Mounting at /foo: const layout = new Layout({ name: 'myLayout', pathname: '/foo' }); app.use('/foo', layout.middleware()); app.get('/foo', ...); app.get('/foo/:id', ...); ``` -------------------------------- ### Connect Middleware for Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Provides a Connect-compatible middleware to handle layout operations, acting as a wrapper for the process method. It must be mounted before defining routes and stores context at res.locals.podium.context. ```javascript const app = express(); app.use(layout.middleware()); ``` -------------------------------- ### Render Content with Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Demonstrates using the `.render()` method to output content. This method is typically used by `.podiumSend()` and can accept an HTML string or a data object for document structure. ```js import { HttpIncoming } from '@podium/utils'; import Layout, { html } from '@podium/layout'; import express from 'express'; const layout = new Layout({ name: 'myLayout', pathname: '/', }); const app = express(); app.get('/', (req, res) => { const incoming = new HttpIncoming(req, res, res.locals); layout.render(incoming, html`
content to render
`); }); ``` -------------------------------- ### Render with Data Object in Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Shows how to use the `.render()` method with a data object to specify document title, locale, head content, scripts, styles, and body markup. ```js import { HttpIncoming } from '@podium/utils'; import Layout from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/', }); const incoming = new HttpIncoming(req, res, res.locals); // Using a data object layout.render(incoming, { title: 'my doc title', body: '
my content
', }); ``` -------------------------------- ### Register Custom Context Parser with .context Source: https://github.com/podium-lib/layout/blob/main/README.md Demonstrates extending the context functionality by registering a custom third-party context parser. The .context property exposes an instance of @podium/context for managing context data. ```javascript import Parser from 'my-custom-parser'; const layout = new Layout({ name: 'myLayout', pathname: '/', }); layout.context.register('customParser', new Parser('someConfig')); ``` -------------------------------- ### Accessing Metrics Stream with .metrics Source: https://github.com/podium-lib/layout/blob/main/README.md Explains that the .metrics property provides access to a combined metric stream from all internal modules. This allows for monitoring all metrics generated by sub-modules in one place. Refer to @metrics/metric for detailed documentation. ```javascript const layout = new Layout({ name: 'myLayout', pathname: '/' }); // Access the metric stream via layout.metrics // Example: layout.metrics.on('metric', (metric) => console.log(metric)); ``` -------------------------------- ### Configure JavaScript Assets Path Source: https://github.com/podium-lib/layout/blob/main/README.md Sets the pathname for a Layout's JavaScript assets. Options include specifying the asset URL, whether to prefix it with the layout's pathname, and the script type. Can accept a single option object or an array of objects. ```javascript const app = express(); const layout = new Layout({ name: 'myLayout', pathname: '/', }); // Serve a JS file at /assets/main.js layout.js({ value: '/assets/main.js' }); // Serve assets statically and set a relative URI app.use('/assets', express.static('./app/files/assets')); layout.js({ value: '/assets/main.js' }); // Set an absolute URL layout.js({ value: 'http://cdn.mysite.com/assets/js/e7rfg76.js' }); // Prefix the return value with the layout's pathname layout.js({ value: '/assets/main.js', prefix: true }); // Set script type to module layout.js({ value: '/assets/module.js', type: 'module' }); // Multiple JS assets layout.js([{ value: '/assets/main.js' }, { value: '/assets/secondary.js' }]); ``` -------------------------------- ### Set Debug Context Option in Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Demonstrates how to configure the `debug` option for the internal `@podium/context` constructor when initializing a `Layout` instance. This allows setting debugging flags for context processing. ```js import Layout from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/foo', context: { debug: { enabled: true, }, }, }); ``` -------------------------------- ### Configure CSS Assets Path Source: https://github.com/podium-lib/layout/blob/main/README.md Sets the pathname for a Layout's CSS assets. Options include specifying the asset URL and whether to prefix it with the layout's pathname. The 'value' can only be set once; subsequent calls with a value will throw, but calls to retrieve the value are permitted. ```javascript const app = express(); const layout = new Layout({ name: 'myLayout', pathname: '/', }); // Serve a CSS file at /assets/main.css layout.css({ value: '/assets/main.css' }); // Serve assets from static file server app.use('/assets', express.static('./app/files/assets')); layout.css({ value: '/assets/main.css' }); // Set an absolute URL layout.css({ value: 'http://cdn.mysite.com/assets/css/3ru39ur.css' }); // Prefix the return value with the layout's pathname layout.css({ value: '/assets/main.css', prefix: true }); // Multiple CSS assets layout.css([{ value: '/assets/main.css' }, { value: '/assets/secondary.css' }]); ``` -------------------------------- ### Set Proxy Timeout Option in Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Illustrates how to set the `timeout` option for the internal `@podium/proxy` constructor when creating a `Layout` instance. This configures the request timeout duration in milliseconds. ```js import Layout from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/foo', proxy: { timeout: 30000, }, }); ``` -------------------------------- ### Set Client Retries Option in Layout Source: https://github.com/podium-lib/layout/blob/main/README.md Shows how to configure the `retries` option for the internal `@podium/client` constructor within a `Layout` instance. This setting controls the number of retries for client requests. ```js import Layout from '@podium/layout'; const layout = new Layout({ name: 'myLayout', pathname: '/foo', client: { retries: 6, }, }); ``` -------------------------------- ### Override Default HTML Document with .view() Source: https://github.com/podium-lib/layout/blob/main/README.md Explains how to override the default encapsulating HTML document structure using the .view() method. It accepts a function that returns the custom HTML template, receiving data like locale, encoding, title, CSS, JS, and head/body content. ```javascript layout.view(data => ` ${data.title} ${data.head} ${data.body} `); ``` -------------------------------- ### Set CSS Prefix Option Source: https://github.com/podium-lib/layout/blob/main/README.md Demonstrates how to set the 'prefix' option for CSS assets within the Layout constructor. This option controls whether the returned value is prefixed with the pathname. ```javascript const app = express(); const layout = new Layout({ name: 'myLayout', pathname: '/foo', }); layout.css({ value: '/assets/main.css', prefix: true }); ``` -------------------------------- ### escape Utility Function Source: https://github.com/podium-lib/layout/blob/main/README.md Introduces the `escape` utility function, which performs the same HTML escaping as the `html` tagged template literal. It can be used manually to escape specific strings when needed. ```javascript import { escape } from "@podium/layout"; ``` -------------------------------- ### Send HTML Fragment with res.podiumSend() Source: https://github.com/podium-lib/layout/blob/main/README.md Details the res.podiumSend() method on http.ServerResponse for sending HTML fragments. It wraps the fragment in a default HTML document or a custom template set via .view(). Supports sending fragments directly or as an object with title, head, and body properties. ```javascript app.get(layout.pathname(), (req, res) => { res.podiumSend(html`

Hello World

`); }); ``` ```javascript app.get(layout.pathname(), (req, res) => { res.podiumSend({ title: 'Document title', head: '', body: '

Hello World

', }); }); ``` -------------------------------- ### DangerouslyIncludeUnescapedHTML Helper Source: https://github.com/podium-lib/layout/blob/main/README.md Explains `DangerouslyIncludeUnescapedHTML` for opting out of automatic escaping for trusted HTML strings. It's important to note that podlet content does not need this if the entire response is sent, rather than just `podlet.content`. ```javascript import { html, DangerouslyIncludeUnescapedHTML } from "@podium/layout"; const greeting = new DangerouslyIncludeUnescapedHTML({ __content: "Howdy" }); const result = html`

${greeting} partner!

` ``` -------------------------------- ### html Tagged Template Literal Source: https://github.com/podium-lib/layout/blob/main/README.md Describes the `html` tagged template literal, which automatically escapes inputs to prevent XSS attacks. Exceptions include podlet fetch results and strings wrapped in `DangerouslyIncludeUnescapedHTML`. It's intended for use with `podiumSend`. ```javascript import { html } from "@podium/layout"; ``` -------------------------------- ### TemplateResult Class Source: https://github.com/podium-lib/layout/blob/main/README.md Introduces the `TemplateResult` class, which is the type returned by the `html` tagged template literal. It can be used for type checking or in advanced scenarios where direct use of `html` might not suffice. ```javascript import { TemplateResult } from "@podium/layout"; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.