Skip to content
TaskeHAMANO edited this page Dec 9, 2015 · 16 revisions

togostanza コマンド

togostanza gem に含まれる togostanza コマンドは、スタンザプロバイダやスタンザの雛形を生成する機能を持ちます。

togostanza init <name>

新しいスタンザプロバイダを作成します。<name> は生成するディレクトリ名です。ディレクトリとして利用可能な文字なら何でも使えますし、後からリネームしても特に問題はありません。

togostanza name <name>

スタンザ作成者の名前をスタンザ作成に用いられるtemplateへ登録します。<name>はtogostanza gemユーザーの名前です。登録すると、それ以降に作成されたスタンザのmetadata.json<stanza name>.gemspec中のauthorがその通りに記述されるようになります。

togostanza mail <address>

スタンザ作成者のメールアドレスをスタンザ作成に用いられるtemplateへ登録します。<address>はtogostanza gemユーザーのメールアドレスです。登録すると、それ以降に作成されたスタンザのmetadata.json<stanza name>.gemspec中のemailがその通りに記述されるようになります。

togostanza stanza new <name>

新しいスタンザを作成します。このコマンドはスタンザプロバイダのディレクトリ内で実行してください。<name> はディレクトリ名やクラス名、スタンザの URL に使われます。英数字とアンダースコアが使えますが、一文字目はアルファベットにしてください。

togostanza stanza remove <name>

スタンザプロバイダにあるスタンザを削除します。このコマンドはスタンザプロバイダのディレクトリ内で実行してください。<name>にはスタンザのディレクトリ名を指定してください。実行後、確認メッセージが表示されるます。[y] or [yes]を入力すれば削除が実行されます。同時にプロバイダのGemfileからそのスタンザの記述が設定が削除されます。

togostanza stanza modify <old_name> <new_name>

スタンザプロバイダにあるスタンザの名称を変更します。このコマンドはスタンザプロバイダのディレクトリ内で実行してください。各<name>にはスタンザのディレクトリ名を指定してください。assets以下で使用されている外部ファイルに対しては名称変更が働かないことに気をつけてください。

スタンザのファイル構成

スタンザは以下のようなファイルから構成されます。

foo_stanza
├── Gemfile
├── assets
├── sparql
├── foo_stanza.gemspec
├── metadata.json
├── lib
│   └── foo_stanza.rb
├── stanza.rb
└── template.hbs
名前 説明
stanza.rb スタンザの本体となるファイルで、データのセットアップなどを記述します。詳細は後述します。
template.hbs stanza.rb でセットアップしたデータを表示するテンプレートです。詳細は後述します。
assets 静的なファイル (画像など) を配置するディレクトリです。詳細は後述します。
metadata.json スタンザに関するメタ情報を記述します。詳細は後述します。
sparql hbs形式で書かれたSPARQLクエリを配置することが出来るディレクトリです。詳細は後述します。
foo_stanza.gemspec スタンザを gem として配布するための定義ファイルです。スタンザの配布にて説明します。
Gemfile このスタンザが使用する Ruby ライブラリの依存関係を記述します。通常は変更の必要はありません。
lib/foo_stanza.rb スタンザの初期化処理を行うファイルです。編集しないでください。
sparql 再利用を考えてhbs形式で書かれたSPARQLクエリを配置することが出来るディレクトリです。詳細は後述します。

スタンザ本体

stanza.rb がスタンザの本体です。スタンザは Ruby のクラスとして表わされます。

class FooStanza < TogoStanza::Stanza::Base
  property :greeting do
    'hello, world!'
  end
end

スタンザ内では propertyresource など、いくつかのメソッドを使ってスタンザの振る舞いを記述します。

property

プロパティ (テンプレートに受け渡すデータ) を定義するメソッドです。

property :foo do
  'bar'
end

property メソッドは第1引数にプロパティ名、ブロック (do ... end の部分) にプロパティの値を求める処理を記述します。上記の例では foo という名前で値が 'bar' という文字列のプロパティを定義しています。

property のブロック内には単純な値だけでなく、任意の Ruby のコードを記述できます。最後に評価した式がそのプロパティの値となります。

# 配列を返すプロパティ
property :foo do
  [1, 2, 3]
end

# 数値計算の結果を返すプロパティ
property :bar do
  10 * 2 #=> 20
end

# 変数を使い、文字列を連結した結果を返すプロパティ
property :baz do
  a = 'foo'
  a + 'bar' #=> 'foobar'
end

ブロックの途中で処理を終了して値を返したい場合は break <式> を用います。return ではないことに注意してください。

property :foo do
  a = 10
  break a
  a + 10  # この行は実行されない
end

パラメータ

プロパティの値を求める際に、スタンザに渡されたパラメータを読み出して property メソッド内で使用することができます。

property :taxonomies do |tax_id|
  query('http://dev.togogenome.org/sparql-test', <<-SPARQL.strip_heredoc)
    SELECT ?uri ?name
    FROM <http://togogenome.org/graph/taxonomy>
    WHERE {
      ?uri rdfs:label ?name .
      FILTER(?uri = 'http://identifiers.org/taxonomy/#{tax_id}')
    } LIMIT 10
  SPARQL
