ご存じのように、当社は最近、Polymerで構築した新しいウェブUIの最初のプレビューをリリースしました。その構築には、当社アプリケーションの出発点としてPolymer Starter Kitを使用しました。現在このキットは、アプリケーションでルーティングを処理するために、最近のルーティング要素(app-routeapp-location)を使用していますが、当初はその作業をpage.jsにデリゲートしていました。これは現在でも当社アプリケーションで使用するソリューションです。

Nuxeo Platformのような大規模なコンテンツリッチプラットフォームの構築とは、ウェブアプリケーションを使用する際に使い勝手をよくする適切な操作に従うことを意味します。今回はURLの作成に焦点を合わせます。

URLは、アプリケーションでナビゲートする際に重要な役割を果たします。URLによって、特定のページにすぐにナビゲートしたり、同僚と共有したりすることができ、参照用のブックマークとして保存することもできます。ウェブアプリケーションでリンクを貼ることは通常、非常に簡単です。「」タグを追加するだけでよく、すぐに使用できます。

</a> [ホーム](/home)

しかし、一般的にPolymerおよびWebコンポーネントを扱っていることと、それらが関心事のカプセル化、組成、分離を提供するように設計されていることを忘れてはなりません。さらに、各要素は、独自のルーティングアプローチで、または実際のリンクを必要とすることなく、全く異なるアプリやコンテキストで使用することがあります。

大規模なアプリケーションで他に考えられる問題は、異なる場所に分散するハードコードされたリンクが多すぎて、メンテナンスやリファクタリングの場合に煩わしいことになる、という点です。

このことに留意して、該当の機能に所定のルートのURLの作成方法を確認する能力を与える必要があります。このプロセスは、リバースルーティングとして知られています。

##ソリューション
コードに取り組む前に、このソリューションが、特定のクライアントルーティングライブラリに依存しないことに注意することが重要です。当社のサンプルでは、page.jsが当社が現在使用しているライブラリなので、このライブラリを使用することになります。

当社アプリケーション用のサンプルルートの定義から始めましょう。

 page('/home', function() {
   // home page route
 });

 page('/document/:id, function() {
   // route for a specific document
 });

 page('/admin/user-group-management/:type/:id, function() {
   // route to manage a user or a group
 });

お分かりのように、page.jsでルートを作成することはとても簡単です。ルータによって処理されるパス、また必要に応じてどんなことでも実行するコールバック関数を指定するだけてよいのです。 - 他には何も必要ありません。これでルートが得られましたので、ページにリンクを作成する適切なhref属性をもつ要素に「」タグを追加するだけでよいのです。しかし、ホームルートはアプリケーションで1、2回程度使用されることがありますが、文書やユーザ/グループのURLは、異なる要素(リスティング、検索など)で何度も現れます。これは、当社のソリューションが役立つところです。

当社は、「Nuxeo.RoutingBehavior」と呼ばれるPolymer動作を導入しました。これは、所定のルート用のURLの作成に使用する「urlFor」という関数タイプのプロパティを提供します。

この動作をもつ各要素は、適切なURLを作成することができます。

</a> <a href$="[[urlFor('document', document.uid)]]">マイ文書</a>

URLを直接ハードコードする代わりに、ルートに名前を付けることに注意してください。このようにして、要素に柔軟性を加えて、該当の要素が2つの異なるアプリで使用される場合、異なるURLを持つことができます。例えば、アプリケーションAで、文書ページのURLが「/my-document/:id」となるのに対して、アプリケーションBでは、そのURLは/document-page/:idとなります。

このプロセスの背後で行われていることを見てみましょう。「urlFor」関数は、引数としてルートの名前とURLの作成に使用されるその他の追加のパラメータを引き受けます。

Nuxeo.RoutingBehavior = {
  properties: {
    urlFor: {
      type: Function,
      notify: true,
      value: function() {
        return this.generateUrl;
      }
    }
  },

  generateUrl: function() {
    if (this.router) {
      var route = arguments[0];
      if (route.startsWith('/')) {
        return this.baseUrl + route;
      }
      if (!this.router[route]) {
        console.error('Could not generate a url for route ' + route);
        return;
      }
      var params = Array.prototype.slice.call(arguments, 1);
      return this.router[route].apply(this, params);
    }
  }
}

よく見ると、数回使用される「router」オブジェクトがあるのが分かります。このオブジェクトは、名前が付けられたリバースルートハンドラをすべて持ち、これをプロパティとして持つことで、あなたの要素にカスタムルータを簡単に設定することができます。アプリケーションのコンテキストでは、ルートを有効化した要素にルートの同じセットを共有させると、当社のi18n helperの場合やすべてのPolymer要素にこれを追加した場合のように、ルートが(再)定義される際に更新を起動するイベントを使用することができます。

Polymer.Base._addFeature({
  router: {
    home: function() {
      // returns url for homepage
      return page.url('/home');
    },
    document: function(id) {
      // returns url for a document page
  return page.url('/document/' + id);
    }
  }
});

アプリケーションに定義される各ルートについては、該当のルートのURLを作成する責任を担う関数(ルートオブジェクトに保存される)を実装する必要があります。これは難しいことではないはずですが、万が一アプリケーションのURLの一部を若干変更する必要があっても、長期的には役に立つことは間違いないでしょう。

そこが肝心な点です!page.jsがアプリケーションのルーティングを処理しますが、当社の動作機能により、分離した方法でリンクを当社の要素に追加することができます。

当社の要素カタログをご覧になり、該当の要素の詳細を確認し、ご意見をお聞かせください。