SlideShare a Scribd company logo
第9回              勉強会
やさしいShareダッシュレットの作り方




                       © 2012 aegif
自己紹介
   林 智行(@linzhixing)
   自然言語好き(人工言語も好き)
   プログラミング言語は駆け出し
   社内のAlfresco管理 / ダッシュレット作成
   aegif OC最年少
   勉強会で発表的なアクティビティは初めて




                                2
Shareダッシュレットとは(1)

   ダッシュレットとは
    –   Alfresco Shareのダッシュボード上に配置される、ユーザが操作可能なウィジェット
    –   WebScriptsの一種
    –   desc.xmlで<family>dashlet</family>を指定したものがダッシュレット(user-dashlet/site-dashletも)
               Alfresco Repositpry
              $TOMCAT_HOME/webapps//alfresco
                  REST API                         CMIS API




                                     利用している

               Alfresco Share                                          外部システム
              $TOMCAT_HOME/webapps/share

                         WebScripts
                            Shareダッシュレット




                                           ユーザ
                                               3
Shareダッシュレットとは(2)




                    4
ダッシュレット = 1,2,3...無限大

   基本的なパターン(リポジトリの情報を取得してダッシュボードに表示する)
    –   AlfrescoのリポジトリからAPIでデータを取得
    –   データを受け取って加工し、表示用のテンプレート(FreeMarker)に渡す
    –   表示用テンプレートで、ダッシュレットの見た目を記述する
        • WebScriptsとしては、HTTPメソッドがGETのWebscriptsになる

                          1             2              3
          Alfresco                                            Share
                       データ取得         データ処理        プレゼンテー
         リポジトリ                                              ダッシュボード
                                                      ション



   少し複雑なパターン(ダッシュレット上からデータを送信したり、結果を返したり)
    –   ほかのWebScripts(POSTプロトコルなど)や外部システムのREST APIなどを組み合わせる
    –   上記RESTに対し、テンプレート上でAjax処理を書く(YUIが使える)


   今日は1,2,3の部分、の1,2,2.5くらいの部分を扱います
    – プレゼンテーション部分の、ShareのYUI作法は結構複雑
        • 知らなくても一応いける




                                            5
WebScriptsの構成

   WebScripts = AlfrescoのREST APIを自前でつくれる (for both リポジトリ, Share)
   定義(.desc.xml)、ロジック(Javascript, Java)、プレゼンテーション(Freemarker)、設定
    (.config.xml, .properties)
   命名規約により複数ファイルがひとかたまりのWebScriptsとして機能
     –   <webscriptsの名前>.<HTTPメソッド>.<ファイルの種類>
          • HTTPメソッド: GET, POST etc.
          • ファイルの種類: desc.xml, js, config.xml etc.
          • e.g. site_inbox.get.desc.xml, site_inbox.get_ja.properties, site_inbox.get.html.ftl
     –   Javaロジックの場合は、$TOMCAT_HOME/shared/classes/web-extension下に*-context.xmlでbean
         定義も必要
   Alfrescoへのデプロイ方法
     –   JAR: WARを汚さないで着脱簡単。
          • インストールは$TOMCAT_HOME/shared/libに。
             – クラスロードの関係で、/shared/lib下のJARではJavaロジックは動作しない
             – ロジックにリポジトリのJava APIが使えない
          • 内部構成
             – alfrescoフォルダ: WebScriptsを構成するファイル
             – META-INFフォルダ: クライアンサイドで読み込むリソース(css、画像、javascript etc.)
          • Alfresco的にはAMPの方が推奨されているようだが、share-extraのサイトではすべてJARで提供されている。
     –   AMP: WARの中を書き変える。モジュールとして独自に管理される。
          • インストールはapply_amps.shで実行
          • 内部構成: マッピングはWiki参照
                                                              6
Shareダッシュレットの作り方
定義/設定情報


   .desc.xml
     –   WebScriptsの定義ファイル
     –   REST APIとしてのURLを定義


   .config.xml
     –   ユーザ固有の情報保存(動的/静的)にも使える
     –   Javascriptからの呼び出し
          • var config = new XML(config.script); ${config.siteId}
     –   FTLからの呼び出し
          • ${config.site_inbox.siteId}


   .properties
     –   プレゼンテーション用のメッセージ
     –   G10Nでプレースホルダ化した項目の値を定義
          • .desc.xmlなどにも使える
     –   _ja.propertiesなどとして、ロケールごとにL18N




                                                        7
