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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@gov-cy/govcy-frontend-renderer

v1.1.0

Published

Render html for design elements of the Unified design system using njk or json template.

Downloads

191

Readme

npm (scoped) License Unit test tag-and-publish-on-version-change

Use this package to render HTML for gov.cy elements, as they are defined in the Unified Design System, using njk or json templates.

The rendered HTML should:

  • Be as close of a representation as possible of the design elements as they are defined in the Unified Design System
  • Include the gov.cy branding
  • Use the govcy design system css classes and javascript functions
  • Use HTML best practices and be valid HTML
  • Use accessibility best practices
  • Allow multiple languages
  • Be tested

The project is not intended to be used for production purposes, but your welcome to try.

The project uses nunjucks templates to built the html.

The package currently works with the version 3.0.0 of the design system.

Features

The package can: can:

Pre-requisites

  • You need to have Node.js installed. The package has been tested on node version 20.

Install

First, install the package using npm:

npm install @gov-cy/govcy-frontend-renderer

Usage

First, you need to import the package as shown in the example below.

import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';

The package's main functions accept an input:

Whether you are using a nunjucks template or a JSON object, the result is identical as they are both rendered using the same nunjucks macros.

The output returned is a string with the rendered HTML.

Nunjucks template example

Use a string with a nunjucks template and the renderFromString function to render HTML from a nunjucks template. See the example below.

import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
const renderer = new govcyFrontendRenderer();

// Define the input data
const inputData = 
{    
    "site" : {
        "lang" : "en",
        "title" : {"en":"Service title", "el":"Τιτλός υπηρεσίας"}, 
        "headerTitle" : {"en":"Header title", "el":"Τιτλός επικεφαλιδας"},
        "description" : {"en":"Service description", "el":"Περιγραφή υπηρεσίας"},
        "url" : "https://gov.cy",
        "cdn" : {
            "dist" : "https://cdn.jsdelivr.net/gh/gov-cy/[email protected]/dist",
            "cssIntegrity" : "sha384-1zLHWOtnS0hOIz5mVEPZp0UH5gUE6eo0CQcCGA3sF2TyYhHyKOd3Ni8Iy/NjEASU",
            "jsIntegrity" : "sha384-zOuDuogVaaTveh/Ou2iYwCk14zFiSmMk7Ax8yRnXDtOJMyKZH5+ZNibNVwZSKtw+"
        }
    },
    "pageData": {
        "title": {"en": "Page title", "el": "Τιτλός σελιδας"},
        "layout": "layouts/govcyBase.njk",
        "mainLayout": "max-width"
    }
};

// Define the template (njk)
let inputString = 
`
{% if pageData.layout %} {% extends pageData.layout %} {% endif %}
{% from "govcyElement.njk" import govcyElement %}
{% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}
{% block main %}
    {% call govcyElement("form",
        { 
            elements:
            [
                {
                    element: "textInput",
                    params: 
                    {
                        label:{en:"What is your name?",el:"Ποιο είναι το όνομα σας;"}
                        ,id:"name"
                        ,name:"name"
                        ,isPageHeading: true
                        ,autocomplete:"tel"
                    }
                },
                {
                    element:  "button",
                    params: {
                        text:{en:"Continue",el:"Συνέχεια"}
                        , type:"submit"
                    }
                }
            ]
        }) %}{% endcall %}

{% endblock %}
`

// Render
let rtn = renderer.renderFromString(inputString, inputData)
console.log(rtn);

In the example above, a sting will be written in the console containing the rendered HTML of a complete page.

It is important to start your template string with the following:

  • {% if pageData.layout %} {% extends pageData.layout %} {% endif %}: Will extend the gov.cy page template as defined in the pageData.layout property.
  • {% from "govcyElement.njk" import govcyElement %}: Will import the govcyElement macro which is responsible for rendering all the design elements.
  • {% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}: (Optional) Will import the govcyUtilities macro which includes localization and other utilities.

To render design elements, the packages uses the govcyElement macro. See more details in the design elements section.

JSON template example

Use a JSON object as the template and the renderFromJSON function to render HTML from a nunjucks template. See the example below.

import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
const renderer = new govcyFrontendRenderer();

