Abstractors are awesome. They provide a way to manipulate context data before rendering, such as applying markdown, or fetching external content, for example twitter post content based on id.
Let’s start with a context file like this:
{
doc: 'lets have some __bold__ text'
}
To replace the __bold__
with <strong>bold</bold>
we will create a doc.js file in /app/abstractors folder that will look like this:
var abstractor = function () {}
abstractor.prototype.init = function(context) {
return new Promise(function(resolve, reject) {
// initialize abstractor
resolve()
})
}
abstractor.prototype.abstract = function(context) {
return new Promise(function(resolve, reject) {
// will hide the generatod context from admin interface
context['$marked_doc_hidden'] = true
// will replace __strong__ to <strong>strong</strong>
context.marked_doc = context.doc.replace(/__([^*]+)__/g, '<strong>$1</strong>')
// abstract directive
return resolve()
})
}
module.exports = new abstractor()
simple enough, this will add a ready to be used marked_doc to our context like this:
{
doc: 'lets have some __bold__ text',
marked_doc: 'lets have some <strong>bold</strong> text'
}
Hint: The basename of an abstractor’s file should exactly match the name of a field you want to abstract. E.g. if you have a field called
rss_feed
and you want to process it, you will need an/app/abstractors/rss_feed.js
file.
Abstractors are used on this very page to add markdown by using marked. Apart from this I used abstractors to fetch twitter post based on id.
Pro tip: abstractors work great with arrays of objects, templatitators and deeply nested structures too without the need to change abstractor’s behaviour. So, if you want to display a series of sections with marked text in each, you can simply make an array of objects containing
doc
field each.
Every abstractor need to export two functions: init() and abstract(). Init runs only once per enduro render event, while abstract run for every key named as the abstractor.
If you want your abstracted fields to be translated too, you should expand your code to add language-specific fields in your context files. The code may look like this:
var abstractor = function () {}
abstractor.prototype.init = function(context) {
return new Promise(function(resolve, reject) {
// initialize abstractor
resolve()
})
}
abstractor.prototype.abstract = function(context) {
return new Promise(function(resolve, reject) {
// will hide the generatod context from admin interface
context['$marked_doc_hidden'] = true
// will replace __strong__ to <strong>strong</strong>
context.marked_doc = context.doc.replace(/__([^*]+)__/g, '<strong>$1</strong>')
// add support for locales
if ('$doc_de' in context) {
context.$marked_doc_de = context.$doc_de.replace(/__([^*]+)__/g, '<strong>$1</strong>')
}
// abstract directive
return resolve()
})
}
module.exports = new abstractor()