Download the latest binary release of ts
from /~https://github.com/togostanza/ts/releases.
Extract the archive and put ts
binary into the directory that is in your PATH
.
Crete a directory for a stanza provider. In this example, we'll be creating a directory named my_provider.
$ mkdir my_provider
Navigete to the my_provider directory and generate a new stanza named hello.
$ cd my_provider
$ ts new hello
Run ts server
in the my_provider directory.
This builds stanzas into dist
directory and serve the files.
$ ts server
Then, open http://localhost:8080/stanza/ with your web browser.
You will see the list of stanza names currently available (only the hello
stanza will be shown at this moment).
Each name is linked to the corresponding help page.
Click the "help" link of hello
stanza.
The description of hello
stanza will appear.
In the "Sample" section, you can see the stanza working and saying "hello, world!".
Let's move on the internal of the stanza.
Doing ts new hello
has generated the following.
.
└── hello
├── index.js
├── metadata.json
└── templates
└── stanza.html
Look into hello/index.js
.
// hello/index.js
Stanza(function(stanza, params) {
stanza.render({
template: "stanza.html",
parameters: {
greeting: "Hello, world!"
}
});
});
This defines the behavior of the stanza.
When the stanza is embedded, this function is called.
Calling stanza.render
renders the stanza, using stanza.html
template with parameters
.
In this example, we passed "Hello, world!"
as greeting
.
This enables us to use the greeting
in the stanza.html
.
Look into the template:
<!-- hello/templates/stanza.html -->
<p>{{greeting}}</p>
Templates are written in Handlebars.
With {{}}
notation, we can embed any values passed via render()
function as parameters
.
metadata.json
describes the stanza itself.
Here is metadata.json
generated by ts new hello
:
{
"@context": {
"stanza": "http://togostanza.org/resource/stanza#"
},
"@id": "hello",
"stanza:label": "Hello Example",
"stanza:definition": "Greeting.",
"stanza:parameter": [
],
"stanza:usage": "<togostanza-hello></togostanza-hello>",
"stanza:type": "Stanza",
"stanza:context": "",
"stanza:display": "",
"stanza:provider": "provider of this stanza",
"stanza:license": "",
"stanza:author": "author name",
"stanza:address": "name@example.org",
"stanza:contributor": [
],
"stanza:created": "2015-02-19",
"stanza:updated": "2015-02-19"
}
The "help" page that you have seen was generated from this information.
The page should be available at http://localhost:8080/stanza/hello/help.html if ts server
is still working.
Let's try to add a parameter name
to the stanza and revise the stanza to greet to the person.
Add a parameter definition into stanza:parameter
in metadata.json
. Also update stanza:example
to use the parameter. Note that we need escape "
of example HTML snippet as \"
in the JSON.
Differences are:
- "stanza:parameter": [
- ],
+ "stanza:parameter": [
+ {
+ "stanza:key": "name",
+ "stanza:example": "Stanza Togo",
+ "stanza:description": "name to greet",
+ "stanza:required": true
+ }
+ ],
- "stanza:usage": "<togostanza-hello></togostanza-hello>",
+ "stanza:usage": "<togostanza-hello name=\"Stanza Togo\"></togostanza-hello>",
Overall metadata.json
becomes:
{
"@context": {
"stanza": "http://togostanza.org/resource/stanza#"
},
"@id": "hello",
"stanza:label": "Hello Example",
"stanza:definition": "Greeting.",
"stanza:parameter": [
{
"stanza:key": "name",
"stanza:example": "Stanza Togo",
"stanza:description": "name to greet",
"stanza:required": true
}
],
"stanza:usage": "<togostanza-hello name=\"Stanza Togo\"></togostanza-hello>",
"stanza:type": "Stanza",
"stanza:context": "",
"stanza:display": "",
"stanza:provider": "provider of this stanza",
"stanza:license": "",
"stanza:author": "author name",
"stanza:address": "name@example.org",
"stanza:contributor": [
],
"stanza:created": "2015-02-19",
"stanza:updated": "2015-02-19"
}
Reload "help" page http://localhost:8080/stanza/hello/help.html. It rebuilds the stanza. You will notice that
- Parameter
name
's definition is added in "Parameters" section - Attribute
name="Stanza Togo"
is added totogostanza-hello
in "Usage" section - Nothing is changed in "Sample" section; still saying "Hello, world!" (because we haven't written the code to use the parameter)
The parameter passed to the stanza is accessible via params
argument. Use this to greet the person:
// hello/index.js
Stanza(function(stanza, params) {
stanza.render({
template: "stanza.html",
parameters: {
greeting: "Hello, " + params.name + "!"
}
});
});
Then, reload http://localhost:8080/stanza/hello/help.html. Now you will see "Hello, Stanza Togo!" in "Sample" section. The stanza greets to "Stanza Togo", who is specified by name
attribute in stanza:example
in metadata.json
.
As an alternative way, you can generate the greeting message in stanza.html
template.
For the sake of simplicity, let us pass params
directly into the template:
// hello/index.js
Stanza(function(stanza, params) {
stanza.render({
template: "stanza.html",
parameters: params
});
});
And build the greeting message in the template:
<!-- hello/templates/stanza.html -->
<p>Hello, {{name}}!</p>
This stanza produces the same output as the previous version.
As for a more practical example, let's build a stanza to show organism name related to the specified tax_id. This is done by extracting information from an RDF store. We can use stanza.query()
for this purpose in index.js
.
Generate another stanza for this example.
$ ts new organism-name
Add tax_id
parameter to stanza:parameter
and update stanza:usage
to use the parameter in metadata.json
:
{
"@context": {
"stanza": "http://togostanza.org/resource/stanza#"
},
"@id": "organism-name",
"stanza:label": "Hello Example",
"stanza:definition": "Greeting.",
"stanza:parameter": [
{
"stanza:key": "tax_id",
"stanza:example": "1148",
"stanza:description": "NCBI taxonomy identifier.",
"stanza:required": true
}
],
"stanza:usage": "<togostanza-organism-name tax_id=\"1148\"></togostanza-organism-name>",
"stanza:type": "Stanza",
"stanza:context": "",
"stanza:display": "",
"stanza:provider": "provider of this stanza",
"stanza:license": "",
"stanza:author": "author name",
"stanza:address": "name@example.org",
"stanza:contributor": [
],
"stanza:created": "2016-02-11",
"stanza:updated": "2016-02-11"
}
Add a query template. Query templates are written in Handlebars as view templates.
Put the following as organism-name/templates/stanza.rq
:
# organism-name/templates/stanza.rq
PREFIX id-tax:<http://identifiers.org/taxonomy/>
PREFIX ddbj-tax:<http://ddbj.nig.ac.jp/ontologies/taxonomy/>
SELECT ?scientific_name ?rank_name
WHERE {
id-tax:{{tax_id}} ddbj-tax:scientificName ?scientific_name ;
ddbj-tax:rank ?rank .
?rank rdfs:label ?rank_name .
}
Here, we have used {{tax_id}}
to interpolate tax_id
parameter.
Now we are ready to issue the query. Write index.js
as follows:
// organism-name/index.js
Stanza(function(stanza, params) {
var q = stanza.query({
endpoint: "http://togogenome.org/sparql-test",
template: "stanza.rq",
parameters: params
});
q.then(function(data) {
var rows = data.results.bindings;
stanza.render({
template: "stanza.html",
parameters: {
organism: rows
},
});
});
});
The function issues a SPARQL query to the specified endpoint
. The query is built from stanza.rq
template and params
object. The parameters given to the togostanza-organism-name
stanza, are directly passed into the query template because here we pass params
as parameters
of query
.
After the results are returned from the endpoint, the callback function of q.then()
is called with the results. The data
is an object that is returned from SPARQL endpoint such as:
{
"head": {
"link": [],
"vars": [
"scientific_name",
"rank_name"
]
},
"results": {
"distinct": false,
"ordered": true,
"bindings": [
{
"scientific_name": {
"type": "literal",
"value": "Synechocystis sp. PCC 6803"
},
"rank_name": {
"type": "literal",
"value": "species"
}
}
]
}
}
We extract rows
from data
first, then call stanza.render()
, in order to render the result. rows
are passed via parameters
as organism
. rows
corresponding to the above example of data
, accessible as organism
in the template, are:
[
{
"scientific_name": {
"type": "literal",
"value": "Synechocystis sp. PCC 6803"
},
"rank_name": {
"type": "literal",
"value": "species"
}
}
]
The last part is the view template:
<!-- organism-name/templates/stanza.html -->
{{#each organism}}
<dl>
<dt>Scientific Name</dt><dd>{{scientific_name.value}}</dd>
<dt>Rank</dt><dd>{{rank_name.value}}</dd>
</dl>
{{/each}}
It receives organism
from index.js
.
Note that we have used {{#each <name>}}...{{/each}}
in order to iterate over organism
.
See details in Handlebars.
Everything is now set up. Open http://localhost:8080/stanza/organism-name/help.html with your browser. You will see that your stanza renders the result retrieved from the RDF store.