blob: f7acc229a7ad3b7434398e4ea889cec6fc2c9147 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Note that I'm still not a JavaScript guru...but this is
// just prototype/demo code ;-)
var Handlebars = require('handlebars')
class HandlebarsRenderer {
constructor(templateSrc) {
this.template = Handlebars.compile(templateSrc);
}
render(content) {
return this.template(content)
}
}
var renderers = {}
var JUST_RECURSE_RENDERER = new HandlebarsRenderer('\
{{#each this}}\
<div class="nested">\
{{{renderObject this}}}\
</div>\n\
{{/each}}\
')
var DEFAULT_RENDERER = new HandlebarsRenderer('\
<em>Default renderer for resourceType <b>{{sling:resourceType}}</b></em><br>\n\
{{#each this}}\
<div class="nested">\
{{{renderObject this}}}\
</div>\n\
{{/each}}\
')
renderers["samples/article"] = new HandlebarsRenderer('\
<h3>Articles renderer</h3>\
<h4>{{title}}</h4>\
<div><b>tags</b>:{{tags}}</div>\
<blockquote>{{{text}}}</blockquote>\
')
renderers["samples/section"] = new HandlebarsRenderer('\
<h3>Articles section renderer</h3>\
This is the <b>{{name}}</b> section.\
')
class WkndPageRenderer extends HandlebarsRenderer {
constructor(templateSrc) {
super(templateSrc)
}
collectResourceTypes(resource, targetSet) {
for(const key in resource) {
const prop = resource[key]
if("sling:resourceType" == key) {
targetSet.add(`${prop} ${renderers[prop] ? " (renderer provided)": ""}`)
} else if(typeof prop == "object") {
this.collectResourceTypes(prop, targetSet)
}
}
}
render(content) {
content.rendererInfo = { resourceTypes:new Set() }
content.omitdefaultRendering = true
this.collectResourceTypes(content, content.rendererInfo.resourceTypes)
return super.render(content)
}
}
renderers["wknd/components/page"] = new WkndPageRenderer('\
<h3>WKND page renderer</h3>\n\
<div>tags: {{jcr:content.cq:tags}}</div>\n\
<h4>We need renderers for the following resource types, found in the page content:</h4>\n\
<ul>\n\
{{#each rendererInfo.resourceTypes}}\n\
<li>{{this}}</li>\n\
{{/each}}\
</ul>\n\
\
{{#each this}}\
<div class="nested">\
{{{renderObject this}}}\
</div>\n\
{{/each}}\
\
');
renderers["wknd/components/image"] = new HandlebarsRenderer('\
The image from <b>{{fileReference}}</b> comes here\n\
')
renderers["wknd/components/contentfragment"] = new HandlebarsRenderer('\
Content Fragment <b>{{fragmentPath}}</b> comes here\n\
{{#if text}}\n\
<blockquote>{{text}}</blockquote></div>\n\
{{/if}}\n\
')
renderers["wknd/components/image-list"] = new HandlebarsRenderer('\
Image list with tags <b>{{tags}}</b>\
')
class NamedComponentRenderer extends HandlebarsRenderer {
constructor(name) {
super(`\
Rendering a <b>${name}</b> component\
{{#each this}}\
<div class="nested">\
{{{renderObject this}}}\
</div>\n\
{{/each}}\
`)
}
}
[
"wknd/components/breadcrumb",
].forEach(rt => renderers[rt] = JUST_RECURSE_RENDERER);
[
"wknd/components/container",
"wknd/components/grid",
"wknd/components/tabs",
].forEach(rt => renderers[rt] = new NamedComponentRenderer(rt));
function renderObject(content) {
if(typeof content != "object") {
return
}
var renderer = renderers[getResourceType(content, false)]
if(!renderer) {
renderer = renderers[getResourceType(content, true)]
}
if(!renderer) {
if(content["jcr:content"]) {
renderer = JUST_RECURSE_RENDERER
} else if(!getResourceType(content, false) && !getResourceType(content, true)) {
renderer = JUST_RECURSE_RENDERER
} else {
renderer = DEFAULT_RENDERER
}
}
return renderer.render(content)
}
Handlebars.registerHelper("renderObject", renderObject)
function getResourceType(content, supertype) {
var result = null;
var key = supertype ? "sling:resourceSuperType" : "sling:resourceType"
result = content[key]
return result;
}
class ContentRenderer {
info() {
return `The ContentRenderer only supports a limited set of sling:resourceType values: ${Object.keys(renderers)}`
}
render(content) {
return renderObject(content)
}
}
module.exports = ContentRenderer;