end

この例では、tax_id というパラメータを SPARQL クエリの FILTER 関数の条件に使用しています。文字列中に #{...} で囲ってパラメータ名を記述すると、値がその箇所に展開されます。

テンプレート

テンプレートは Handlebars という言語で記述します。 基本的に普通の HTML ですが、スタンザ本体で定義したプロパティを表示結果に埋め込むことができます。

プロパティはテンプレート内で {{foo}} のようにして読み出せます。

また、{{#each <name>}}...{{/each}} で指定した配列の各要素に対して繰り返すことができます。 この中で Hash のキー名 {{<key>}} の形式で指定することで Hash の値を呼び出せます。

例として、Taxonomy 一覧のプロパティ taxonomies をテーブルとして表示したい場合には以下のようになります。

<table class='table'>
  <thead>
    <tr>
      <th>Taxonomy URI</th>
      <th>Taxonomy name</th>
    </tr>
  </thead>
  <tbody>
    {{#each taxonomies}}
      <tr>
        <td>{{uri}}</td>
        <td>{{name}}</td>
      </tr>
    {{/each}}
  </tbody>
</table>

query

query メソッドは指定された SPARQL エンドポイントに対して問い合わせを行うメソッドです。第1引数にエンドポイントURL、第二引数に SPARQLクエリを指定します。

ヒアドキュメントを使用する例

property :taxonomies do
  query('http://dev.togogenome.org/sparql-test', <<-SPARQL.strip_heredoc)
    SELECT ?uri ?name
    FROM <http://togogenome.org/graph/taxonomy>
    WHERE {
      ?uri rdfs:label ?name .
    } LIMIT 10
  SPARQL
end

foo_stanza/sparqlへ置いたクエリを使用する例(Ver. 2.0.0以降)

生成した各スタンザディレクトリに出来るsparqlディレクトリにhbs形式でSPARQLクエリを置くことで、クエリの再利用性を担保することが出来ます。 上述したクエリをfoo_stanza/sparql/taxonomy_label.hbsへ配置した後にクエリの名称を第二引数に渡します。

property :taxonomies do
  query('http://dev.togogenome.org/sparql-test', taxonomy_label.hbs)
end

この例では http://dev.togogenome.org/sparql-test に対し、生物種の一覧から URI と名前を10件を問い合わせています。

query メソッドの返り値は以下のような Hash の配列になります。

[
  {uri: "http://identifiers.org/taxonomy/1012520", name: "bacterium enrichment culture clone ALO1_GLFRUDD03FU55T"},
  {uri: "http://identifiers.org/taxonomy/1012521", name: "bacterium enrichment culture clone ALO1_GLFRUDD03FU5U4"},
  {uri: "http://identifiers.org/taxonomy/1012522", name: "bacterium enrichment culture clone ALO1_GLFRUDD03FU5UV"},
  ...
]

配列の要素となっている個々の Hash が問い合わせ結果の1件に相当します。Hash には SPARQL のバインディングが格納されます。

このままの形式ではテンプレートで扱いづらい場合、加工した結果をプロパティの値とすることができます。例として、前述の生物種の一覧から Taxonomy ID のみを取り出して配列にしてみましょう。

property :taxonomies do
  # (1)
  taxonomies = query('http://dev.togogenome.org/sparql-test', <<-SPARQL.strip_heredoc)
    SELECT ?uri ?name
    FROM <http://togogenome.org/graph/taxonomy>
    WHERE {
      ?uri rdfs:label ?name .
    } LIMIT 10
  SPARQL

  taxonomies.map {|taxonomy| # (2)
    uri = taxonomy[:uri]     # (3)
    uri.split('/').last      # (4)
  } #=> ['1012520', '1012521', '1012522', ...]
end

ここで使用している map メソッドは配列の各要素に対して処理を繰り返し、その結果からなる新しい配列を返します。

この例では query の実行結果として得られた Hash の配列を taxonomies という変数に代入し (1)、個々の Hash を taxonomy という変数に入れて処理を実行します (2)。Hash から uri というキーでバインディングを取り出し (3)、それを / で分割して最後の要素を取り出す (4) ことで Taxonomy ID の配列を生成しています。

Ruby には map 以外にも配列を操作するための様々なメソッドがあります。詳細はリファレンスマニュアルを参照してください。

grouping

grouping メソッドは Hash の配列を指定されたキーで集約した結果を返します。

property :foo do
  ary = [
    {x: 1, y: 3},
    {x: 1, y: 4},
    {x: 2, y: 5},
    {x: 2, y: 6}
  ]

  grouping(ary, :x, :y)
  #=> [
  #     {x: 1, y: [3, 4]},
  #     {x: 2, y: [5, 6]}
  #   ]
end

第1引数は Hash の配列、第2引数以降には集約するキーを指定します。この例では配列 ary を、キー x の値が同じものについて y の値を集約しています。

キーの配列を指定することで、複数のキーの組み合わせについて集約することもできます。

property :foo do
  ary = [
    {x: 1, y: 1, z: 3},
    {x: 1, y: 2, z: 4},
    {x: 2, y: 1, z: 5},
    {x: 2, y: 2, z: 6},
    {x: 1, y: 2, z: 7},
    {x: 2, y: 1, z: 8}
  ]

  grouping(ary, [:x, :y], :z)
  #=> [
  #     {[:x, :y] => [1, 1], :z => [3]},
  #     {[:x, :y] => [1, 2], :z => [4, 7]},
  #     {[:x, :y] => [2, 1], :z => [5, 8]},
  #     {[:x, :y] => [2, 2], :z => [6]}]
  #   ]
end

複数キーで集約した場合、集約結果の Hash のキーが配列となるため、そのままではテンプレートからキーを指定することができません。この問題はキーに別名を付けることで回避できます。

property :foo do
  ary = [
    {x: 1, y: 1, z: 3},
    {x: 1, y: 2, z: 4},
    {x: 2, y: 1, z: 5},
    {x: 2, y: 2, z: 6},
    {x: 1, y: 2, z: 7},
    {x: 2, y: 1, z: 8}
  ]

  grouping(ary, {[:x, :y] => :x_y}, :z)
  #=> [
  #     {:x_y => [1, 1], :z => [3]},
  #     {:x_y => [1, 2], :z => [4, 7]},
  #     {:x_y => [2, 1], :z => [5, 8]},
  #     {:x_y => [2, 2], :z => [6]}]
  #   ]
end

grouping メソッドは query の問い合わせ結果をテンプレートで扱いやすい形に変形したいときに便利です。

resource

resource メソッドを使うとスタンザに含まれる JavaScript からアクセスできる JSON API を定義できます。この API をリソースと呼びます。

resource :foo do
  {hello: 'world'}
end

リソースには /stanza/<スタンザ名>/resources/<リソース名> という URL でアクセスできます。リソースはプロパティと同様、パラメータや querygrouping が使えます。

リソースを使うことでユーザの操作に応じて動的にデータを取得するようなスタンザを実現できます。

アセット (asset)

画像や JavaScript、CSS などの静的なファイルのことをアセットと呼びます。

アセットを使うには、スタンザディレクトリの assets/<スタンザ名> の中にファイルを配置してください。さらにサブディレクトリを切っても構いません。ここに配置したファイルは /stanza/assets/<スタンザ名>/<ファイル名> という URL でアクセスできます。

ヘルプドキュメント

metadata.jsonに各スタンザのメタデータをJSON形式で記述すると、それを参考にしてhelpページを作成します。Javascript版 Togostanzaのドキュメントも参考にしてください。こちらはLD-JSONの形式ではありません。

{
  "id": "<stanza_id>",
  "label": "<stanza_title>",
  "definition": "<stanza_definition>",
  "parameter": [
    {
      "key" : "<stanza_param_name>",
      "example" : "<stanza_param_example>",
      "description" : "<stanza_param_desc>",
      "required" : true
    }
  ],
  "type": "Stanza",
  "context": "",
  "display": "",
  "provider": "<provider of this stanza>",
  "license": "(e.g. CC-BY)",
  "author": "<author name>",
  "address": "<[email protected]>",
  "version": "<version>",
  "created": "<date_created>",
  "updated": "<date_updated>"
}

togostanza gem のアップデート

togostanza gem は時々機能追加やバグ修正が行われます。新しいバージョンをインストールするには、スタンザプロバイダのディレクトリで次のコマンドを実行してください:

$ bundle update togostanza

次に生成されたファイルを更新します。スタンザプロバイダの 一つ上 のディレクトリで togostanza init <プロバイダ名> を実行します:

$ togostanza init my_provider

既存のファイルに変更があった場合、上書きするかどうか聞かれます。d (diff) で変更内容を確認し、上書きの必要があれば y (yes) で上書きしてください。上書きの必要がなければ n (no) でスキップします。

$ togostanza init my_provider
      create  my_provider/.gitignore
    conflict  my_provider/Gemfile
Overwrite /home/ursm/my_provider/Gemfile? (enter "h" for help) [Ynaqdh] n
        skip  my_provider/Gemfile
   identical  my_provider/config.ru
   identical  my_provider/Procfile
   identical  my_provider/config/unicorn.rb
   identical  my_provider/log/.keep
         run  bundle from "./my_provider"
(snip)

続けてスタンザのファイルも更新します。スタンザプロバイダのディレクトリで togostanza stanza new <スタンザ名> を実行します。同様に、必要に応じてファイルを上書きしてください。

$ cd my_provider
$ togostanza stanza new my_awesome_stanza
   identical  my_awesome_stanza/Gemfile
   identical  my_awesome_stanza/my_awesome_stanza.gemspec
   identical  my_awesome_stanza/lib/my_awesome_stanza.rb
   identical  my_awesome_stanza/stanza.rb
   identical  my_awesome_stanza/template.hbs
   identical  my_awesome_stanza/metadata.json
   identical  my_awesome_stanza/assets/my_awesome/.keep
      append  Gemfile