Skip to content

Commit

Permalink
Merge pull request #346 from marko-js/issue-344
Browse files Browse the repository at this point in the history
Fixes #344 - defineRenderer for marko
  • Loading branch information
patrick-steele-idem authored Aug 3, 2016
2 parents 7e76972 + 94eafb7 commit d433ac2
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 1 deletion.
48 changes: 48 additions & 0 deletions defineRenderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
var marko = require('./');
var createRenderFunc = require('raptor-renderer').createRenderFunc;

function defineRenderer(def) {
var template = def.template;
var getTemplateData = def.getTemplateData;
var renderer = def.renderer;

var loadedTemplate;


if (!renderer) {
// Create a renderer function that takes care of translating
// the input properties to a view state. Also, this renderer
// takes care of re-using existing widgets.
renderer = function renderer(input, out) {
var newProps = input;

if (!newProps) {
// Make sure we always have a non-null input object
newProps = {};
}

if (!loadedTemplate) {
// Lazily load the template on first render to avoid potential problems
// with circular dependencies
loadedTemplate = template.render ? template : marko.load(template);
}

// Use getTemplateData(state, props, out) to get the template
// data. If that method is not provided then just use the
// the state (if provided) or the input data.
var templateData = getTemplateData ?
getTemplateData(newProps, out) :
newProps;

// Render the template associated with the component using the final template
// data that we constructed
loadedTemplate.render(templateData, out);
};
}

renderer.render = createRenderFunc(renderer);

return renderer;
}

module.exports = defineRenderer;
44 changes: 43 additions & 1 deletion docs/javascript-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,46 @@ Default options:
*/
assumeUpToDate: NODE_ENV == null ? false : (NODE_ENV !== 'development' && NODE_ENV !== 'dev')
};
```
```

# require('marko/defineRenderer')

Utility module for building a UI component with both a `renderer(input, out)` (for use as a Marko custom tag renderer) a `render(input)` method (for rendering the UI component and inserting the HTML in the DOM):


_src/components/app-hello/index.js_

```javascript
var defineRenderer = require('marko/defineRenderer');

module.exports = defineRenderer({
template: require('./template.marko'),
getTemplateData: function(input) {
var firstName = input.firstName;
var lastName = input.lastName;

return {
fullName: firstName + ' ' + lastName
};
}
})
```

The UI component can be used as a custom tag:

```xml
<app-hello first-name="John" last-name="Doe" />
```

And it can also be rendered and inserted into the DOM:

```javascript
require('./src/components/app-hello')
.render({
firstName: 'John',
lastName: 'Doe'
})
.appendTo(document.body);
```

The return value of `render()` will be a [RenderResult](https://github.com/raptorjs/raptor-renderer#renderresult) instance.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"raptor-polyfill": "^1.0.0",
"raptor-promises": "^1.0.1",
"raptor-regexp": "^1.0.0",
"raptor-renderer": "^1.4.4",
"raptor-strings": "^1.0.0",
"raptor-util": "^1.0.0",
"resolve-from": "^1.0.0",
Expand Down
3 changes: 3 additions & 0 deletions test/autotests/api/defineRenderer/template.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Hello ${data.fullName}!
</div>
16 changes: 16 additions & 0 deletions test/autotests/api/defineRenderer/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
exports.check = function(marko, markoCompiler, expect, done) {

var defineRenderer = require('../../../../defineRenderer');
var renderer = defineRenderer({
template: require('./template.marko'),
getTemplateData: function(input) {
return {
fullName: input.firstName + ' ' + input.lastName
};
}
});

var renderResult = renderer.render({ firstName: 'John', lastName: 'Doe' });
expect(renderResult.html).to.equal('<div>Hello John Doe!</div>');
done();
};

0 comments on commit d433ac2

Please sign in to comment.