publican.lib
Advanced tools
+1
-1
| { | ||
| "name": "publican.lib", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "Standard library of functions and utilities for Publican static sites", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+337
-214
@@ -1,28 +0,27 @@ | ||
| # publican.lib | ||
| # Publican.lib | ||
| A standard library of functions and utilities for [Publican static sites](https://publican.dev/). | ||
| A standard library of functions and utilities for [Publican static sites](https://publican.dev/). Refer to [publican.dev/tools/publican.lib/](https://publican.dev/tools/publican.lib/) for full documentation. | ||
| ## Quickstart | ||
| ## Import everything | ||
| Install `publican.lib` in your Publican project: | ||
| Install Publican.lib in your Publican project: | ||
| ```bash | ||
| npm i publican.lib | ||
| npm install publican.lib | ||
| ``` | ||
| Import it in your Publican configuration file (`publican.config.js`): | ||
| Then import it into your Publican configuration file: | ||
| ```js | ||
| // publican.config.js | ||
| // Publican configuration | ||
| import { libInit } from 'publican.lib'; | ||
| ``` | ||
| Then pass `publican` and `tacs` to the `libInit()` initialization function before calling `await publican.build();` | ||
| Pass `publican` and `tacs` to the `libInit()` initialization function before calling `await publican.build();` | ||
| ```js | ||
| // set Publican defaults, e.g. | ||
| // publican.config.root = '/'; | ||
| // ...set Publican defaults... | ||
| // initialize publican.dev | ||
| // initialize publican.lib | ||
| libInit(publican, tacs); | ||
@@ -38,5 +37,5 @@ | ||
| ## Advanced setup | ||
| ## Import individual utilities | ||
| The method above imports all library functions, but you can choose them on an individual basis, e.g. | ||
| Rather than using all functionality, you can choose to import specific functions. For example, to use all formatting and the `nav.pagination()`: | ||
@@ -47,6 +46,7 @@ ```js | ||
| // import from Publican.lib | ||
| import * as format from 'publican.lib/format'; | ||
| import { pagination } from 'publican.lib/nav'; | ||
| // create global object | ||
| // create a global functions object | ||
| tacs.fn = tacs.fn || {}; | ||
@@ -62,219 +62,387 @@ | ||
| ## feed | ||
| ## Utility functions | ||
| `feed` functions help with machine-readable feeds. All are available as `tacs.lib.feed.<fn>` functions after running `libInit()`. | ||
| The `util` library provides utility functions you can use in your Publican configuration file or elsewhere. | ||
| ### `rss(str, domain, root)` | ||
| Removes invalid HTML attributes and ensures all URIs use absolute references. | ||
| ### `env(name [, default])` | ||
| ```html | ||
| <content:encoded><![CDATA[ | ||
| ${ tacs.lib.feed.rss( data.contentRendered, tacs.config.domain, tacs.root ) } | ||
| ]]></content:encoded> | ||
| Fetches an environment variable, converts to a numeric value where possible, and reverts to a default when necessary: | ||
| ```js | ||
| // isDev true when NODE_ENV is explicitly set to "development" | ||
| const isDev = (env('NODE_ENV', 'production') === 'development'); | ||
| ``` | ||
| ### `json(str, domain, root)` | ||
| ### `apiFetch(object)` | ||
| Does the same as [`rss()`](#rssstr-domain-root) but also applies special encodings for JSON feeds. | ||
| Make an HTTP request, format the response, and cache when required. The object parameter properties: | ||
| ```json | ||
| "content_html": "${ tacs.lib.feed.json( data.contentRendered, tacs.config.domain, tacs.root ) }" | ||
| ``` | ||
| * `uri` - required | ||
| * `method` such as `"GET"` (the default) or `"POST"` | ||
| * `headers` - optional object with name/value pairs | ||
| * `authKey` - optional request header `Authorization` token | ||
| * `contentType` - optional request header `Content-Type` (JSON by default) | ||
| * `body` - request body as a querystring, object, or array of arrays | ||
| * `timeout` - in millseconds (default of 10000 -- 10 seconds) | ||
| * `cacheDir` - cache directory location (not used by default) | ||
| * `cacheMin` - the number of minutes to cache data | ||
| Ensure special characters are fully replaced using [`replace`](#replace) settings. | ||
| The function returns an object with the following properties: | ||
| * `ok`: either `true` or `false` | ||
| * `status`: the HTTP status code (`200` for OK) | ||
| * `body`: the resulting text or JSON response (or error message) | ||
| * `error`: error code | ||
| * `cache`: the cache file name when returning cached results | ||
| ### `escape(str)` | ||
| Example that caches a response for 10 minutes: | ||
| Escapes single-line HTML and XML strings. | ||
| ```js | ||
| const res = await apiFetch({ | ||
| uri: 'https://api.site.com/call', | ||
| authKey: 'mytoken', | ||
| cacheDir: './_cache/' | ||
| }); | ||
| ```html | ||
| <title>${ tacs.lib.feed.escape( data.title ) }</title> | ||
| if (res.ok) console.log(res.body); | ||
| ``` | ||
| ## format | ||
| ### `normalize(str)` | ||
| `format` functions display locale-specific values such as dates and numbers. All are available as `tacs.lib.format.<fn>` functions after running `libInit()`. | ||
| Normalizes a string to lowercase characters with hyphens in place of spaces: | ||
| ```js | ||
| normalize(' Publican Library 1 '); | ||
| // returns "publican-library-1" | ||
| ``` | ||
| ### `setLocale(locale)` | ||
| Defines the default locale when none is explicitly set in any of the following functions. | ||
| ### `strHash(str)` | ||
| Hashes a string to an MD5 hex value. | ||
| ```js | ||
| tacs.lib.format.setLocale( 'es-ES' ); | ||
| strHash('Publican Library'); | ||
| ``` | ||
| [`apiFetch()`](#apifetchobject) uses a hash of the HTTP URI, headers, and body as a filename when caching response data. | ||
| ### `number(num [, locale])` | ||
| Returns a formatted number with appropriate thousand and fraction symbols. | ||
| ### `cspScript(code [, type])` | ||
| When passed client-side JavaScript code in a string and an optional [`type` attribute](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/script/type), `cspScript()` returns an object with the properties: | ||
| * `code`: the inline code inside a `<script>` tag, and | ||
| * `hash`: a SHA-256 hash for [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/Guides/CSP) `script-src` settings. | ||
| ```js | ||
| tacs.lib.format.number( 12345.678 ); // 12,345.678 - default US | ||
| tacs.lib.format.number( 12345.678, 'es-ES' ); // 12.345,678 - Spanish | ||
| const tacs.myScript = cspScript('alert("Hello!")'); | ||
| ``` | ||
| You can use this in a template: | ||
| ### `currency(num, currency [, locale])` | ||
| ```html | ||
| <!-- Content Security Policy --> | ||
| <meta http-equiv="Content-Security-Policy" content=" | ||
| default-src 'self'; | ||
| script-src 'self' 'sha256-${ tacs.myScript.hash }'; | ||
| "> | ||
| Returns a formatted currency with appropriate thousand and fraction symbols. | ||
| <!-- add inline <script> --> | ||
| ${ tacs.myScript.code } | ||
| ``` | ||
| > Note: Publican [minifies inline JavaScript](https://publican.dev/docs/reference/publican-options/#html-minification) by default. Always pass a minified script to `cspScript()` to ensure it's not minified and the CSP hash remains the same. | ||
| ### `sortBy(prop)` | ||
| A function to sort an array using property values, e.g. | ||
| ```js | ||
| tacs.lib.format.currency( 12345.678, 'USD' ) // $12,345.68 - default US | ||
| tacs.lib.format.currency( 12345.678, 'USD', 'es-ES' ) // 12.345,68 $ - Spanish | ||
| const obj = [ | ||
| { name: "Craig" }, | ||
| { name: "Bob" }, | ||
| { name: "Anne" }, | ||
| ].sort( sortBy('name') ); | ||
| // in order: Anne, Bob, Craig | ||
| ``` | ||
| ### `numberRound(num [, locale])` | ||
| ### `fileInfo(path)` | ||
| Rounds a number up depending on its size: | ||
| When passed a file path, it returns an object with the following properties: | ||
| * < 1,000: to nearest 1 | ||
| * > 1,000 and < 10,000: to nearest 10 | ||
| * > 10,000 and < 100,000: to nearest 100 | ||
| * etc. | ||
| * `exists`: true or false | ||
| * `isFile`: true when a file | ||
| * `isDir`: true when a directory | ||
| * `modified`: the last modification timestamp | ||
| Returns an object with file information: | ||
| ```js | ||
| tacs.lib.format.numberRound( 12345 ) // 12,400 | ||
| const | ||
| file = './somefile.txt', | ||
| info = fileInfo(file); | ||
| if (info.exists) { | ||
| console.log(file); | ||
| if (info.isFile) { | ||
| console.log('is a file'); | ||
| } | ||
| else if (info.isDir) { | ||
| console.log('is a directory'); | ||
| } | ||
| } | ||
| ``` | ||
| ### `dateHuman(date [, locale])` | ||
| ## Event hook functions | ||
| Returns a date in human-readable format: | ||
| The `hook` [event functions](https://publican.dev/docs/reference/event-functions/) append supplemental data and change some aspects of static site rendering. | ||
| ### `processFileDate()` | ||
| A [processContent hook](https://publican.dev/docs/reference/event-functions/#processcontent) that sets the content [`date`](https://publican.dev/docs/reference/content-properties/#datadate) and `modified` properties for any content file using a file name pattern `YYYY-MM-DD_something.md`. | ||
| It does not alter the [rendered file slug](https://publican.dev/docs/reference/content-properties/#dataslug), but you can remove the date with: | ||
| ```js | ||
| tacs.lib.format.dateHuman('2026-09-05', 'en-US') // September 5, 2026 | ||
| tacs.lib.format.dateHuman('2026-09-05', 'en-GB') // 5 September 2026 | ||
| tacs.lib.format.dateHuman('2026-09-05', 'es-ES') // 5 de septiembre de 2026 | ||
| // slug replacement strings - remove YYYY-MM-DD | ||
| publican.config.slugReplace.set(/\d{4}-\d{2}-\d{2}_/g, ''); | ||
| ``` | ||
| ### `dateUTC(date)` | ||
| ### `contentFilename()` | ||
| Returns a date in UTC format. | ||
| A [processContent hook](https://publican.dev/docs/reference/event-functions/#processcontent) that parses a `{{ filename }}` above a code block in a markdown file. You can style the resulting HTML to show a tab or similar: | ||
| ```js | ||
| tacs.lib.format.dateUTC('2026-09-05') // Sat, 5 Sep 2025 00:00:00 GMT | ||
| ```html | ||
| <p class="filename language-js"> | ||
| <dfn>myfile.js</dfn> | ||
| </p> | ||
| <pre class="language-js">... | ||
| ``` | ||
| ### `dateISO(date)` | ||
| ### `htmlBlocks()` | ||
| Returns a date in ISO format. | ||
| A [processContent hook](https://publican.dev/docs/reference/event-functions/#processcontent) that replaces markdown lines starting `:::` with HTML tags. For example: | ||
| ```js | ||
| tacs.lib.format.dateISO('2026-09-05') // 2026-09-05 | ||
| ```md | ||
| ::: div id="mydiv" | ||
| Some content | ||
| ::: /div | ||
| ``` | ||
| results in the HTML: | ||
| ### `dateISOfull(date)` | ||
| ```html | ||
| <div id="mydiv"> | ||
| Returns a full datetime in ISO format. | ||
| <p>Some content<p> | ||
| ```js | ||
| tacs.lib.format.dateISOfull('2026-09-05') // 2026-09-05T00:00:00.000Z | ||
| </div> | ||
| ``` | ||
| ### `dateYear(date)` | ||
| ### `renderstartData()` | ||
| Returns a year. | ||
| A [processRenderStart hook](https://publican.dev/docs/reference/event-functions/#processrenderstart) that modifies the title and description of all tag index files to create friendlier text such as: | ||
| ```js | ||
| tacs.lib.format.dateYear('2026-09-05') // 2026 | ||
| * "JavaScript" posts | ||
| * List of 23 posts using the tag "JavaScript". | ||
| ### `renderstartInlineScripts()` | ||
| A [processRenderStart hook](https://publican.dev/docs/reference/event-functions/#processrenderstart) that creates a global `tacs.script` JavaScript Map that defines [inline scripts using cspScript()](#cspscriptcode--type): | ||
| 1. `tacs.script.get('theme')`: an inline script that appends a `data-theme` attribute to the root `<html>` element using a localStorage value | ||
| 1. `tacs.script.get('speculation')`: an inline [speculation rules definition](https://developer.mozilla.org/docs/Web/API/Speculation_Rules_API) | ||
| ### `prerenderInlineScripts()` | ||
| A [processPreRender hook](https://publican.dev/docs/reference/event-functions/#processprerender) that creates a `data.script` JavaScript Map for every page that defines an [inline script using cspScript()](#cspscriptcode--type): | ||
| 1. `data.script.get('schema')`: an inline [schema.org](https://schema.org/) structured data block. | ||
| ### `renderstartTagScore()` | ||
| A [processRenderStart hook](https://publican.dev/docs/reference/event-functions/#processrenderstart) that creates a global `tacs.tagScore` JavaScript Map object that calculates a score for each tag (lesser-used tags have a higher score). This helps determine related articles. | ||
| ### `prerenderRelated()` | ||
| A [processPreRender hook](https://publican.dev/docs/reference/event-functions/#processprerender) that appends a `data.related` array to every page with a list of related articles in order of relevancy. To output the three most-relevant related articles: | ||
| ```html | ||
| ${ data?.related?.length ? ` | ||
| <aside> | ||
| <h2>Related posts</h2> | ||
| <nav> | ||
| ${ data.related | ||
| .slice(0,3) | ||
| .map(p => `<p><a href="{ p.link }">${ p.title }</a></p>`) | ||
| .join('') } | ||
| </nav> | ||
| </aside> | ||
| ` : ''} | ||
| ``` | ||
| ## hook | ||
| ### `postrenderMeta()` | ||
| `hook` provides event functions to append supplemental data and can change static site rendering. | ||
| A [processPostRender hook](https://publican.dev/docs/reference/event-functions/#processpostrender) that inserts a Publican `<meta name="generator">` tag into the head of every HTML page. | ||
| ### processContent hook: `processFileDate()` | ||
| ## Formatting functions | ||
| Sets the `date` and `modified` date values for content when the filename matches `YYYY-MM-DD_something.md` | ||
| The `format` functions display locale-specific values such as dates and numbers. | ||
| ### processContent hook: `contentFilename()` | ||
| ### `setLocale(locale)` | ||
| Parses `{{ filename }}` above markdown code blocks to create code such as: | ||
| Defines the default locale when none is explicitly set in other formatting functions. | ||
| ```js | ||
| tacs.lib.format.setLocale( 'es-ES' ); | ||
| ``` | ||
| ### `number(num [, locale])` | ||
| Returns a formatted number with appropriate thousand and fraction symbols. | ||
| ```html | ||
| <p class="filename language-js"> | ||
| <dfn><code class="language-js">format.js</code></dfn> | ||
| </p> | ||
| <p>US: ${ tacs.lib.format.number( 12345.678 ) }</p> | ||
| <p>ES: ${ tacs.lib.format.number( 12345.678, 'es-ES' ) }</p> | ||
| ``` | ||
| US: 12,345.678 | ||
| ### processContent hook: `htmlBlocks()` | ||
| ES: 12.345,678 | ||
| Replaces lines starting `:::` with HTML tags, e.g. | ||
| ```md | ||
| ::: div id="mydiv" | ||
| ### `currency(num, currency [, locale])` | ||
| Some content | ||
| Returns a formatted currency with appropriate thousand and fraction symbols. | ||
| ::: /div | ||
| ```html | ||
| <p>US: ${ tacs.lib.format.currency( 12345.678, 'USD' ) }</p> | ||
| <p>ES: ${ tacs.lib.format.currency( 12345.678, 'USD', 'es-ES' ) }</p> | ||
| ``` | ||
| results in the HTML: | ||
| US: $12,345.68 | ||
| ES: 12.345,68 $ | ||
| ### `numberRound(num [, locale])` | ||
| Rounds a number up depending on its size: | ||
| * < 1,000: to nearest 1 | ||
| * \> 1,000 and < 10,000: to nearest 10 | ||
| * \> 10,000 and < 100,000: to nearest 100 | ||
| * etc. | ||
| ```html | ||
| <div id="mydiv"> | ||
| <p>${ tacs.lib.format.numberRound( 12345 ) }</p> | ||
| <p>${ tacs.lib.format.numberRound( 123456 ) }</p> | ||
| ``` | ||
| <p>Some content<p> | ||
| 12,400 | ||
| </div> | ||
| 124,000 | ||
| ### `dateHuman(date [, locale])` | ||
| Returns a date in human-readable format: | ||
| ```html | ||
| <p>US: ${ tacs.lib.format.dateHuman('2026-09-05', 'en-US') }</p> | ||
| <p>UK: ${ tacs.lib.format.dateHuman('2026-09-05', 'en-GB') }</p> | ||
| <p>ES: ${ tacs.lib.format.dateHuman('2026-09-05', 'es-ES') }</p> | ||
| ``` | ||
| US: September 5, 2026 | ||
| ### processRenderStart hook: `renderstartData()` | ||
| UK: 5 September 2026 | ||
| Modifies the title and description of all tag index files, e.g. | ||
| ES: 5 de septiembre de 2026 | ||
| * title: "JavaScript" posts | ||
| * description: List of 23 posts using the tag "JavaScript". | ||
| ### `dateUTC(date)` | ||
| ### processRenderStart hook: `renderstartInlineScripts()` | ||
| Returns a date in UTC format. | ||
| Creates a `tacs.script` Map that defines [CSP scripts](#cspscriptcode--type) for theming (theme) and prerender (speculation) inline scripts. | ||
| ```html | ||
| <pre>${ tacs.lib.format.dateUTC('2026-09-05T01:23:45') }</pre> | ||
| ``` | ||
| ```txt | ||
| Sat, 05 Sep 2026 00:23:45 GMT | ||
| ``` | ||
| ### processPreRender hook: `prerenderInlineScripts()` | ||
| Creates a `data.script` Map for every page that defines a [CSP script](#cspscriptcode--type) for structured data. | ||
| ### `dateISO(date)` | ||
| Returns a date in ISO format. | ||
| ### processRenderStart hook: `renderstartTagScore()` | ||
| ```html | ||
| <pre>tacs.lib.format.dateISO('2026-09-05T01:23:45')</pre> | ||
| ``` | ||
| Creates a new `tacs.tagScore` Map object that calculates a score for each tag to help determine related articles. Lesser-used tags have a higher score. | ||
| ```txt | ||
| 2026-09-05 | ||
| ``` | ||
| ### processPreRender hook: `prerenderRelated()` | ||
| ### `dateISOfull(date)` | ||
| Appends a `data.related` array to every page with a list of related articles in order of relevancy. | ||
| Returns a full datetime in ISO format. | ||
| ```html | ||
| <pre>tacs.lib.format.dateISOfull('2026-09-05T01:23:45')</pre> | ||
| ``` | ||
| ### postrenderMeta: `postrenderMeta()` | ||
| ```txt | ||
| 2026-09-05T00:23:45.000Z | ||
| ``` | ||
| Appends a `<meta name="generator">` tag into every HTML page. | ||
| ### `dateYear(date)` | ||
| ## nav | ||
| Returns a year. | ||
| `nav` functions provide navigation functions for menus and pagination. All are available as `tacs.lib.nav.<fn>` functions after running `libInit()`. | ||
| ```html | ||
| <pre>tacs.lib.format.dateYear('2026-09-05T01:23:45')</pre> | ||
| ``` | ||
| ```txt | ||
| 2025 | ||
| ``` | ||
| ### `menuMain(tacs, currentPage [, allOpen, maxLevel, omit])` | ||
| Creates a hierarchical main menu using the HTML structure: | ||
| ## Navigation functions | ||
| The `nav` functions provide HTML menus and pagination. | ||
| ### `menuMain()` | ||
| Creates a hierarchical main menu using the HTML `<menu>` structure with `<details>` and `<summary>` elements: | ||
| ```html | ||
@@ -302,9 +470,9 @@ <menu> | ||
| Parameters: | ||
| The function parameters in order: | ||
| * `tacs` - the global `tacs` object - required | ||
| * `currentPage` - the current page's URL from `data.link` - required | ||
| * `allOpen` - either -1=never, 0=when child is active, or 1=always | ||
| * `maxLevel` - the maximum depth of links | ||
| * `omit` - an array of root directory names to omit | ||
| * `tacs`: the global `tacs` object (required) | ||
| * `currentPage`: the current page's URL from `data.link` (required) | ||
| * `allOpen`: either -1=never open `<details>`, 0=when child is active, or 1=always | ||
| * `maxLevel`: the maximum depth of links | ||
| * `omit`: an array of root directory names to omit | ||
@@ -320,12 +488,12 @@ Use in a template: | ||
| ### `menuDir(tacs, rootDir, currentPage [, maxLevel])` | ||
| ### `menuDir()` | ||
| Creates a hierarchical menu for a specific directory using a similar structure to [`menuMain`](#menumaintacs-currentpage--allopen-maxlevel-omit), but all `<details>` have an `open` attribute set. | ||
| Creates a hierarchical menu for a specific directory using a similar structure to [`menuMain`](#menumain), but all `<details>` have an `open` attribute set. | ||
| Parameters: | ||
| * `tacs` - the global `tacs` object - required | ||
| * `rootDir` - directory name - required | ||
| * `currentPage` - the current page's URL from `data.link` - required | ||
| * `maxLevel` - the maximum depth of links | ||
| * `tacs`: the global `tacs` object (required) | ||
| * `rootDir`: the directory name (required) | ||
| * `currentPage`: the current page's URL from `data.link` (required) | ||
| * `maxLevel`: the maximum depth of links | ||
@@ -341,3 +509,3 @@ Use in a template: | ||
| ### `breadcrumb(tacs, currentPage)` | ||
| ### `breadcrumb()` | ||
@@ -357,4 +525,4 @@ Creates a breadcrumb trail to the current page using the HTML structure: | ||
| * `tacs` - the global `tacs` object - required | ||
| * `currentPage` - the current page's URL from `data.link` - required | ||
| * `tacs`: the global `tacs` object (required) | ||
| * `currentPage`: the current page's URL from `data.link` (required) | ||
@@ -368,5 +536,5 @@ Use in a template: | ||
| ### `tagList(tacs [, classPrefix, classMin, classMax])` | ||
| ### `tagList()` | ||
| Generates a list of all tags ordered by a count of the articles using those tags using the HTML structure: | ||
| Generates a list of all tags ordered by ascending count of the articles using those tags. It results in the HTML structure: | ||
@@ -388,6 +556,6 @@ ```html | ||
| * `tacs` - the global `tacs` object - required | ||
| * `classPrefix` - a `class` name to use (`taglist` by default) | ||
| * `classMin` - the minimum size counter (1 by default) | ||
| * `classMax` - the maximum size counter (5 by default) | ||
| * `tacs`: the global `tacs` object (required) | ||
| * `classPrefix`: a `class` name to use (`taglist` by default) | ||
| * `classMin`: the minimum size class (1 by default) | ||
| * `classMax`: the maximum size class (5 by default) | ||
@@ -403,5 +571,5 @@ The most-used tag has a class of `taglist5`. The least-used tag has a class of `taglist1`. All other tags have a value between. | ||
| ### `pagination(pagination)` | ||
| ### `pagination()` | ||
| Generates pagination on directory and tag index pages using the HTML structure: | ||
| Generates pagination for directory and tag index pages using the HTML structure: | ||
@@ -419,4 +587,6 @@ ```html | ||
| Use in a template by passing the page's `data.pagination` object: | ||
| Parameters: | ||
| * `pagination`: the page's `data.pagination` object (required) | ||
| ```html | ||
@@ -427,119 +597,72 @@ ${ tacs.lib.nav.pagination( data.pagination ) } | ||
| ## replace | ||
| ## Feed functions | ||
| `replace` provides custom string replacements that fixes common HTML issues and JSON encoding. | ||
| The `feed` functions help create machine-readable files in JSON and XML format. | ||
| ### `replaceMap(root)` | ||
| ### `rss(str, domain, root)` | ||
| Removes invalid HTML attributes and ensures all URIs use absolute references. | ||
| ## util | ||
| `util` provides utility functions you can import, e.g. | ||
| ```js | ||
| import { env, apiFetch } from 'publican.lib'; | ||
| ```xml | ||
| <content:encoded><![CDATA[ | ||
| ${ tacs.lib.feed.rss( data.contentRendered, tacs.config.domain, tacs.root ) } | ||
| ]]></content:encoded> | ||
| ``` | ||
| ### `env(name [, default])` | ||
| ### `json(str, domain, root)` | ||
| Fetches an environment variable, converts to a numeric value where possible, and reverts to a default when necessary: | ||
| Does the same as [`rss()`](#rssstr-domain-root) but also applies special encodings for JSON feeds that [are replaced](#json-characters). | ||
| ```js | ||
| const isDev = (env('NODE_ENV', 'production') === 'development'); | ||
| ```json | ||
| "content_html": "${ tacs.lib.feed.json( data.contentRendered, tacs.config.domain, tacs.root ) }" | ||
| ``` | ||
| ### `normalize(str)` | ||
| ### `escape(str)` | ||
| Normalizes a string to lowercase characters with hyphens in place of spaces: | ||
| Escapes single-line HTML and XML strings. | ||
| ```js | ||
| normalize(' Publican Library 1 '); // "publican-library-1" | ||
| ```html | ||
| <title>${ tacs.lib.feed.escape( data.title ) }</title> | ||
| ``` | ||
| ### `strHash(str)` | ||
| ## String replacements | ||
| Hashes a string to an MD5 hex value, as used by [`apiFetch()`](#apifetchobject) when caching HTTP requests: | ||
| The `replace` library provides a single `replaceMap()` function. It's passed the root path and returns a JavaScript Map with [string replacement](https://publican.dev/docs/setup/string-replacement/) definitions. | ||
| ```js | ||
| strHash('Publican Library'); | ||
| ``` | ||
| ### Text replacements | ||
| ### `cspScript(code [, type])` | ||
| * `__/` (double underscore then slash) or `−−ROOT−−` is replaced with the root path | ||
| * `−−COPYRIGHT−−` is replaced with `©<CURRENT_YEAR>` | ||
| Creates the `<script>` code with it's optional [`type` attribute](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/script/type) and [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/Guides/CSP) `script-src` SHA-256 hash for inline scripts. It returns an object with `code` and `hash` properties, e.g. | ||
| ```js | ||
| const myScript = cspScript('alert("Hello!")'); | ||
| // { | ||
| // code: "<script>alert("Hello")</script>", | ||
| // hash: "abc..." | ||
| // } | ||
| ``` | ||
| ### Style replacements | ||
| All elements with a `style` attribute setting the text alignment have `class="center"` or `class="right"` assigned accordingly. | ||
| ### `sortBy(prop)` | ||
| A function to sort an array using property values, e.g. | ||
| ### Table scrolling | ||
| ```js | ||
| const obj = [ | ||
| { name: "Craig" }, | ||
| { name: "Bob" }, | ||
| { name: "Anne" }, | ||
| ].sort( sortBy('name') ); | ||
| // now in Anne, Bob, Craig order | ||
| ``` | ||
| All `<table>` elements get a `<div class="tablescroll">` container to help with scrolling on smaller devices (set `overflow-inline: auto;` in CSS). | ||
| ### `apiFetch(object)` | ||
| ### Unnecessary paragraphs | ||
| Make an HTTP request with optional caching. The object parameters: | ||
| Unnecessary `<p>` tags are removed from around `<img>`, `<svg>`, and `<iframe>` elements. | ||
| * `uri` - required | ||
| * `method` such as `"GET"` (the default) or `"POST"` | ||
| * `headers` - optional object with name/value pairs | ||
| * `authKey` - optional request header Authorization token | ||
| * `contentType` - optional request header Content-Type (JSON by default) | ||
| * `body` - request body as a querystring, object, or array of arrays | ||
| * `timeout` - in millseconds (default of 10000) | ||
| * `cacheDir` - the location of the cache directory (not used by default) | ||
| * `cacheMin` - the number of minutes to cache request data | ||
| The function returns an object with the following properties: | ||
| ### Image handling | ||
| * `ok`: either `true` or `false` | ||
| * `status`: the HTTP status code (200 for OK) | ||
| * `body`: the resulting text or JSON response (or error message) | ||
| * `error`: error code | ||
| * `cache`: the cache file name when returning cached results | ||
| When not explicitly set on `<img>` tags: | ||
| Example: | ||
| * `alt` attributes are added, and | ||
| * `loading="lazy"` is set | ||
| ```js | ||
| const res = await apiFetch({ | ||
| uri: 'https://api.site.com/call', | ||
| authKey: 'mytoken' | ||
| }); | ||
| if (res.ok) console.log(res.body); | ||
| ``` | ||
| ### JSON characters | ||
| ### `fileInfo(path)` | ||
| Returns an object with file information: | ||
| ```js | ||
| const info = fileInfo('./some-file.txt'); | ||
| // { | ||
| // exists: true, | ||
| // isFile: true, | ||
| // isDir: false, | ||
| // modified: 12345678 (timestamp) | ||
| // } | ||
| ``` | ||
| Special characters for [JSON feeds](#jsonstr-domain-root) are replaced. |
40133
11.22%657
23.03%