Successfully reported this slideshow.

View customize pluginを使いこなす

12

Share

Loading in …3
×
1 of 83
1 of 83

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

View customize pluginを使いこなす

  1. 1. View customize pluginを 使いこなす 2016-05-14 第10回redmine.tokyo勉強会 Hirokazu Onozato @onozaty
  2. 2. 自己紹介 • Hirokazu Onozato (onozaty) オノザティ • https://twitter.com/onozaty • https://github.com/onozaty • http://www.enjoyxstudy.com/ • 株式会社ユニスティ所属 • エンジニア • アプリケーション開発 • マネージメントも少々
  3. 3. 個人で作ったもの • 個人の時間を使って作ったものを公開 • http://www.enjoyxstudy.com/products.html • Firefoxの拡張機能、JavaScriptライブラリなど • suggest.js - 入力補完ライブラリ http://www.enjoyxstudy.com/javascript/suggest/ • ShortcutKey2URL ‐ショートカットキーでURLを開くための Firefoxの拡張機能 http://www.enjoyxstudy.com/firefox/extension/shortcutkey2url/ • IRCbot Console - ブラウザから操作できる多機能なIRCボット http://www.enjoyxstudy.com/ircbotconsole/
  4. 4. RedmineのPlugin • RedmineのPluginも2年くらい前から作り出した • 業務であったらいいなと思うものを、プライベー トな時間で作って公開+自分でも利用 • View customize https://www.redmine.org/plugins/redmine_view_customize • Parent issue filter https://www.redmine.org/plugins/redmine_parent_issue_filter • Copy parent issue id https://www.redmine.org/plugins/copy_parent_issue_id
  5. 5. Redmineの使用状況 • Redmine使用歴6年 • 初めて触ったのは10年前だったが、その時はあまり しっかり使わずに、6年前から継続して使用 • 現プロジェクトでは、0.9 から使い始めて、1.x、 2.x とマイグレーションを重ねて、今は3.1を利用 • チケット数は40,000超え
  6. 6. 利用プラグイン • View customize https://www.redmine.org/plugins/redmine_view_customize • Parent issue filter https://www.redmine.org/plugins/redmine_parent_issue_filter • Copy parent issue id https://www.redmine.org/plugins/copy_parent_issue_id • Issue Template https://www.redmine.org/plugins/issue_templates • Checklists https://www.redmine.org/plugins/redmine_checklists • News Notification https://github.com/georz/redmine_news_notification • その他自作Pluginも
  7. 7. View customize plugin
  8. 8. View customize plugin • Redmineの画面をカスタマイズするためのPlugin • https://www.redmine.org/plugins/redmine_view_customize • https://github.com/onozaty/redmine-view-customize • 特定の画面に対して、JavaScript、CSSを埋め込む 機能を提供
  9. 9. View customize plugin • Redmine自体のコードを変更したり、プラグイン を作ったりといった手間無く、手軽にカスタマイ ズできる • 再起動不要でカスタマイズを適用
  10. 10. ≒UserScript • UserScriptをクライアントではなく、サーバ側で 設定して、Redmineを使用する全ユーザに適用す るイメージ ※UserScriptとは、画面ロード時に任意のJavaScriptを実行して 画面カスタマイズを行えるブラウザの機能
  11. 11. できることの例 • プロジェクト毎にヘッダの色を変える • チケット一覧を識別しやすいように装飾 • チケット作成時にトラッカーに応じてデフォルト値を設定 • サイドバーを開閉式に • 「全てのチケット一覧」リンクをヘッダに • 進行中にもかかわらず担当者が未設定の場合に警告を表示 • ユーザ選択のカスタムフィールドで自分を選択する項目を先頭に追加 • プロジェクト一覧からの各プロジェクトへのリンク先を変更 • カスタムフィールドを連動させる(親の値に応じて、子を絞り込む) • コンテキストメニューを選択しやすくする
  12. 12. 注意点
  13. 13. 注意点 • View customize pluginでは、画面側(JavaScript、 CSS)でしかカスタマイズできないため、出来ない こともある • 画面にない情報を表示するとか
  14. 14. 注意点 • 画面だけでもいろいろ解決できることがあるが、 もしも欲しい機能に特化したプラグインがあるな らば、そちらを使った方が良い • 画面側だけの制約が無いので、シンプルな実装になっ ているはず • その機能の検証も十分行われているはず
  15. 15. 使い方
  16. 16. インストール • Redmineのインストールディレクトリ配下の pluginsディレクトリに移動して、View customize pluginのリポジトリをclone ※clone時のディレクトリ名はview_customizeとしてください cd /var/lib/redmine/plugins git clone https://github.com/onozaty/redmine-view-customize.git view_customize rake redmine:plugins:migrate RAILS_ENV=production
  17. 17. インストールしただけでは… • 何も変わらない • View customize pluginは、Redmineの拡張方法を 提供するだけで、どう設定するかはユーザ次第
  18. 18. 設定方法 • 管理 > View customize で一覧画面へ遷移し、 「New view customize」で設定入力画面へ
  19. 19. 設定方法 コードを実行するパス(URL)。 正規表現で記載。 実行するコード。 JavaScript または StyleSheet(CSS)で書く。 Redmineの画面で使用され ているjQueryも使える。 (Redmineのバージョンに よってライブラリが違うの で注意) プライベートにチェックを入れると、作成したユーザ のみに有効
  20. 20. 実行 • Pathが一致すると、画面にコードが埋め込まれて 実行される
  21. 21. View customizeを触るうえで キーとなる技術
  22. 22. キーとなる技術 • JavaScript(ブラウザ上で動作するスクリプト言語) とCSS(ページのデザインを定義する仕組み)で設定 するので、オリジナルのカスタマイズをしたい場 合には、それらの知識が必要となってくる • ただ、カスタマイズをするにあたって、そこまで多く の知識が求められるわけではないので、調べたり、見 よう見まねでもどうにかなるはず • 実際JavaScriptやCSS知らなかった人でも、調べながらで使え てたりする
  23. 23. jQuery
  24. 24. jQuery • JavaScriptライブラリ • https://jquery.com/ • RedmineではjQueryをすべての画面で読み込んで いるので、View customizeでもjQueryが利用でき る
  25. 25. jQuery • jQueryを使うと、クロスブラウザによる違いの煩 わしさを吸収したり、DOM操作が簡潔に書けるの で便利 • ただ、最近のブラウザだと標準で代替するようなメ ソッドが提供されているので、IE8捨てられるならば、 jQuery使うまでもないかも • WebにjQueryの情報はあふれているので、調べる のも簡単
  26. 26. CSSセレクタ
  27. 27. CSSセレクタ • CSSセレクタとは、CSSでスタイルを適用する対象 を示すもの • View customizeでも良く使うことになる • JavaScriptで指定要素を取得するとき • jQueryの$(selector)関数 • CSSで対象を指定するとき div#header h1
  28. 28. 設定に関するノウハウ
  29. 29. 対象画面の指定方法
  30. 30. Path pattern • Path patternに一致した画面の場合、該当のスクリ プトが埋め込まれる • 正規表現で記載する
  31. 31. URLとPath • URLでアプリケーション配下がPath • クエリパラメータは含まれない • http://example.com/projects -> /prjects • http://example.com/projects/a/issues?set_filter=1 -> /projects/a/issues • http://example.com/redmine/projects ※ドキュメントルートではなく、/redmineとしてインストール -> /prjects
  32. 32. Pathを確認する方法 • バージョン1.1.4から、HTMLにPathをコメントと して埋め込むようになっている • ブラウザのソース表示で見ればその画面のPathが わかる!
  33. 33. 指定例 (よくつかうもの) Path pattern 一致する画面 .* 全ての画面 /issues$ チケット一覧 /issues/new$ チケットの新規作成画面 /issues/[0-9]+$ 個々のチケット内容表示画面 /issues/[0-9]+/copy$ チケットのコピーによる作成画面 /issues/gantt ガントチャート /projects$ プロジェクト一覧 .*[]+$ といった文字は、正規表現におけるメタ文字(特殊な意味をもった文字)
  34. 34. チケットの入力フォーム • チケットの入力フォームは、いろいろな画面で存 在するので、Pathの指定だけだと面倒 • /issues/1 ○チケット内容表示画面でも編集ボタンでフォームが • /issues/new ○新規作成 • /issues/1/copy ○コピーによる作成画面 • /issues/gantt ×ガントチャートなので、これは一致させたくない • /issues ×チケット一覧の場合 ○チケット登録時のValidationエラーの場合
  35. 35. Path pattern + JavaScriptで絞る • “/issues” と指定して、JavaScript側でチケットの入 力フォームが無かったら処理しないようにする • チケットの入力フォームでしか存在しない要素 (#issue-form とか)で確認する • 指定した要素が無かった場合でも処理がスキップされ るように書いていればOK
  36. 36. jQueryの$(selector)関数 • jQueryの$(selector)関数で返却されるjQueryオブジェクト は、一致する要素が無かった場合、何も処理されないので、 それを使っていれば大丈夫 • 上記例だと、入力フォームが無かった場合、on関数でのイベント 登録が行われず、何も処理されないことになる (エラーにもならない) $('#issue-form input[type="submit"]') .on('click', function(event) { // 送信ボタン押下時に何か処理を行わせる });
  37. 37. プロジェクト毎の指定 • チケット詳細画面(/issues/1 など)は、プロジェク トをパスに持たないので、Pathだけだとプロジェ クトを指定できない • /projects/prj1/issues • /projects/prj1/issues/1 ×これはパスとして無効 • /issues/1 ○チケット詳細はプロジェクト関係なく固定パス
  38. 38. body要素に付与されるclass属性で判断 • body要素のclass属性に project-プロジェクト識別 子 が設定されるので、これを使ってプロジェクト を識別する
  39. 39. JavaScriptでプロジェクトを判定 • jQueryの.hasClass()関数で指定のクラス名が存在 するかチェックできる • または、class属性を取り出して比較するなど if ($('body').hasClass('project-prj1')) { // プロジェクト識別子が'prj1'の場合 }
  40. 40. CSSでプロジェクトを指定 • CSSのセレクタでbodyのclassを利用するだけ body.project-prj1 #top-menu { background-color: #006400; /* dark green */ } body.project-prj1 #header { background-color: #008000; /* green */ }
  41. 41. class属性が振られるもの • プロジェクト以外にも、class属性が振られるもの が多々あるので、対象画面や対象箇所を限定する のに使用できる
  42. 42. class属性が振られるもの • body要素 • controller-{コントローラ名} • action-{アクション名} • チケット一覧の各行 • tracker-{トラッカーID} • status-{ステータスID} • priority-{優先度ID} • created-by-me
  43. 43. class属性が振られるもの • 他にもいろいろあるので、詳しくは「Redmineの 画面で振られているclass属性について - Enjoy*Study」にて • http://blog.enjoyxstudy.com/entry/2014/10/11/000000
  44. 44. コード(JavaScript)の書き方
  45. 45. ブラウザの開発者ツールを活用
  46. 46. ブラウザの開発者ツール • いきなりView customizeで設定するのではなく、 ブラウザの開発者ツールを使いながら作成、確認 する • DOMインスペクタ • コンソール
  47. 47. ブラウザの開発者ツール • 開発者ツールは、Chrome、Firefox、IE それぞれ のブラウザに標準でも入っている • Firefoxだと拡張機能のFirebugでもOK • 愛用しているので、以降のキャプチャはFirebugにて
  48. 48. DOMインスペクタ • 選択した要素がHTML上でどういった構造で書か れているか確認できる • ソース表示で見るより簡単
  49. 49. コンソール • 表示している画面に対してのJavaScriptの実行を手 軽に試せる • 補完も効く(複数行モードの場合はダメ)
  50. 50. コンソール • 複数行まとめて実行できるものもあり、長めの コードでも修正、実行を繰り返し行える
  51. 51. 実際に試してみる
  52. 52. 例:ヘッダにチケット一覧リンクを追加 • やること 1. どこに要素を追加すればよいか調べる 2. その要素を起点に、リンクを追加するコードを書く 3. うまくいったら、View customize で設定 (いったんプライベートで) 4. 動作することが確認できたら、プライベートを外し て全体に反映
  53. 53. 追加位置を調べる • DOMインスペクタで追加したい位置を選択
  54. 54. 追加位置を調べる • パスを確認 • id属性がtop-menuとなっているdiv要素配下のul要素の 最後に追加してあげればよさそう
  55. 55. 追加位置を調べる • コンソールで追加対象の要素を取得してみる • div#top-menu > ul (id属性がtop-menuのdiv要素の子 のul要素) で取れた
  56. 56. リンクを追加するコードを書く • 対象のul要素の子要素として、リンクを追加する コードを実行し、思った動作になるまで確認
  57. 57. View customizeで設定 • 画面の描画完了時にコードを実行する必要がある (描画完了前だと、要素が取得できない)ので、 jQueryの$(function)関数を利用 $(function() { // ロード完了時に呼び出される $('#top-menu > ul') .append('<li><a href="/issues">全てのチケット</a></li>'); });
  58. 58. View customizeで設定 • いったんプライベートで設定し、動作を確認する • 動作OKでプライベートを外して、全体に有効へ
  59. 59. コード(CSS)の書き方
  60. 60. JavaScriptの時と同じ • DOMインスペクタで、変更したい要素を探す • CSSセレクタがどうなりそうかも確認しておく • 要素のスタイルを変えて試す
  61. 61. CSSをView customizeに設定 • Path Patternは絞れるならば絞って問題ないが、 CSSセレクタ自体で対象箇所が絞ってかけるので、 全画面対象でもほとんど問題なし • そのままCSSを書くイメージ
  62. 62. CSSセレクタの書き方
  63. 63. CSSセレクタの確認 • DOMインスペクタを使うことによって、CSSセレ クタはわかる
  64. 64. CSSセレクタの指定 • bodyからすべてのパスを書く必要はなく、id属性 が付与されているものを起点に考えると良い • id属性は、一意のものになるので body div#wrapper div#wrapper2 div#wrapper3 div#header h1 div#header h1 bodyからのフルパス こっちで十分
  65. 65. 良く使うCSSセレクタ 他にもいろいろあるので、詳しくない場合には ”CSSセレクタ”で一度調べておくと良い セレクタ名 書式 対象 型セレクタ E E要素 idセレクタ E#myid id名がmyidのE要素 classセレクタ E.warning class名がwarinigのE要素 子孫セレクタ E F E要素の子孫にあたるF要素 子セレクタ E > F E要素の子にあたるF要素 (子孫セレクタは、E要素の配下ならば、ど こにあっても良いが、子セレクタは、1階層 下のみが対象)
  66. 66. CSSセレクタで気を付けること • 必要のない要素と一致させない • 一致してしまう場合には、条件をもっときつく • 単に要素を指定するのではなく、要素+属性で指定す る(idセレクタ、classセレクタなど) • 子孫セレクタではなく子セレクタを使うなど
  67. 67. うまく動作しないときの 確認ポイント
  68. 68. Path patternがあっているか • 画面のソースを表示して、View customizeで指定 したコードが埋め込まれているか確認 • 埋め込まれていない場合、Path patternが間違えている ので、Path patternを見直す
  69. 69. JavaScriptでエラーが発生していないか • 開発者ツールで、エラーメッセージが出力されて いないか確認 • エラーメッセージが出力されていれば、それをもとに JavaScriptを修正
  70. 70. CSSが上書きされていないか • 複数のCSSが一致する場合、その要素に対してど のようなスタイルが適用されるかは、優先度に よって決まる • 該当の要素を詳細に指定している方が優先される • 型セレクタよりidセレクタで指定したものの方が優先 • セレクタのレベルが同じならば、後に書かれたものが 優先される
  71. 71. CSSが上書きされていないか • 上にあるほどもの優先度が高い • 取り消し線のものは、優先度が高いものによって上書きさ れているもの
  72. 72. チケットの入力フォームがらみは面倒 • チケットの入力フォームは、トラッカーまたはス テータスが変わると、フォームの再読み込みが行 われる(#all_attributes配下が差し替わる) • これは、トラッカーやステータスによって入力可能な フィールドや選択肢が変わるため • これにより入力フォームの各要素に対する変更(内 容変更や、イベントの登録)は、リセットされてし まう
  73. 73. チケット入力フォームに対するイベント • 入力フォームが差し替わってもハンドリングでき るようにする必要がある • 考え方としては、親の要素に対してイベントを登 録しておいて、イベントが発生した際に発生元が 該当のものか判断するようなイメージ • jQueryのon関数を使うと簡単に書ける
  74. 74. チケット入力フォームに対するイベント • ダメな例 これだと、入力フォームが差し替わったタイミングで登録先の要素 (#issue_status_id)が別物に変わってしまうのでうまく動かない • OKな例 documentに対してイベントハンドラを登録し、該当の要素(#issue_status_id) が発生元だったら動作するように書くことによって、#issue_status_idが差し 替わってもハンドリング可能に $('#issue_status_id') .on('change', function(e) { // ステータス変更時に実施したい処理 }); $(document) .on('change', '#issue_status_id', function(e) { // ステータス変更時に実施したい処理 });
  75. 75. チケット入力フォームに対する変更 • 入力フォームが差し替わると、変更した内容も元 に戻ってしまうので、差し替わったタイミングで 処理する必要がある • たとえば、カスタムフィールドの値に応じて、他のカ スタムフィールドで選択可能な値を絞る場合など
  76. 76. チケット入力フォームに対する変更 • 差し替え処理を行っている関数をフックして、差 し替え処理の後に処理を差し込む • replaceIssueFormWith 関数が、差し替え処理を行って いる関数なので、そこを対象に // 関数を別名で退避 var _replaceIssueFormWith = replaceIssueFormWith; // 関数を中身を変更 // 退避した処理を呼び出すような関数として作り変える replaceIssueFormWith = function(html) { // 退避しておいた関数を呼び出し _replaceIssueFormWith(html); // ここでフォーム差し替え後に // やりたい処理を書く };
  77. 77. View customize導入に向けて
  78. 78. 試す環境を作る • プロジェクトで使っているRedmineにいきなり適 用するのは敷居が高いという場合には、まずは仮 想環境などで試してみる • Redmineの各バージョンのVagrant boxを公開している ので、そちらを使えばすぐに vagrant init onozaty/redmine-3.2 vagrant up
  79. 79. スクリプトを書いてみる • この資料を参考に書いてみる • スクリプトのサンプルは、下記リポジトリに貯め ていっているので参考に • https://github.com/onozaty/redmine-view-customize-scripts • これからもだんだん増えていく予定
  80. 80. 困ったときには
  81. 81. 困ったときには… • @onozaty まで (follow me!!) • 即レスとまでいきませんが、毎日確認してます • スクリプト例などもつぶやいています
  82. 82. 困ったときには… • こういうことできませんか?といった質問も、お 気軽にどうぞ • 一応、全部答えている(できるものはBlogでも公開)つ もりですが、拾えてなかったらごめんなさい
  83. 83. おわり

×