// Define the input data
const inputData = 
{    
    "site" : {
        "lang" : "en",
        "title" : {"en":"Service title", "el":"Τιτλός υπηρεσίας"}, 
        "headerTitle" : {"en":"Header title", "el":"Τιτλός επικεφαλιδας"},
        "description" : {"en":"Service description", "el":"Περιγραφή υπηρεσίας"},
        "url" : "https://gov.cy",
        "cdn" : {
            "dist" : "https://cdn.jsdelivr.net/gh/gov-cy/[email protected]/dist",
            "cssIntegrity" : "sha384-1zLHWOtnS0hOIz5mVEPZp0UH5gUE6eo0CQcCGA3sF2TyYhHyKOd3Ni8Iy/NjEASU",
            "jsIntegrity" : "sha384-zOuDuogVaaTveh/Ou2iYwCk14zFiSmMk7Ax8yRnXDtOJMyKZH5+ZNibNVwZSKtw+"
        }
    },
    "pageData": {
        "title": {"en": "Page title", "el": "Τιτλός σελιδας"},
        "layout": "layouts/govcyBase.njk",
        "mainLayout": "max-width"
    }
};

// Define the JSON template 
let inputJson =  
{
    "sections": [
        {
            "name": "main",
            "elements": [
                {
                    "element": "form",
                    "params": {
                        "elements": [
                            {
                                "element": "textInput",
                                "params": 
                                {
                                    "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
                                    ,"id":"name"
                                    ,"name":"name"
                                    ,"isPageHeading": true
                                    ,"autocomplete":"tel"
                                }
                            },
                            {
                                "element": "button",
                                "params": 
                                {
                                    "text":{"en":"Continue","el":"Συνέχεια"}
                                    , "type":"submit"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    ]
}
;

// Render
let rtn = renderer.renderFromJSON(inputJson, inputData)
console.log(rtn);

In the example above, a sting will be written in the console containing the rendered HTML of a complete page.

More details in defining design elements see in the design elements section.

Render individual components example

To render individual components, use the same functions as above, but leave the pageData.layout empty, as shown in the example below (the example uses a JSON template). Everything except the site.langin the siteData and pageData will be ignored.

import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
const renderer = new govcyFrontendRenderer();

// Define the input data
const inputData = 
{    
    "site" : {
        "lang" : "en"
    },
    "pageData": {
        "layout": "",
    }
};

// Define the JSON template 
let inputJson =  
{
    "sections": [
        {
            "name": "main",
            "elements": [
                {
                    "element": "form",
                    "params": {
                        "elements": [
                            {
                                "element": "textInput",
                                "params": 
                                {
                                    "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
                                    ,"id":"name"
                                    ,"name":"name"
                                    ,"isPageHeading": true
                                    ,"autocomplete":"tel"
                                }
                            },
                            {
                                "element": "button",
                                "params": 
                                {
                                    "text":{"en":"Continue","el":"Συνέχεια"}
                                    , "type":"submit"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    ]
}
;

// Render
let rtn = renderer.renderFromJSON(inputJson, inputData)
console.log(rtn);

All the inputData except the site.lang and the empty pageData.layout will be ignored.

Site and page meta data explained

In the examples above an inputData object is defined and it is used to pass the site and page's meta data. They are used by the layouts/govcyBase.njk template to add the necessary HTML tags and attributes.

The inputData object has the following structure:

  • site.lang: the language of the site. It is used both in the <html lang attribute and to define the default language to be used by the individual design elements defined in the template.
  • site.title: the title of the site. It is used in the <title>, <meta property="og:title" and <meta property="twitter:title" tags of the head.
  • site.description: the description of the site. It is used in the <meta name="description", <meta property="og:description" and <meta property="twitter:description" tags of the head.
  • site.url: the URL of the site. It is used in the <meta property="og:url" and <meta property="twitter:url" tags of the head.
  • site.cdn.dist: the CDN of the site. It is used to define the URL of the CDN used for the CSS and JS files. If you need to change the version of the CDN, you can do it by changing this value (in this case you will need to change the site.cdn.cssIntegrity and site.cdn.jsIntegrity values as well)
  • site.cdn.cssIntegrity: the integrity of the CSS file. It is used to define the integrity of the CSS file. If you need to change the version of the CDN, you will need to change this value. https://www.srihash.org/ can help you generate the integrity value.
  • site.cdn.jsIntegrity: the integrity of the JS file. It is used to define the integrity of the JS file. If you need to change the version of the CDN, you will need to change this value. https://www.srihash.org/ can help you generate the integrity value.
  • pageData.title: the title of the page. It is used in the <title>, <meta property="og:title" and <meta property="twitter:title" tags of the head.
  • pageData.layout: the layout of the page. It is used to define the layout (or page template) of the page, which is defined in the layouts/govcyBase.njk template.
  • pageData.mainLayout: the main layout of the page. It can be either two-thirds or max-width.

Input Template explained

The input template can either be a JSON template or a nunjucks template string. It is used to define the design elements to be rendered.

Nunjucks input template

To use the pre-defined design elements, you need to import the govcyElement macro by including the{% from "govcyElement.njk" import govcyElement %} as shown in the coded examples.

// Define the template (njk)
let inputString = 
`
{% if pageData.layout %} {% extends pageData.layout %} {% endif %}
{% from "govcyElement.njk" import govcyElement %}
{% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}
{% block main %}
    {% call govcyElement("form",
        { 
            elements:
            [
                {
                    element: "textInput",
                    params: 
                    {
                        label:{en:"What is your name?",el:"Ποιο είναι το όνομα σας;"}
                        ,id:"name"
                        ,name:"name"
                        ,isPageHeading: true
                        ,autocomplete:"tel"
                    }
                },
                {
                    element:  "button",
                    params: {
                        text:{en:"Continue",el:"Συνέχεια"}
                        , type:"submit"
                    }
                }
            ]
        }) %}{% endcall %}

{% endblock %}
`;

If your using the pageData.layout, you can render html in each of the following gov.cy page template blocks:

  • bodyStart: the start of the body
  • header: the header section (where the gov.cy logo and service name are rendered)
  • beforeMain: the section before the main content
  • main: the main content
  • footer: the footer section
  • bodyEnd: the end of the body

Use the govcyElement macro inside the blocks to render the design elements defined in the govcyElement.njk template. More details in defining design elements see in the design elements section.

JSON input template

When using a JSON input template, there is no need to import or extend anything.

// Define the JSON template 
let inputJson =  
{
    "sections": [
        {
            "name": "main",
            "elements": [
                {
                    "element": "form",
                    "params": {
                        "elements": [
                            {
                                "element": "textInput",
                                "params": 
                                {
                                    "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
                                    ,"id":"name"
                                    ,"name":"name"
                                    ,"isPageHeading": true
                                    ,"autocomplete":"tel"
                                }
                            },
                            {
                                "element": "button",
                                "params": 
                                {
                                    "text":{"en":"Continue","el":"Συνέχεια"}
                                    , "type":"submit"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    ]
}
;

If your using the pageData.layout, you can render html in each of the following gov.cy page template blocks, by using the sections array (in a similar way blocks is use ) :

  • bodyStart: the start of the body
  • header: the header section (where the gov.cy logo and service name are rendered)
  • beforeMain: the section before the main content
  • main: the main content
  • footer: the footer section
  • bodyEnd: the end of the body

Define your design elements for each sections under the elements array. These elements use the same govcyElement macro to render the design elements. Do that by defining the element and params objects. For example:

{
    "element": "textInput",
    "params": 
    {
        "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
    }
}

will use the govcyElement macro to render the textInput design element as follows:

{{ 
    govcyElement({
    "textInput", 
    {
        "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
    }
    }) 
}}

More details in defining design elements see in the design elements section.

Included design elements

More details on the elements that are supported by the package and how to include them in your templates, can be found on the design elements document.

Localization

All content in design elements are defined with an object defining the available languages and their content. For example label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}. When rendering the package will determin which language to use with the following logic and order:

  1. if params.lang is defined in the design element, use that
  2. else if site.lang is defined in the siteData, use that
  3. else use el

If the params.lang is defined in the design element, the package will also render element with a lang attribute.

Change the package

Details on how to build, test and update the project can be found in the project notes document.

License

The package is released under the MIT License.

Contact

If you have any questions or feedback, please feel free to reach out to us at [email protected]