npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@akashacms/renderers

v0.9.9

Published

Consolidated support for multiple website content rendering tools in Node.js

Downloads

249

Readme

Renderers - Consolidated support for multiple website content rendering tools in Node.js

The @akashacms/renderers package can be used by any software, and does not have known dependencies on other AkashaCMS packages. It was designed for use by AkashaCMS, but also designed to be potentially usable by any other software.

The purpose is to present a harmonized interface to any package whose purpose is rendering files used in website construction. These packages fall into three categories:

  • Template rendering engines like EJS, Handlebars or Nunjucks
  • CSS rendering using LESS
  • Document rendering using Markdown or AsciiDoctor

Links:

  • Home page: https://akashacms.github.io/rendering-engines/index.html
  • NPM: https://www.npmjs.com/package/@akashacms/renderers
  • Introduction: https://akashacms.com/news/2022/09/renderers-package.html

Installation

$ npm install @akashacms/renderers --save

In your source code add this:

// CommonJS modules
const Renderers = require('@akashacms/renderers');
// ES6 modules
import {
    Configuration as RenderersConfiguration
} from '@akashacms/renderers';

The Configuration class handles configuration and organizing access to the rendering packages. For CommonJS modules imported as shown here, this class is referenced as Renderers.Configuration.

import {
    Configuration as RenderersConfiguration,
    Renderer
} from '@akashacms/renderers';

The Renderer class is how we encapsulate the rendering packages. Each encapsulated package has a matching Renderer class that interfaces with the package.

Usage

The model is that a file to be rendered has an input file name, and an output file name. The input file is in a pre-rendered format, such as Markdown, and the output file is in its rendered format, such as HTML.

The Configuration automatically loads the Renderer implementations contained in the package. It is easy to write your own Renderer and add them to the Configuration.

Suppose you have a content file to render. It can be rendered with the following code:

import { promises as fsp } from 'fs';

import {
    Configuration as RenderersConfiguration
} from '@akashacms/renderers';

const renderers = new RenderersConfiguration({
    // possible configuration options
});

const inputFN = '/path/to/input.html.md';
const input = await fsp.readFile(inputFN, 'utf-8');
const renderer = renderers.findRendererPath(inputFN);
const renderContext = renderer.parseMetadata({
    fspath: inputFN,
    content: input
});
// parseMetadata looks for frontmatter, and will
// modify the renderingContext to have two new fields.
// `body` will have the main body of the input
// `metadata` will have the frontmatter as an object

const rendered = await renderer.render(renderContext);

// ...
const outputFN = renderer.filePath(inputFN);
fsp.writeFile(outputFN, rendered, 'utf-8');

The findRendererPath method searches the available Renderers for one which will handle the path. Each Renderer has a match method which is used for matching file names.

The double extension, .html.md, is meant to convey that the input is Markdown and the output is HTML.

The parseMetadata method will examine a file to access any metadata values. For the Markdown renderer, and most other renderers, this turns into looking for a frontmatter block that is formatted in YAML.

The render method renders the content and metadata in the RenderingContext object. It produces an output formatted as per the renderer.

The output file name is computed by the Renderer using the filePath method.

You may want to render the Markdown file into a layout template. If so, change the final bit to this:

const layoutMetadata = {};
for (const yprop in renderContext.metadata) {
    layoutMetadata[yprop] = renderContext.metadata[yprop];
}
layoutMetadata.content = rendered;

const layoutFN = '/path/to/layouts/example.html.ejs';
const layout = await fsp.readFile(layoutFN, 'utf-8');
const layoutRenderer = renderers.findRendererPath(layoutFN);
const layoutRendered = layoutRenderer.render({
    fspath: layoutFN,
    content: layout,
    metadata: layoutMetadata
});
const outputFN = renderer.filePath(inputFN);
fsp.writeFile(outputFN, layoutRendered, 'utf-8');

This example uses an EJS formatted template. This follows roughly the same pattern as above.

It starts by finding the renderer for the layout template using findRendererPath.

In this case we assume the template does not contain any metadata values. Your application might want to support metadata in the layout template, in which case you can call parseMetadata.

The layout template should receive all metadata values. This allows those values to be substituted into the template. The example shows us computing the metadata from the values found in the original document. To that we add a value, content, which is the rendered output from the first stage.

Supported rendering engines

The supported engines are:

Name | Extension | Description -----|-----------|------------ AsciiDoc | .html.adoc | Supports AsciiDoctor documents Markdown | .html.md | Supports Markdown documents Markdoc | .html.markdoc | Supports Markdoc documents LESS | .css.less | Supports compiling LESS files to CSS EJS | .html.ejs | EJS Handlebars | .html.handlebars | Handlebars JSON | .html.json | Supports rendering a JSON document through a template to produce HTML Liquid | .html.liquid | LiquidJS Nunjucks | .html.njk | Nunjucks