@gov-cy/govcy-frontend-renderer 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 gov-cy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ [![npm (scoped)](https://img.shields.io/npm/v/@govcy-frontend-renderers)](https://www.npmjs.com/package/@govcy-frontend-renderers)
2
+ ![License](https://img.shields.io/github/license/gov-cy/govcy-frontend-renderer)
3
+ [![Unit test](https://github.com/gov-cy/govcy-frontend-renderer/actions/workflows/unit-test.yml/badge.svg)](https://github.com/gov-cy/govcy-frontend-renderer/actions/workflows/unit-test.yml)
4
+ [![tag-and-publish-on-version-change](https://github.com/gov-cy/govcy-frontend-renderer/actions/workflows/tag-and-publish-on-version-change.yml/badge.svg)](https://github.com/gov-cy/govcy-frontend-renderer/actions/workflows/tag-and-publish-on-version-change.yml)
5
+
6
+ Use this package to render HTML for gov.cy elements, as they are defined in the [Unified Design System](https://gov-cy.github.io/govcy-design-system-docs/), using njk or json templates.
7
+
8
+ The rendered HTML should:
9
+ - Be as close of a representation as possible of the design elements as they are defined in the [Unified Design System](https://gov-cy.github.io/govcy-design-system-docs/)
10
+ - Include the gov.cy branding
11
+ - Use the [govcy design system](https://gov-cy.github.io/govcy-design-system-docs/) css classes and javascript functions
12
+ - Use HTML best practices and be valid HTML
13
+ - Use accessibility best practices
14
+ - Allow multiple languages
15
+ - Be tested
16
+
17
+ The project is not intended to be used for production purposes, but your welcome to try.
18
+
19
+ The project uses [nunjucks](https://mozilla.github.io/nunjucks/) templates to built the html.
20
+
21
+ The package currently works with the **version 3.0.0** of the design system.
22
+
23
+ ## Features
24
+
25
+ The package can:
26
+ can:
27
+
28
+ - Generate HTML programmatically from [input nunjucks template](#nunjucks-template-example), using the project's base template and macros.
29
+ - Generate HTML programmatically from [input JSON](#json-template-example) data
30
+ - Generate complete pages as well as [individual components](#render-individual-components-example)
31
+
32
+ ## Pre-requisites
33
+ - You need to have [Node.js](https://nodejs.org/en/) installed. The package has been tested on node version 20.
34
+
35
+ ## Install
36
+
37
+ First, install the package using npm:
38
+
39
+ ```shell
40
+ npm install @gov-cy/govcy-frontend-renderer
41
+ ```
42
+
43
+ ## Usage
44
+ First, you need to import the package as shown in the example below.
45
+
46
+ ```js
47
+ import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
48
+ ```
49
+
50
+ The package's main functions accept an input:
51
+ - a **JSON object** with the [site and page meta data](#site-and-page-meta-data-explained)
52
+ - and a **template** which can either be a [nunjucks template](#nunjucks-template-example) or a [JSON object](#json-template-example), that define the design elements to be rendered.
53
+
54
+ 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.
55
+
56
+ The output returned is a string with the rendered HTML.
57
+
58
+ ### Nunjucks template example
59
+ Use a [string with a nunjucks template](#nunjucks-input-template) and the `renderFromString` function to render HTML from a nunjucks template. See the example below.
60
+
61
+ ```js
62
+ import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
63
+ const renderer = new govcyFrontendRenderer();
64
+
65
+ // Define the input data
66
+ const inputData =
67
+ {
68
+ "site" : {
69
+ "lang" : "en",
70
+ "title" : {"en":"Service title", "el":"Τιτλός υπηρεσίας"},
71
+ "headerTitle" : {"en":"Header title", "el":"Τιτλός επικεφαλιδας"},
72
+ "description" : {"en":"Service description", "el":"Περιγραφή υπηρεσίας"},
73
+ "url" : "https://gov.cy",
74
+ "cdn" : {
75
+ "dist" : "https://cdn.jsdelivr.net/gh/gov-cy/govcy-design-system@3.0.0/dist",
76
+ "cssIntegrity" : "sha384-1zLHWOtnS0hOIz5mVEPZp0UH5gUE6eo0CQcCGA3sF2TyYhHyKOd3Ni8Iy/NjEASU",
77
+ "jsIntegrity" : "sha384-zOuDuogVaaTveh/Ou2iYwCk14zFiSmMk7Ax8yRnXDtOJMyKZH5+ZNibNVwZSKtw+"
78
+ }
79
+ },
80
+ "pageData": {
81
+ "title": {"en": "Page title", "el": "Τιτλός σελιδας"},
82
+ "layout": "layouts/govcyBase.njk",
83
+ "mainLayout": "max-width"
84
+ }
85
+ };
86
+
87
+ // Define the template (njk)
88
+ let inputString =
89
+ `
90
+ {% if pageData.layout %} {% extends pageData.layout %} {% endif %}
91
+ {% from "govcyElement.njk" import govcyElement %}
92
+ {% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}
93
+ {% block main %}
94
+ {% call govcyElement("form",
95
+ {
96
+ elements:
97
+ [
98
+ {
99
+ element: "textInput",
100
+ params:
101
+ {
102
+ label:{en:"What is your name?",el:"Ποιο είναι το όνομα σας;"}
103
+ ,id:"name"
104
+ ,name:"name"
105
+ ,isPageHeading: true
106
+ ,autocomplete:"tel"
107
+ }
108
+ },
109
+ {
110
+ element: "button",
111
+ params: {
112
+ text:{en:"Continue",el:"Συνέχεια"}
113
+ , type:"submit"
114
+ }
115
+ }
116
+ ]
117
+ }) %}{% endcall %}
118
+
119
+ {% endblock %}
120
+ `
121
+
122
+ // Render
123
+ let rtn = renderer.renderFromString(inputString, inputData)
124
+ console.log(rtn);
125
+
126
+ ```
127
+ In the example above, a sting will be written in the console containing the rendered HTML of a complete page.
128
+
129
+ It is important to start your template string with the following:
130
+ - `{% if pageData.layout %} {% extends pageData.layout %} {% endif %}`: Will extend the gov.cy page template as defined in the `pageData.layout` property.
131
+ - `{% from "govcyElement.njk" import govcyElement %}`: Will import the `govcyElement` macro which is responsible for rendering all the [design elements](#included-design-elements).
132
+ - `{% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}`: (Optional) Will import the `govcyUtilities` macro which includes [localization](#localization) and other utilities.
133
+
134
+ To render design elements, the packages uses the `govcyElement` macro. See more details in the [design elements](DESIGN_ELEMENTS.md) section.
135
+
136
+ ### JSON template example
137
+ Use a [JSON object as the template](#json-input-template) and the `renderFromJSON` function to render HTML from a nunjucks template. See the example below.
138
+
139
+ ```js
140
+ import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
141
+ const renderer = new govcyFrontendRenderer();
142
+
143
+ // Define the input data
144
+ const inputData =
145
+ {
146
+ "site" : {
147
+ "lang" : "en",
148
+ "title" : {"en":"Service title", "el":"Τιτλός υπηρεσίας"},
149
+ "headerTitle" : {"en":"Header title", "el":"Τιτλός επικεφαλιδας"},
150
+ "description" : {"en":"Service description", "el":"Περιγραφή υπηρεσίας"},
151
+ "url" : "https://gov.cy",
152
+ "cdn" : {
153
+ "dist" : "https://cdn.jsdelivr.net/gh/gov-cy/govcy-design-system@3.0.0/dist",
154
+ "cssIntegrity" : "sha384-1zLHWOtnS0hOIz5mVEPZp0UH5gUE6eo0CQcCGA3sF2TyYhHyKOd3Ni8Iy/NjEASU",
155
+ "jsIntegrity" : "sha384-zOuDuogVaaTveh/Ou2iYwCk14zFiSmMk7Ax8yRnXDtOJMyKZH5+ZNibNVwZSKtw+"
156
+ }
157
+ },
158
+ "pageData": {
159
+ "title": {"en": "Page title", "el": "Τιτλός σελιδας"},
160
+ "layout": "layouts/govcyBase.njk",
161
+ "mainLayout": "max-width"
162
+ }
163
+ };
164
+
165
+ // Define the JSON template
166
+ let inputJson =
167
+ {
168
+ "sections": [
169
+ {
170
+ "name": "main",
171
+ "elements": [
172
+ {
173
+ "element": "form",
174
+ "params": {
175
+ "elements": [
176
+ {
177
+ "element": "textInput",
178
+ "params":
179
+ {
180
+ "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
181
+ ,"id":"name"
182
+ ,"name":"name"
183
+ ,"isPageHeading": true
184
+ ,"autocomplete":"tel"
185
+ }
186
+ },
187
+ {
188
+ "element": "button",
189
+ "params":
190
+ {
191
+ "text":{"en":"Continue","el":"Συνέχεια"}
192
+ , "type":"submit"
193
+ }
194
+ }
195
+ ]
196
+ }
197
+ }
198
+ ]
199
+ }
200
+ ]
201
+ }
202
+ ;
203
+
204
+ // Render
205
+ let rtn = renderer.renderFromJSON(inputJson, inputData)
206
+ console.log(rtn);
207
+ ```
208
+ In the example above, a sting will be written in the console containing the rendered HTML of a complete page.
209
+
210
+ More details in defining design elements see in the [design elements](DESIGN_ELEMENTS.md) section.
211
+
212
+ ### Render individual components example
213
+
214
+ 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.lang`in the *siteData* and *pageData* will be ignored.
215
+
216
+ ```js
217
+ import { govcyFrontendRenderer } from '@gov-cy/govcy-frontend-renderer';
218
+ const renderer = new govcyFrontendRenderer();
219
+
220
+ // Define the input data
221
+ const inputData =
222
+ {
223
+ "site" : {
224
+ "lang" : "en"
225
+ },
226
+ "pageData": {
227
+ "layout": "",
228
+ }
229
+ };
230
+
231
+ // Define the JSON template
232
+ let inputJson =
233
+ {
234
+ "sections": [
235
+ {
236
+ "name": "main",
237
+ "elements": [
238
+ {
239
+ "element": "form",
240
+ "params": {
241
+ "elements": [
242
+ {
243
+ "element": "textInput",
244
+ "params":
245
+ {
246
+ "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
247
+ ,"id":"name"
248
+ ,"name":"name"
249
+ ,"isPageHeading": true
250
+ ,"autocomplete":"tel"
251
+ }
252
+ },
253
+ {
254
+ "element": "button",
255
+ "params":
256
+ {
257
+ "text":{"en":"Continue","el":"Συνέχεια"}
258
+ , "type":"submit"
259
+ }
260
+ }
261
+ ]
262
+ }
263
+ }
264
+ ]
265
+ }
266
+ ]
267
+ }
268
+ ;
269
+
270
+ // Render
271
+ let rtn = renderer.renderFromJSON(inputJson, inputData)
272
+ console.log(rtn);
273
+ ```
274
+ All the `inputData` except the `site.lang` and the empty `pageData.layout` will be ignored.
275
+
276
+ ### Site and page meta data explained
277
+ 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.
278
+
279
+ The `inputData` object has the following structure:
280
+
281
+ - **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.
282
+ - **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.
283
+ - **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.
284
+ - **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.
285
+ - **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)
286
+ - **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.
287
+ - **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.
288
+ - **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.
289
+ - **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.
290
+ - **pageData.mainLayout**: the main layout of the page. It can be either `two-thirds` or `max-width`.
291
+
292
+ ### Input Template explained
293
+ 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.
294
+
295
+ #### Nunjucks input template
296
+ 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.
297
+
298
+ ```js
299
+ // Define the template (njk)
300
+ let inputString =
301
+ `
302
+ {% if pageData.layout %} {% extends pageData.layout %} {% endif %}
303
+ {% from "govcyElement.njk" import govcyElement %}
304
+ {% from "utilities/govcyUtilities.njk" import govcyLocalizeContent %}
305
+ {% block main %}
306
+ {% call govcyElement("form",
307
+ {
308
+ elements:
309
+ [
310
+ {
311
+ element: "textInput",
312
+ params:
313
+ {
314
+ label:{en:"What is your name?",el:"Ποιο είναι το όνομα σας;"}
315
+ ,id:"name"
316
+ ,name:"name"
317
+ ,isPageHeading: true
318
+ ,autocomplete:"tel"
319
+ }
320
+ },
321
+ {
322
+ element: "button",
323
+ params: {
324
+ text:{en:"Continue",el:"Συνέχεια"}
325
+ , type:"submit"
326
+ }
327
+ }
328
+ ]
329
+ }) %}{% endcall %}
330
+
331
+ {% endblock %}
332
+ `;
333
+ ```
334
+
335
+ If your using the `pageData.layout`, you can render html in each of the following [gov.cy page template](https://gov-cy.github.io/govcy-design-system-docs/getting-started/page-template/) blocks:
336
+ - **bodyStart**: the start of the body
337
+ - **header**: the header section (where the gov.cy logo and service name are rendered)
338
+ - **beforeMain**: the section before the main content
339
+ - **main**: the main content
340
+ - **footer**: the footer section
341
+ - **bodyEnd**: the end of the body
342
+
343
+ 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](DESIGN_ELEMENTS.md) section.
344
+
345
+ #### JSON input template
346
+ When using a JSON input template, there is no need to import or extend anything.
347
+
348
+ ```js
349
+ // Define the JSON template
350
+ let inputJson =
351
+ {
352
+ "sections": [
353
+ {
354
+ "name": "main",
355
+ "elements": [
356
+ {
357
+ "element": "form",
358
+ "params": {
359
+ "elements": [
360
+ {
361
+ "element": "textInput",
362
+ "params":
363
+ {
364
+ "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
365
+ ,"id":"name"
366
+ ,"name":"name"
367
+ ,"isPageHeading": true
368
+ ,"autocomplete":"tel"
369
+ }
370
+ },
371
+ {
372
+ "element": "button",
373
+ "params":
374
+ {
375
+ "text":{"en":"Continue","el":"Συνέχεια"}
376
+ , "type":"submit"
377
+ }
378
+ }
379
+ ]
380
+ }
381
+ }
382
+ ]
383
+ }
384
+ ]
385
+ }
386
+ ;
387
+
388
+ ```
389
+
390
+ If your using the `pageData.layout`, you can render html in each of the following [gov.cy page template](https://gov-cy.github.io/govcy-design-system-docs/getting-started/page-template/) blocks, by using the `sections` array (in a similar way `blocks` is use ) :
391
+ - **bodyStart**: the start of the body
392
+ - **header**: the header section (where the gov.cy logo and service name are rendered)
393
+ - **beforeMain**: the section before the main content
394
+ - **main**: the main content
395
+ - **footer**: the footer section
396
+ - **bodyEnd**: the end of the body
397
+
398
+ 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:
399
+
400
+ ```json
401
+ {
402
+ "element": "textInput",
403
+ "params":
404
+ {
405
+ "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
406
+ }
407
+ }
408
+ ```
409
+
410
+ will use the `govcyElement` macro to render the `textInput` design element as follows:
411
+
412
+ ```Nunjucks
413
+ {{
414
+ govcyElement({
415
+ "textInput",
416
+ {
417
+ "label":{"en":"What is your name?","el":"Ποιο είναι το όνομα σας;"}
418
+ }
419
+ })
420
+ }}
421
+ ```
422
+
423
+ More details in defining design elements see in the [design elements](DESIGN_ELEMENTS.md) section.
424
+
425
+ #### Included design elements
426
+ 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](DESIGN_ELEMENTS.md) document.
427
+
428
+ ### Localization
429
+ 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:
430
+
431
+ 1. if `params.lang` is defined in the design element, use that
432
+ 2. else if `site.lang` is defined in the `siteData`, use that
433
+ 3. else use `el`
434
+
435
+ If the `params.lang` is defined in the design element, the package will also render element with a `lang` attribute.
436
+
437
+ ## Change the package
438
+
439
+ Details on how to build, test and update the project can be found in the [project notes](NOTES.md) document.
440
+
441
+ ## License
442
+
443
+ The package is released under the [MIT License](https://opensource.org/licenses/MIT).
444
+
445
+ ## Contact
446
+
447
+ If you have any questions or feedback, please feel free to reach out to us at [dsf-admin@dits.dmrid.gov.cy](mailto:dsf-admin@dits.dmrid.gov.cy)