UNPKG

5.59 kBMarkdownView Raw
1# periodicjs.core.responder
2[![Build Status](https://travis-ci.org/typesettin/periodicjs.core.responder.svg?branch=master)](https://travis-ci.org/typesettin/periodicjs.core.responder) [![NPM version](https://badge.fury.io/js/periodicjs.core.responder.svg)](http://badge.fury.io/js/periodicjs.core.responder) [![Coverage Status](https://coveralls.io/repos/github/typesettin/periodicjs.core.responder/badge.svg?branch=master)](https://coveralls.io/github/typesettin/periodicjs.core.responder?branch=master) [![Join the chat at https://gitter.im/typesettin/periodicjs.core.data](https://badges.gitter.im/typesettin/periodicjs.core.responder.svg)](https://gitter.im/typesettin/periodicjs.core.responder?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
4
5### Description
6Core responder is a component of periodicjs.core.controller that provides adapters for different formatting responses across different content types. Each adapter may have options specific to the content type, but after being constructed the same methods are exposed. Depending on content type adapters do everything from wrapping JSON data in a standard way to rendering HTML from templates.
7
8### [Full Documentation](https://github.com/typesettin/periodicjs.core.responder/blob/master/doc/api.md)
9
10### Usage (basic)
11```javascript
12const AdapterInterface = require('periodicjs.core.responder');
13var adapter = AdapterInterface.create({ adapter: 'json' });
14//Basic usage (JSON)
15//With no callback param returns a Promise
16adapter.render({ foo: 'bar' })
17 .then(result => {
18 /*
19 {
20 "result": "success",
21 "status": 200,
22 "data": {
23 "foo": "bar"
24 }
25 }
26 */
27 });
28//With a callback param
29adapter.render({ foo: 'bar' }, (err, result) => {
30 /*
31 {
32 "result": "success",
33 "status": 200,
34 "data": {
35 "foo": "bar"
36 }
37 }
38 */
39});
40//Second param can also be configurable options sync: true will handle operation synchronously
41let result = adapter.render({ foo: 'bar' }, { sync: true });
42/*
43 {
44 "result": "success",
45 "status": 200,
46 "data": {
47 "foo": "bar"
48 }
49 }
50*/
51//Formatting can also be customized
52let result = adapter.render({ foo: 'bar' }, {
53 formatRender: function (data, options) {
54 return {
55 custom: 'field',
56 data
57 };
58 }
59});
60/*
61 {
62 "custom": "field",
63 "data": {
64 "foo": "bar"
65 }
66 }
67*/
68//Basic usage (XML)
69adapter = AdapterInterface.create({ adapter: 'xml', xml_root: 'example' });
70adapter.render({ foo: 'bar' })
71 .then(result => {
72 /*
73 <?xml version="1.0">
74 <example>
75 <foo>bar</foo>
76 </example>
77 */
78 });
79//configuration for XML rendering can also be passed
80adapter.render({ foo: 'bar' }, {
81 declaration: { encoding: 'UTF-8' }
82}, (err, result) => {
83 /*
84 <?xml version="1.0" encoding="UTF=8">
85 <example>
86 <foo>bar</foo>
87 </example>
88 */
89});
90//Basic usage (HTML)
91//Since template rendering is inherently async the sync option is ignored
92adapter = AdapterInterface.create({ adapter: 'html', viewname: 'user.ejs' });
93//By default HTML adapter renders EJS templates
94adapter.render({ user: 'Jim' })
95 .then(result => {
96 //Hello <%- user %>! => Hello Jim!
97 });
98//Custom template engines can also be used as long as they expose a .render method
99adapter = AdapterInterface.create({ adapter: 'html', viewname: 'user.pug', engine: require('pug') });
100adapter.render({ user: 'Jim' })
101 .then(result => {
102 //Hello ${user}! => Hello Jim!
103 });
104```
105### Usage (HTML Adapter Advanced)
106```javascript
107const AdapterInterface = require('periodicjs.core.responder');
108const mustache = require('mustache');
109const path = require('path');
110//Because the adapter uses the .render method of the template engine you can overwite this .render method to further customize behavior
111var render = mustache.render.bind(mustache);
112mustache.render = function (template, data, options) {
113 mustache.parse(template);
114 return render(template, data, options);
115};
116const adapter = AdapterInteraface.create({ adapter: 'html', engine: mustache, viewname: 'user.mustache' });
117//You can customize which directories .render will search for the template by passing .dirname. This also optimizes .render because custom directories are searched ahead of the theme/extension directories
118adapter.render({ user: 'Jim' }, { dirname: '/some/path/to/dir' })
119 .then(result => {
120 //Hello {{ user }}! => Hello Jim!
121 });
122
123```
124### Usage (with custom adapter)
125```javascript
126const AdapterInterface = require('periodicjs.core.responder');
127const template = function (data) {
128 return `Hello ${ data }!`;
129};
130const CustomAdapter = class {
131 constructor (options) {
132 ...
133 },
134 render (data, options) {
135 return template(data);
136 },
137 error (err, options) {
138 return `There was an error: ${ err.message } :(`;
139 }
140};
141var adapter = AdapterInterface.create({ adapter: CustomAdapter });
142adapter.render('Jim'); //Hello Jim!
143```
144
145### Development
146*Make sure you have grunt installed*
147```sh
148$ npm install -g grunt-cli jsdoc-to-markdown
149```
150
151For generating documentation
152```sh
153$ grunt doc
154$ jsdoc2md adapters/**/*.js index.js > doc/api.md
155```
156### Notes
157* Check out [https://github.com/typesettin/periodicjs](https://github.com/typesettin/periodicjs) for the full Periodic Documentation
158
159### Testing
160```sh
161$ npm i
162$ grunt test
163```
164### Contributing
165License
166----
167
168MIT