GitHub - w-mcilhagga/dst: dead simple templating using tagged templates in javas...
source link: https://github.com/w-mcilhagga/dst
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
dst
- dead simple templates.
dst
is a very simple very tiny template engine inspired by mustaches.js, but built on top of javascript tagged templates. Minimized, the template engine is just 1.22KB.
You can also look at some examples or try out the examples in the tryout.html page (which must be run using a local server if you download it - I'll put together an online version later.)
Usage.
Here is a quick example showing how to use dst
import {dst, item} from './path/to/dst.min.js' let a = ["Moe","Larry","Curly"], result = dst`Stooges:\n${{a}} ${item}\n${{}}`
The value of result
is:
Stooges:
Moe
Larry
Curly
A dst
template is a tagged template which understands sections, that can be included, excluded, or repeated multiple times. In the above example, the section starts with ${{a}}
and ends with ${{}}
. The start of the section is a template placeholder ${ }
containing the object literal {a}
. The end of the section is a placeholder containing an empty object {}
. When a
is an array, the inside of the section is repeated as many times as there are items in the array. Inside the section being repeated, item
refers to the current item in the loop.
dst
handles most other substitutions as if it were a normal template literal.
There are two kinds of section in dst
: boolean and array.
Boolean Sections.
A boolean section is shown or omitted depending on the value of a boolean variable. For example, the code below:
let p = false, result = dst`shown ${{p}} not shown ${{}}`
will give result
the following value:
shown
The part of the template between the start of the section ${{p}}
and the end ${{}}
is only processed and output if p
is true.
Array Sections.
When the variable in the section start is an array, the inside of the section is repeated multiple times. For example:
let a = ["Moe","Larry","Curly"], result = dst`Stooges:\n<ul>\n${{a}} <li>${item}</li>\n${{}}</ul>`
The value of result
is then
Stooges:
<ul>
<li>Moe</li>
<li>Larry</li>
<li>Curly</li>
</ul>
The start of the array section is indicated by ${{a}}
and the end of the section is indicated by ${{}}
. You can put a comment inside the end to link it visually to the start, for example ${{/*a*/}}
. The template string between the start and end is looped over as often as there are elements in a
. Within the loop section, the special object item
refers to the array element in the loop.
If the array elements are objects, then we can reference parts of those objects using item
. For example:
let a = [{name:"Moe"},{name:"Larry"},{name:"Curly"}], result = dst`Stooges:\n<ul>\n${{a}} <li>${item.name}</li>\n${{}}</ul>`
also gives:
Stooges:
<ul>
<li>Moe</li>
<li>Larry</li>
<li>Curly</li>
</ul>
Template Line Removal.
It can aid readability to put the sections and ends on lines by themselves. This would ordinarily create line breaks in the template output so to avoid this, dst
spots sections that are on lines by themselves and removes the newline. For example
result = dst`Stooges: <ul> ${{a}} <li>${item.name}</li> ${{}} </ul>`
...will produce the same output as the previous example; no extra lines are inserted where the section start ${{a}}
and end ${{}}
are in the template because they are on lines by themselves.
If you actually do want a newline next to a section start or end, you have to insert an extra new line in the template to create it.
Nested Sections.
The item
object can be used to start another section within the existing one. For example:
let a = [[1,2,3], [4,5,6], [7,8]], result = dst`${{a}} * ${{item}} element = ${item}, ${{}}\n${{}}`
gives result
the following value:
* element = 1, element = 2, element = 3,
* element = 4, element = 5, element = 6,
* element = 7, element = 8,
The first occurrence of item
is ${{item}}
which starts a new array section, since the item is an array. Within the nested ${{item}}...${{}}
section, the ${item}
causes substitution of the item value.
The nested section doesn't have to be an array. If it evaluated to a boolean value, the nested section would be included or omitted.
Functions.
A function can be used in a template substitution or to start a section. When used in a template substitution, the function is given the current array item. For example
let a = [1,2,3,4], result = dst`${{a}} ${item} squared is ${v=>v**2}\n${{}}`
gives result
the value
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
When a function is used as a section, it is called using the current array item as an argument (even if inside a boolean section), and the return value of that is used as the section value. (If there is no current array item, it is passed undefined
).
For example:
let a = [1,2,3,4], stars = v=>Array(v).fill('*'), result = dst`${{a}} ${{stars}} ${item} ${{}}\n${{}}`
gives result
the value
*
* *
* * *
* * * *
The outer section ${{a}}...${{}}
loops over a
. The inner section starts with ${{stars}}
. The function stars
is passed the current item of a
(1 or 2 or 3 or 4), and returns an array of stars. This array creates an array section which is then looped over to produce each line in the output.
Functions in a template are called with three arguments:
- the array element (i.e. the
item
). - the array index,
undefined
if in a boolean section. - the array being looped over,
undefined
if in a boolean section.
like an Array.map
callback. You can use as many or as few of these arguments as you want.
Note that
item
is actually a proxy for the identity functionv=>v
, anditem.prop
is a proxy forv=>v[prop]
.
Using ${[ ]}
instead of ${{ }}
A section is marked by a template placeholder containing an object literal. Since arrays are also objects in javascript, a section can start instead with a placeholder containing an array. This is useful if we want to use anonymous variables. For example
let result = dst`${[ [1,2,3] ]} ${item} ${{}}`
gives result
the value ' 1 2 3 '
.
This feature means you can't substitute arrays directly into dst
, since ${[1,2,3]}
is going to be interpreted as a boolean section (with a value of 1). Instead, to substitute an array, you need to make it a string by joining it, as ${[1,2,3].join(',')}
. This is what happens to arrays anyway in ordinary template literals.
Re-using Templates.
The only way to reuse a dst
template is to put it in a function. Thus:
function stooges(a) { return dst`Stooges:\n<ul>\n${{a}} <li>${item.name}</li>\n${{}}</ul>` } stooges([{name:"Moe"},{name:"Larry"},{name:"Curly"}])
Writing templates as functions lets you to insert templates within templates. If you put the function in a template substitution, it is called with the current array item or section variable.
For example
let li = value => dst`<li>${value.name}</li>`, // dst doesn't do anything special here a = [{name:"Moe"},{name:"Larry"},{name:"Curly"}], result = dst`Stooges:\n<ul>\n${{a}} ${li}\n${{}}</ul>`
does the same as before.
Unlike mustaches.js
, you can't easily define a template in a <template>
tag. Instead, you should define them in scripts or modules.
Join elements.
Sometimes you will want to run an array section where something is inserted between elements, but not after the last one. You can do this by defining a function j
which detects whether its at the end of the array, and use it to define a boolean section. The function is:
let j = (v,i,arr)=>(i<arr.length-1)
These can be used as follows:
let a = [1,2,3], result = dst`${{a}} ${item}${{j}},${{}}${{}}`
The ${{j}}
section contains a comma. When j
evaluates to true, the comma is inserted in the result, and when false (at the end of the array) the comma isn't inserted. The example gives str
the value ' 1, 2, 3'
.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK