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

3,704 views
3,568 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,704
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
53
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Alfresco勉強会20120829: やさしいShareダッシュレットの作り方

    1. 1. 第9回 勉強会やさしいShareダッシュレットの作り方 © 2012 aegif
    2. 2. 自己紹介 林 智行(@linzhixing) 自然言語好き(人工言語も好き) プログラミング言語は駆け出し 社内のAlfresco管理 / ダッシュレット作成 aegif OC最年少 勉強会で発表的なアクティビティは初めて 2
    3. 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
    4. 4. Shareダッシュレットとは(2) 4
    5. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 16. こんなダッシュレットがあったらいいな…… 外部システムと連携 – チケット管理システム(Redmine)とか 16

    ×