Shareダッシュレットの作り方
    ロジック(データ取得 & データ処理)

   REST APIでデータ取得
     –   WebクライアントのWebscriptsであれば、JavaかJavascriptか問題になったが……
     –   JSONでデータを取得して軽く加工するだけであればJavascriptで充分、というかJavaは向いていない
          • リポジトリのJava APIは使えない(alfresco.warとshare.warは別のWebアプリケーション)
          • WebクライアントのJavascriptで出来ていたことも出来なかったり
             – e.g.search.xpathsearchが使えない
          • $TOMCAT/shared/lib下にJARで配置する場合、クラスロードの関係でJavaが使えない
     –   それでもJavaを使いたい場合
          • AMP形式でインストール
          • e.g.ダッシュレットから外部のLDAPにJNDIでアクセスしたい
     –   Javascriptであればremote.call(url)でREST APIを呼べる
   REST APIについての情報源
     –   Webscripts一覧(<localhost>/alfresco/share/page/index, <localhost>/share/share/page/index)
     –   ネット
   データの処理
     –   表示用テンプレートのFreeMarker上でも<#if>や<#assign>などを使ってデータ加工できてしまうが、望ま
         しくないし面倒くさい




                                                     8
Shareダッシュレットの作り方
REST APIで取得したJSONデータ

 サイト内の特定フォルダの内容
 alfresco/service/slingshot/doclib/doclist/documents/site/<サイトID>/<サイト内のフォルダパス>



 {
     "totalRecords": 5,
     "startIndex": 0,
     "metadata":
     {
         //省略
   },
   "items":
   [
      {
   "nodeRef": "workspace://SpacesStore/84debbfe-60bc-458a-bc17-8c4913285852",
   "nodeType": "cm:content",
   "type": "document",
   "mimetype": "text/plain",
   "isFolder": false,
   "isLink": false,
   "fileName": "test1.txt",
   "displayName": "test1.txt",
   "status": "",
   "title": "",
   "description": "",
   "author": "",
   "createdOn": "2012-08-29T15:19:12.989+09:00",
   "createdBy": "Administrator",
   "createdByUser": "admin",
   "modifiedOn": "2012-08-29T15:19:12.989+09:00",
   "modifiedBy": "Administrator",
   "modifiedByUser": "admin",
   "lockedBy": "",
   "lockedByUser": "",
   "size": "4",
   "version": "1.0",
   "contentUrl": "api/node/content/workspace/SpacesStore/84debbfe-60bc-458a-bc17-8c4913285852/test1.txt",
   "webdavUrl": "/webdav/%e3%82%b5%e3%82%a4%e3%83%88/aegifportal/documentLibrary/%e5%8f%97%e4%bf%a1BOX/admin/
test1.txt",
 //以下省略


                                                              9
Shareダッシュレットの作り方
ロジック( .get.js)のソースコード

<import resource="classpath:/alfresco/templates/org/alfresco/import/alfresco-util.js">

function main(){
	      var s = new XML(config.script);                 ■.config.xmlから設定情報読み取り
	      var userid = context.user.id;
	
                                                       ■Surfが提供しているbuilt-inオブジェクトから読み取り
	      //documents API
	      var documentsAPIUrl = "/slingshot/doclib/doclist/documents/site/" + s.target.siteid.toString() + "/documentLibrary/" + s.target.folder.toString() + "/" + userid;
	      var data = doclistAPI(documentsAPIUrl);

	     //folder info
	     if(typeof data.metadata === "undefined"){
	     	      model.folder = {};                                                                    REST APIのURL
	     }else{
	     	      if(typeof data.metadata.parent === "undefined"){
	     	      	      model.folder = {};
	     	      }else{
	     	      	      model.folder = data.metadata.parent;
	     	      }
	     }
	                                                    プレゼンテーション用にデータ
	     //documents info
	     if(typeof data.items === "undefined"){         を渡すためmodelに格納                                            標準で用意されているメソッ
	     	      model.items = [];
	     }else{                                                                                                  ドを使用
	     	      //date conversion
	     	      for(i=0; i < data.items.length; i++){
	     	      	      data.items[i].formattedModifiedOn = AlfrescoUtil.fromISO8601(data.items[i].modifiedOn);
	     	      }
	     	      //sorting by date in descending order
	     	      data.items.sort(
	     	      	      function(a,b){ return b.formattedModifiedOn - a.formattedModifiedOn }
	     	      );
	     	      //slice to the limited number
	     	      var maxShow = Number(s.maxShow.toString());
	     	      data.items = data.items.slice(0, maxShow);	    	
	     	      model.items = data.items;
	     	      model.maxShow = maxShow;
	     }	                                                              Surfが提供している
}
                                                                     remoteオブジェクトを使用
function doclistAPI(url){
	      var connector = remote.connect("alfresco");
	      var json = remote.call(encodeURI(url));
	      var data = eval (" (" + json + ") ") ;
	      return data;
}

main();
                              処理をmain関数にまとめて、main();
                             で実行するのがお作法らしい


                                                                                  10
Shareダッシュレットの作り方
プレゼンテーション部分


   まずFreeMarker開発環境を整える
     –   EclipseではJBoss ToolのプラグインにFreeMarker IDEがある
   デフォルトで色々読み込まれてる
     –   header.get.html.ftl: templateArgs.siteIdなどの値を利用可能
     –   Alfresco.widgetのYUIコンポーネント
     –   basic.css
     –   etc.
   WebScriptsのロジックからデータを受け取れる
     –   Javascriptでmodel.<property>に格納した値を、${property}でinterpoleできる
   FreeMarkerの${...}で使うデータは存在判定を忘れずに!
     –   ?? , ?has_context , ! etc.




                                                      11
Shareダッシュレットの作り方
プレゼンテーション( .get.head.ftl)のソースコード

リソースファイルへのJar内部のフォルダ構成を指定
/aegif/components/dashlets

  <#include "/org/alfresco/components/component.head.inc">
<#--
    Uncomment the lines below to wire in the client-side assets. Other files will
    also be required if additional functionality, e.g. config dialogues, are needed.
-->
<@script type="text/javascript" src="${page.url.context}/res/aegif/components/dashlets/site_inbox.js"></@script>
<@link rel="stylesheet" type="text/css" href="${page.url.context}/res/aegif/components/dashlets/site_inbox.css" />




                                                                   12
Shareダッシュレットの作り方
プレゼンテーション( .get.html.ftl)のソースコード
  <script type="text/javascript">//<![CDATA[
   new Alfresco.widget.DashletResizer("${args.htmlid}", "${instance.object.id}");         標準のYUIコンポーネント
//]]></script>
                                                                                           呼び出し

<div class="dashlet">
   <div class="title">${msg("header")}</div>
   <div class="body scrollableList"<#-- if args.height??> style="height: ${args.height}px;"</#if -->>
     <div class="detail-list-item first-item last-item">
        <span>                                                                        .config.xmlや.propertiesから設
	    	     	     <#if items?has_content>                                              定情報を読み込んで利用
	    	     	     <#if folder?has_content>
	    	     	     <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/documentlibrary#filter=path|/$
{config.script.site_inbox.target.folder}/${user.id}" class="theme-color-1">${msg("message.inbox1")}</a>
	    	     	     </#if>                 ロジック部分から受け
	    	     	     ${msg("message.inbox2")}${msg("message.listnum.latest")}${maxShow}${msg("message.listnum.display")}<br/>
                                       取ったデータを利用
	    	     	     <table class="site_inbox" border="0" rules="rows" width=100%>
	    	     	     <#list items as item>
	    	     	     	    <#assign fileExtIndex = item.fileName?last_index_of(".")>
	    	     	     	    <#assign fileExt = (fileExtIndex > -1)?string(item.fileName?substring(fileExtIndex + 1)?lower_case,
"generic")>	     	
                                                                       ファイル拡張子を取得
	    	     	     	    <tr class="site_inbox">
	    	     	     	    	     <td class="site_inbox fileimage">	         (標準で用意されてるかも)
	    	     	     	    	     	     <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/document-details?nodeRef=$
{item.nodeRef}">
	    	     	     	    	     	     	     <img src="${url.context}/res/components/images/filetypes/${fileExt}-file-32.png"
onerror="this.src='${url.context}/res/components/images/filetypes/generic-file-32.png'" alt="${item.displayName}" title="$
{item.displayName}">
	    	     	     	    	     	     </a>
	    	     	     	    	     </td>
	    	     	     	    	     <td>
	    	     	     	    	     	     <h3 class="filename">
	    	     	     	    	     	     	     <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/document-details?
nodeRef=${item.nodeRef}" class="theme-color-1">${item.displayName}</a><br/>
	    	     	     	    	     	     </h3>
	    	     	     	    	     	     <span class="site_inbox">${msg("message.modifiedDate")}<span>${item.formattedModifiedOn?string("yyyy年MM月
dd日 HH:mm")}</span></span><br/>
	    	    	     	    	    </td>
	    	    	     	    </tr>	
                          	
	    	    	     </#list>



                                                                   13
その他 開発上のTIPS

   Shareを別のtomcatインスタンスで起動する
    –   デバッグ(とくにFreeMarker)のスピードUp
         • Share単体なら15sくらいで起動
    –   必要な設定
         • $TOMCAT_HOME/conf/server.xml
            – <Server port="8005" shutdown="SHUTDOWN">
            –   Define a non-SSL HTTP/1.1 Connector on port 8080--><Connector port="8180" protocol="HTTP/1.1"

         • $TOMCAT_HOME/conf/catalina.properties
            – shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar
            – 上記フォルダを作っておく。/shared/classesフォルダには元のヴァニラAlfrescoからweb-extensionをコピー
   標準のCSSのかかり方をFirebugで調べる
   FreeMarkerのデバッグ良い方法ないかな……




                                                                         14
おまけ

    他にも、こんなダッシュレットがつくれます



   MyShareLocale
     –   Shareのダッシュレット上からShareの表示言語(ロケール)を切り替える
     –   仕組み
         • Surfの仕組みとして、各ページ読み込みのたびにLocaleResolverでロケールが解決されている
         • LocaleResolverのbean定義を自前のLocaleResolverに変更する(/web-extensionの-context.xmlで書き換え)
         • 自前のLocaleResolverはユーザのCookieを読み込んでロケールを解決する
         • ユーザはダッシュレットおよびログインページで、表示させたいロケールを選択しCookieに保存する:
     –   どんな時に便利?
         • 正直、ブラウザのアドオンでロケール変更するのでOK(IEだと少し面倒くさいけれど……)
         • Shareの翻訳に便利
           – Alfresco Shareクリンゴン語Language Packの翻訳にも便利




   LDAP Utility
     –   Shareのダッシュレット上から、連携しているLDAPのユーザパスワードをユーザが変更できるようにする
     –   仕組み
         • Java-backed Webscriptsとして、JNDI機能によりLDAPサーバを叩いている
         • GET/POST両方のWebScriptを定義。ダッシュレットはGETの方だが、YUIによるAjaxでPOSTを呼んでいる。

                                              15
こんなダッシュレットがあったらいいな……


   外部システムと連携
     –   チケット管理システム(Redmine)とか




                                 16
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方

More Related Content

PDF
Alfrescoのカスタムテーブルの使い方
PDF
[Alfresco]ドキュメントライブラリのUIカスタマイズ
PPTX
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
PPTX
メタプログラミングRuby勉強会#7(fluentプラグイン)
PDF
20130606 alfresco study16audit
PDF
DBFlute Mavenプラグインを用いてCRUD作成
PDF
Sc2009autumn s2robot
PPTX
Alfresco勉強会#28 alfresco 5.0の検索機能をみてみよう
Alfrescoのカスタムテーブルの使い方
[Alfresco]ドキュメントライブラリのUIカスタマイズ
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
メタプログラミングRuby勉強会#7(fluentプラグイン)
20130606 alfresco study16audit
DBFlute Mavenプラグインを用いてCRUD作成
Sc2009autumn s2robot
Alfresco勉強会#28 alfresco 5.0の検索機能をみてみよう

What's hot (19)

PDF
AlfrescoとSolr(後編)
PDF
15分でCakePHPを始める方法(Nseg 2013-11-09 )
PPTX
HTML5最新動向
KEY
FuelPHPをさわってみて
PDF
PowerShell DSC と Linux
PDF
20091030cakephphandson 01
PPTX
HTML5&API総まくり
PDF
FuelPHP Osu Nagoya vol.1
PDF
Ansible2.9 ネットワーク対応のアップデート #ansiblejp
PDF
12 cyberagent
PDF
omoon.org の裏側 〜FuelPHP の task 活用例〜
PDF
JobSchedulerでCD(継続的デリバリ)
PDF
最近の PowerShell のお話
PDF
Alfresco ce 4.2の新機能
PDF
FuelPHPで3種のprofilerを使ってみた
PDF
10分でわかるFuelPHP @ 2011/12
PDF
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
PDF
Fuel php osc tokyo2012
PDF
Ansible handson ood2016
AlfrescoとSolr(後編)
15分でCakePHPを始める方法(Nseg 2013-11-09 )
HTML5最新動向
FuelPHPをさわってみて
PowerShell DSC と Linux
20091030cakephphandson 01
HTML5&API総まくり
FuelPHP Osu Nagoya vol.1
Ansible2.9 ネットワーク対応のアップデート #ansiblejp
12 cyberagent
omoon.org の裏側 〜FuelPHP の task 活用例〜
JobSchedulerでCD(継続的デリバリ)
最近の PowerShell のお話
Alfresco ce 4.2の新機能
FuelPHPで3種のprofilerを使ってみた
10分でわかるFuelPHP @ 2011/12
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Fuel php osc tokyo2012
Ansible handson ood2016
Ad

Viewers also liked (13)

PDF
WordPressを仕事で使用する際に便利なおすすめプラグインの紹介
KEY
Alfrescoクラスタリング入門
PPT
Alfrescoのバックアップとレストア
PDF
Alfresco勉強会#34 Alfrescoをカスタマイズする時に知っておくと便利なこと
PPTX
0からわかるAlfresco
PDF
Alfrescoインストール手順書(株式会社ヴィセント)
PDF
20130925 alfresco study18performancetuning
PPTX
Alfresco tuning part2
PPTX
Alfresco tuning part1
PDF
全社情報共有サイトへの Alfresco Community 5 導入事例紹介 - 第27回Alfresco勉強会
PDF
bottleで始めるWEBアプリの最初の一歩
PDF
Alfresco勉強会#18 alfrescoのバックアップとリストア
PPTX
Alfresco Javascript Consoleのご紹介
WordPressを仕事で使用する際に便利なおすすめプラグインの紹介
Alfrescoクラスタリング入門
Alfrescoのバックアップとレストア
Alfresco勉強会#34 Alfrescoをカスタマイズする時に知っておくと便利なこと
0からわかるAlfresco
Alfrescoインストール手順書(株式会社ヴィセント)
20130925 alfresco study18performancetuning
Alfresco tuning part2
Alfresco tuning part1
全社情報共有サイトへの Alfresco Community 5 導入事例紹介 - 第27回Alfresco勉強会
bottleで始めるWEBアプリの最初の一歩
Alfresco勉強会#18 alfrescoのバックアップとリストア
Alfresco Javascript Consoleのご紹介
Ad

Similar to Alfresco勉強会20120829: やさしいShareダッシュレットの作り方 (20)

PPTX
開発者向けAlfrescoのご紹介(2013/03/27 JJUG ナイトセミナー「Java製OSS特集」発表資料)
PDF
Hadoopによるリクルートでの技術調査とその活用
PDF
XPagesでRESTを使ってみたら、こんなんだった
PDF
Scalaでプログラムを作りました
PDF
SilverlightとSharePoint2010の紹介
PDF
全部入り!WGPで高速JavaScript+HML5体験
PDF
Pyramid入門
PPTX
Fluxflex meetup 2011 in Tokyo
PPTX
fluxflex meetup in Tokyo
PDF
第142回Smalltalk勉強会 - PharoJSで作るWebアプリケーション
PDF
20130412 titanium meetupvol7
PPTX
130329 perl casual_ruik
PDF
「新しい」を生み出すためのWebアプリ開発とその周辺
PDF
XPagesDay 2015 RESTの総復習
PPTX
20160115nodered design patterns
PDF
jQuery と MVC で実践する標準志向 Web 開発
PDF
XAML と C# を使った Windows ストアアプリ(LOB)構築のためのtips Prism 4.5 & Kona project 等のご紹介
PDF
できる!スマホアプリ:Webからはじまるアプリ for CMU16
PPTX
Share UIカスタマイズ Widget編
PDF
Spine入門
開発者向けAlfrescoのご紹介(2013/03/27 JJUG ナイトセミナー「Java製OSS特集」発表資料)
Hadoopによるリクルートでの技術調査とその活用
XPagesでRESTを使ってみたら、こんなんだった
Scalaでプログラムを作りました
SilverlightとSharePoint2010の紹介
全部入り!WGPで高速JavaScript+HML5体験
Pyramid入門
Fluxflex meetup 2011 in Tokyo
fluxflex meetup in Tokyo
第142回Smalltalk勉強会 - PharoJSで作るWebアプリケーション
20130412 titanium meetupvol7
130329 perl casual_ruik
「新しい」を生み出すためのWebアプリ開発とその周辺
XPagesDay 2015 RESTの総復習
20160115nodered design patterns
jQuery と MVC で実践する標準志向 Web 開発
XAML と C# を使った Windows ストアアプリ(LOB)構築のためのtips Prism 4.5 & Kona project 等のご紹介
できる!スマホアプリ:Webからはじまるアプリ for CMU16
Share UIカスタマイズ Widget編
Spine入門

Alfresco勉強会20120829: やさしいShareダッシュレットの作り方

  • 1. 第9回 勉強会 やさしいShareダッシュレットの作り方 © 2012 aegif
  • 2. 自己紹介  林 智行(@linzhixing)  自然言語好き(人工言語も好き)  プログラミング言語は駆け出し  社内のAlfresco管理 / ダッシュレット作成  aegif OC最年少  勉強会で発表的なアクティビティは初めて 2
  • 3. Shareダッシュレットとは(1)  ダッシュレットとは – Alfresco Shareのダッシュボード上に配置される、ユーザが操作可能なウィジェット – WebScriptsの一種 – desc.xmlで<family>dashlet</family>を指定したものがダッシュレット(user-dashlet/site-dashletも) Alfresco Repositpry $TOMCAT_HOME/webapps//alfresco REST API CMIS API 利用している Alfresco Share 外部システム $TOMCAT_HOME/webapps/share WebScripts Shareダッシュレット ユーザ 3
  • 5. ダッシュレット = 1,2,3...無限大  基本的なパターン(リポジトリの情報を取得してダッシュボードに表示する) – AlfrescoのリポジトリからAPIでデータを取得 – データを受け取って加工し、表示用のテンプレート(FreeMarker)に渡す – 表示用テンプレートで、ダッシュレットの見た目を記述する • WebScriptsとしては、HTTPメソッドがGETのWebscriptsになる 1 2 3 Alfresco Share データ取得 データ処理 プレゼンテー リポジトリ ダッシュボード ション  少し複雑なパターン(ダッシュレット上からデータを送信したり、結果を返したり) – ほかのWebScripts(POSTプロトコルなど)や外部システムのREST APIなどを組み合わせる – 上記RESTに対し、テンプレート上でAjax処理を書く(YUIが使える)  今日は1,2,3の部分、の1,2,2.5くらいの部分を扱います – プレゼンテーション部分の、ShareのYUI作法は結構複雑 • 知らなくても一応いける 5
  • 6. WebScriptsの構成  WebScripts = AlfrescoのREST APIを自前でつくれる (for both リポジトリ, Share)  定義(.desc.xml)、ロジック(Javascript, Java)、プレゼンテーション(Freemarker)、設定 (.config.xml, .properties)  命名規約により複数ファイルがひとかたまりのWebScriptsとして機能 – <webscriptsの名前>.<HTTPメソッド>.<ファイルの種類> • HTTPメソッド: GET, POST etc. • ファイルの種類: desc.xml, js, config.xml etc. • e.g. site_inbox.get.desc.xml, site_inbox.get_ja.properties, site_inbox.get.html.ftl – Javaロジックの場合は、$TOMCAT_HOME/shared/classes/web-extension下に*-context.xmlでbean 定義も必要  Alfrescoへのデプロイ方法 – JAR: WARを汚さないで着脱簡単。 • インストールは$TOMCAT_HOME/shared/libに。 – クラスロードの関係で、/shared/lib下のJARではJavaロジックは動作しない – ロジックにリポジトリのJava APIが使えない • 内部構成 – alfrescoフォルダ: WebScriptsを構成するファイル – META-INFフォルダ: クライアンサイドで読み込むリソース(css、画像、javascript etc.) • Alfresco的にはAMPの方が推奨されているようだが、share-extraのサイトではすべてJARで提供されている。 – AMP: WARの中を書き変える。モジュールとして独自に管理される。 • インストールはapply_amps.shで実行 • 内部構成: マッピングはWiki参照 6
  • 7. Shareダッシュレットの作り方 定義/設定情報  .desc.xml – WebScriptsの定義ファイル – REST APIとしてのURLを定義  .config.xml – ユーザ固有の情報保存(動的/静的)にも使える – Javascriptからの呼び出し • var config = new XML(config.script); ${config.siteId} – FTLからの呼び出し • ${config.site_inbox.siteId}  .properties – プレゼンテーション用のメッセージ – G10Nでプレースホルダ化した項目の値を定義 • .desc.xmlなどにも使える – _ja.propertiesなどとして、ロケールごとにL18N 7
  • 8. Shareダッシュレットの作り方 ロジック(データ取得 & データ処理)  REST APIでデータ取得 – WebクライアントのWebscriptsであれば、JavaかJavascriptか問題になったが…… – JSONでデータを取得して軽く加工するだけであればJavascriptで充分、というかJavaは向いていない • リポジトリのJava APIは使えない(alfresco.warとshare.warは別のWebアプリケーション) • WebクライアントのJavascriptで出来ていたことも出来なかったり – e.g.search.xpathsearchが使えない • $TOMCAT/shared/lib下にJARで配置する場合、クラスロードの関係でJavaが使えない – それでもJavaを使いたい場合 • AMP形式でインストール • e.g.ダッシュレットから外部のLDAPにJNDIでアクセスしたい – Javascriptであればremote.call(url)でREST APIを呼べる  REST APIについての情報源 – Webscripts一覧(<localhost>/alfresco/share/page/index, <localhost>/share/share/page/index) – ネット  データの処理 – 表示用テンプレートのFreeMarker上でも<#if>や<#assign>などを使ってデータ加工できてしまうが、望ま しくないし面倒くさい 8
  • 9. Shareダッシュレットの作り方 REST APIで取得したJSONデータ サイト内の特定フォルダの内容 alfresco/service/slingshot/doclib/doclist/documents/site/<サイトID>/<サイト内のフォルダパス> { "totalRecords": 5, "startIndex": 0, "metadata": { //省略 }, "items": [ { "nodeRef": "workspace://SpacesStore/84debbfe-60bc-458a-bc17-8c4913285852", "nodeType": "cm:content", "type": "document", "mimetype": "text/plain", "isFolder": false, "isLink": false, "fileName": "test1.txt", "displayName": "test1.txt", "status": "", "title": "", "description": "", "author": "", "createdOn": "2012-08-29T15:19:12.989+09:00", "createdBy": "Administrator", "createdByUser": "admin", "modifiedOn": "2012-08-29T15:19:12.989+09:00", "modifiedBy": "Administrator", "modifiedByUser": "admin", "lockedBy": "", "lockedByUser": "", "size": "4", "version": "1.0", "contentUrl": "api/node/content/workspace/SpacesStore/84debbfe-60bc-458a-bc17-8c4913285852/test1.txt", "webdavUrl": "/webdav/%e3%82%b5%e3%82%a4%e3%83%88/aegifportal/documentLibrary/%e5%8f%97%e4%bf%a1BOX/admin/ test1.txt", //以下省略 9
  • 10. Shareダッシュレットの作り方 ロジック( .get.js)のソースコード <import resource="classpath:/alfresco/templates/org/alfresco/import/alfresco-util.js"> function main(){ var s = new XML(config.script); ■.config.xmlから設定情報読み取り var userid = context.user.id; ■Surfが提供しているbuilt-inオブジェクトから読み取り //documents API var documentsAPIUrl = "/slingshot/doclib/doclist/documents/site/" + s.target.siteid.toString() + "/documentLibrary/" + s.target.folder.toString() + "/" + userid; var data = doclistAPI(documentsAPIUrl); //folder info if(typeof data.metadata === "undefined"){ model.folder = {}; REST APIのURL }else{ if(typeof data.metadata.parent === "undefined"){ model.folder = {}; }else{ model.folder = data.metadata.parent; } } プレゼンテーション用にデータ //documents info if(typeof data.items === "undefined"){ を渡すためmodelに格納 標準で用意されているメソッ model.items = []; }else{ ドを使用 //date conversion for(i=0; i < data.items.length; i++){ data.items[i].formattedModifiedOn = AlfrescoUtil.fromISO8601(data.items[i].modifiedOn); } //sorting by date in descending order data.items.sort( function(a,b){ return b.formattedModifiedOn - a.formattedModifiedOn } ); //slice to the limited number var maxShow = Number(s.maxShow.toString()); data.items = data.items.slice(0, maxShow); model.items = data.items; model.maxShow = maxShow; } Surfが提供している } remoteオブジェクトを使用 function doclistAPI(url){ var connector = remote.connect("alfresco"); var json = remote.call(encodeURI(url)); var data = eval (" (" + json + ") ") ; return data; } main(); 処理をmain関数にまとめて、main(); で実行するのがお作法らしい 10
  • 11. Shareダッシュレットの作り方 プレゼンテーション部分  まずFreeMarker開発環境を整える – EclipseではJBoss ToolのプラグインにFreeMarker IDEがある  デフォルトで色々読み込まれてる – header.get.html.ftl: templateArgs.siteIdなどの値を利用可能 – Alfresco.widgetのYUIコンポーネント – basic.css – etc.  WebScriptsのロジックからデータを受け取れる – Javascriptでmodel.<property>に格納した値を、${property}でinterpoleできる  FreeMarkerの${...}で使うデータは存在判定を忘れずに! – ?? , ?has_context , ! etc. 11
  • 12. Shareダッシュレットの作り方 プレゼンテーション( .get.head.ftl)のソースコード リソースファイルへのJar内部のフォルダ構成を指定 /aegif/components/dashlets  <#include "/org/alfresco/components/component.head.inc"> <#-- Uncomment the lines below to wire in the client-side assets. Other files will also be required if additional functionality, e.g. config dialogues, are needed. --> <@script type="text/javascript" src="${page.url.context}/res/aegif/components/dashlets/site_inbox.js"></@script> <@link rel="stylesheet" type="text/css" href="${page.url.context}/res/aegif/components/dashlets/site_inbox.css" /> 12
  • 13. Shareダッシュレットの作り方 プレゼンテーション( .get.html.ftl)のソースコード  <script type="text/javascript">//<![CDATA[ new Alfresco.widget.DashletResizer("${args.htmlid}", "${instance.object.id}"); 標準のYUIコンポーネント //]]></script> 呼び出し <div class="dashlet"> <div class="title">${msg("header")}</div> <div class="body scrollableList"<#-- if args.height??> style="height: ${args.height}px;"</#if -->> <div class="detail-list-item first-item last-item"> <span> .config.xmlや.propertiesから設 <#if items?has_content> 定情報を読み込んで利用 <#if folder?has_content> <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/documentlibrary#filter=path|/$ {config.script.site_inbox.target.folder}/${user.id}" class="theme-color-1">${msg("message.inbox1")}</a> </#if> ロジック部分から受け ${msg("message.inbox2")}${msg("message.listnum.latest")}${maxShow}${msg("message.listnum.display")}<br/> 取ったデータを利用 <table class="site_inbox" border="0" rules="rows" width=100%> <#list items as item> <#assign fileExtIndex = item.fileName?last_index_of(".")> <#assign fileExt = (fileExtIndex > -1)?string(item.fileName?substring(fileExtIndex + 1)?lower_case, "generic")> ファイル拡張子を取得 <tr class="site_inbox"> <td class="site_inbox fileimage"> (標準で用意されてるかも) <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/document-details?nodeRef=$ {item.nodeRef}"> <img src="${url.context}/res/components/images/filetypes/${fileExt}-file-32.png" onerror="this.src='${url.context}/res/components/images/filetypes/generic-file-32.png'" alt="${item.displayName}" title="$ {item.displayName}"> </a> </td> <td> <h3 class="filename"> <a href="${url.context}/page/site/${config.script.site_inbox.target.siteid}/document-details? nodeRef=${item.nodeRef}" class="theme-color-1">${item.displayName}</a><br/> </h3> <span class="site_inbox">${msg("message.modifiedDate")}<span>${item.formattedModifiedOn?string("yyyy年MM月 dd日 HH:mm")}</span></span><br/> </td> </tr> </#list> 13
  • 14. その他 開発上のTIPS  Shareを別のtomcatインスタンスで起動する – デバッグ(とくにFreeMarker)のスピードUp • Share単体なら15sくらいで起動 – 必要な設定 • $TOMCAT_HOME/conf/server.xml – <Server port="8005" shutdown="SHUTDOWN"> – Define a non-SSL HTTP/1.1 Connector on port 8080--><Connector port="8180" protocol="HTTP/1.1" • $TOMCAT_HOME/conf/catalina.properties – shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar – 上記フォルダを作っておく。/shared/classesフォルダには元のヴァニラAlfrescoからweb-extensionをコピー  標準のCSSのかかり方をFirebugで調べる  FreeMarkerのデバッグ良い方法ないかな…… 14
  • 15. おまけ 他にも、こんなダッシュレットがつくれます  MyShareLocale – Shareのダッシュレット上からShareの表示言語(ロケール)を切り替える – 仕組み • Surfの仕組みとして、各ページ読み込みのたびにLocaleResolverでロケールが解決されている • LocaleResolverのbean定義を自前のLocaleResolverに変更する(/web-extensionの-context.xmlで書き換え) • 自前のLocaleResolverはユーザのCookieを読み込んでロケールを解決する • ユーザはダッシュレットおよびログインページで、表示させたいロケールを選択しCookieに保存する: – どんな時に便利? • 正直、ブラウザのアドオンでロケール変更するのでOK(IEだと少し面倒くさいけれど……) • Shareの翻訳に便利 – Alfresco Shareクリンゴン語Language Packの翻訳にも便利  LDAP Utility – Shareのダッシュレット上から、連携しているLDAPのユーザパスワードをユーザが変更できるようにする – 仕組み • Java-backed Webscriptsとして、JNDI機能によりLDAPサーバを叩いている • GET/POST両方のWebScriptを定義。ダッシュレットはGETの方だが、YUIによるAjaxでPOSTを呼んでいる。 15
  • 16. こんなダッシュレットがあったらいいな……  外部システムと連携 – チケット管理システム(Redmine)とか 16

Editor's Notes