Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
View customize pluginを使いこなす
Search
onozaty
May 14, 2016
Programming
0
20
View customize pluginを使いこなす
第10回 redmine.tokyo にて発表したView Customize Plugin の資料です。
onozaty
May 14, 2016
Tweet
Share
More Decks by onozaty
See All by onozaty
リモートワーク中に買って良かったものベスト3
onozaty
0
160
情報を表現するときのポイント
onozaty
0
17
チームで開発するための環境を整える
onozaty
1
150
Selenium入門(2023年版)
onozaty
1
160
40歳過ぎてもエンジニアでいるためにやっていること
onozaty
0
36
Java8から17へ
onozaty
0
15
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
0
120
Redmine issue assign notice plugin の紹介
onozaty
0
120
最近作ったもの
onozaty
0
19
Other Decks in Programming
See All in Programming
CloudNativePGがCNCF Sandboxプロジェクトになったぞ! 〜CloudNativePGの仕組みの紹介〜
nnaka2992
0
220
一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜
atsumim
0
110
Linux && Docker 研修/Linux && Docker training
forrep
23
4.5k
『品質』という言葉が嫌いな理由
korimu
0
160
【PHP】破壊的バージョンアップと戦った話〜決断と説得
satoshi256kbyte
0
120
Rails アプリ地図考 Flush Cut
makicamel
1
110
負債になりにくいCSSをデザイナとつくるには?
fsubal
9
2.3k
『GO』アプリ データ基盤のログ収集システムコスト削減
mot_techtalk
0
110
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
890
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
480
富山発の個人開発サービスで日本中の学校の業務を改善した話
krpk1900
4
370
テストをしないQAエンジニアは何をしているか?
nealle
0
130
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
The Cult of Friendly URLs
andyhume
78
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Being A Developer After 40
akosma
89
590k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Fireside Chat
paigeccino
34
3.2k
Typedesign – Prime Four
hannesfritz
40
2.5k
Bash Introduction
62gerente
610
210k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
Building Your Own Lightsaber
phodgson
104
6.2k
Transcript
View customize pluginを 使いこなす 2016-05-14 第10回redmine.tokyo勉強会 Hirokazu Onozato @onozaty
自己紹介 • Hirokazu Onozato (onozaty) オノザティ • https://twitter.com/onozaty • https://github.com/onozaty
• http://www.enjoyxstudy.com/ • 株式会社ユニスティ所属 • エンジニア • アプリケーション開発 • マネージメントも少々
個人で作ったもの • 個人の時間を使って作ったものを公開 • 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/
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
Redmineの使用状況 • Redmine使用歴6年 • 初めて触ったのは10年前だったが、その時はあまり しっかり使わずに、6年前から継続して使用 • 現プロジェクトでは、0.9 から使い始めて、1.x、 2.x
とマイグレーションを重ねて、今は3.1を利用 • チケット数は40,000超え
利用プラグイン • 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も
View customize plugin
View customize plugin • Redmineの画面をカスタマイズするためのPlugin • https://www.redmine.org/plugins/redmine_view_customize • https://github.com/onozaty/redmine-view-customize •
特定の画面に対して、JavaScript、CSSを埋め込む 機能を提供
View customize plugin • Redmine自体のコードを変更したり、プラグイン を作ったりといった手間無く、手軽にカスタマイ ズできる • 再起動不要でカスタマイズを適用
≒UserScript • UserScriptをクライアントではなく、サーバ側で 設定して、Redmineを使用する全ユーザに適用す るイメージ ※UserScriptとは、画面ロード時に任意のJavaScriptを実行して 画面カスタマイズを行えるブラウザの機能
できることの例 • プロジェクト毎にヘッダの色を変える • チケット一覧を識別しやすいように装飾 • チケット作成時にトラッカーに応じてデフォルト値を設定 • サイドバーを開閉式に •
「全てのチケット一覧」リンクをヘッダに • 進行中にもかかわらず担当者が未設定の場合に警告を表示 • ユーザ選択のカスタムフィールドで自分を選択する項目を先頭に追加 • プロジェクト一覧からの各プロジェクトへのリンク先を変更 • カスタムフィールドを連動させる(親の値に応じて、子を絞り込む) • コンテキストメニューを選択しやすくする
注意点
注意点 • View customize pluginでは、画面側(JavaScript、 CSS)でしかカスタマイズできないため、出来ない こともある • 画面にない情報を表示するとか
注意点 • 画面だけでもいろいろ解決できることがあるが、 もしも欲しい機能に特化したプラグインがあるな らば、そちらを使った方が良い • 画面側だけの制約が無いので、シンプルな実装になっ ているはず • その機能の検証も十分行われているはず
使い方
インストール • 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
インストールしただけでは… • 何も変わらない • View customize pluginは、Redmineの拡張方法を 提供するだけで、どう設定するかはユーザ次第
設定方法 • 管理 > View customize で一覧画面へ遷移し、 「New view customize」で設定入力画面へ
設定方法 コードを実行するパス(URL)。 正規表現で記載。 実行するコード。 JavaScript または StyleSheet(CSS)で書く。 Redmineの画面で使用され ているjQueryも使える。 (Redmineのバージョンに
よってライブラリが違うの で注意) プライベートにチェックを入れると、作成したユーザ のみに有効
実行 • Pathが一致すると、画面にコードが埋め込まれて 実行される
View customizeを触るうえで キーとなる技術
キーとなる技術 • JavaScript(ブラウザ上で動作するスクリプト言語) とCSS(ページのデザインを定義する仕組み)で設定 するので、オリジナルのカスタマイズをしたい場 合には、それらの知識が必要となってくる • ただ、カスタマイズをするにあたって、そこまで多く の知識が求められるわけではないので、調べたり、見 よう見まねでもどうにかなるはず
• 実際JavaScriptやCSS知らなかった人でも、調べながらで使え てたりする
jQuery
jQuery • JavaScriptライブラリ • https://jquery.com/ • RedmineではjQueryをすべての画面で読み込んで いるので、View customizeでもjQueryが利用でき る
jQuery • jQueryを使うと、クロスブラウザによる違いの煩 わしさを吸収したり、DOM操作が簡潔に書けるの で便利 • ただ、最近のブラウザだと標準で代替するようなメ ソッドが提供されているので、IE8捨てられるならば、 jQuery使うまでもないかも •
WebにjQueryの情報はあふれているので、調べる のも簡単
CSSセレクタ
CSSセレクタ • CSSセレクタとは、CSSでスタイルを適用する対象 を示すもの • View customizeでも良く使うことになる • JavaScriptで指定要素を取得するとき •
jQueryの$(selector)関数 • CSSで対象を指定するとき div#header h1
設定に関するノウハウ
対象画面の指定方法
Path pattern • Path patternに一致した画面の場合、該当のスクリ プトが埋め込まれる • 正規表現で記載する
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
Pathを確認する方法 • バージョン1.1.4から、HTMLにPathをコメントと して埋め込むようになっている • ブラウザのソース表示で見ればその画面のPathが わかる!
指定例 (よくつかうもの) Path pattern 一致する画面 .* 全ての画面 /issues$ チケット一覧 /issues/new$
チケットの新規作成画面 /issues/[0-9]+$ 個々のチケット内容表示画面 /issues/[0-9]+/copy$ チケットのコピーによる作成画面 /issues/gantt ガントチャート /projects$ プロジェクト一覧 .*[]+$ といった文字は、正規表現におけるメタ文字(特殊な意味をもった文字)
チケットの入力フォーム • チケットの入力フォームは、いろいろな画面で存 在するので、Pathの指定だけだと面倒 • /issues/1 ◦チケット内容表示画面でも編集ボタンでフォームが • /issues/new ◦新規作成
• /issues/1/copy ◦コピーによる作成画面 • /issues/gantt ×ガントチャートなので、これは一致させたくない • /issues ×チケット一覧の場合 ◦チケット登録時のValidationエラーの場合
Path pattern + JavaScriptで絞る • “/issues” と指定して、JavaScript側でチケットの入 力フォームが無かったら処理しないようにする • チケットの入力フォームでしか存在しない要素
(#issue-form とか)で確認する • 指定した要素が無かった場合でも処理がスキップされ るように書いていればOK
jQueryの$(selector)関数 • jQueryの$(selector)関数で返却されるjQueryオブジェクト は、一致する要素が無かった場合、何も処理されないので、 それを使っていれば大丈夫 • 上記例だと、入力フォームが無かった場合、on関数でのイベント 登録が行われず、何も処理されないことになる (エラーにもならない) $('#issue-form
input[type="submit"]') .on('click', function(event) { // 送信ボタン押下時に何か処理を行わせる });
プロジェクト毎の指定 • チケット詳細画面(/issues/1 など)は、プロジェク トをパスに持たないので、Pathだけだとプロジェ クトを指定できない • /projects/prj1/issues • /projects/prj1/issues/1
×これはパスとして無効 • /issues/1 ◦チケット詳細はプロジェクト関係なく固定パス
body要素に付与されるclass属性で判断 • body要素のclass属性に project-プロジェクト識別 子 が設定されるので、これを使ってプロジェクト を識別する
JavaScriptでプロジェクトを判定 • jQueryの.hasClass()関数で指定のクラス名が存在 するかチェックできる • または、class属性を取り出して比較するなど if ($('body').hasClass('project-prj1')) { //
プロジェクト識別子が'prj1'の場合 }
CSSでプロジェクトを指定 • CSSのセレクタでbodyのclassを利用するだけ body.project-prj1 #top-menu { background-color: #006400; /* dark
green */ } body.project-prj1 #header { background-color: #008000; /* green */ }
class属性が振られるもの • プロジェクト以外にも、class属性が振られるもの が多々あるので、対象画面や対象箇所を限定する のに使用できる
class属性が振られるもの • body要素 • controller-{コントローラ名} • action-{アクション名} • チケット一覧の各行 •
tracker-{トラッカーID} • status-{ステータスID} • priority-{優先度ID} • created-by-me
class属性が振られるもの • 他にもいろいろあるので、詳しくは「Redmineの 画面で振られているclass属性について - Enjoy*Study」にて • http://blog.enjoyxstudy.com/entry/2014/10/11/000000
コード(JavaScript)の書き方
ブラウザの開発者ツールを活用
ブラウザの開発者ツール • いきなりView customizeで設定するのではなく、 ブラウザの開発者ツールを使いながら作成、確認 する • DOMインスペクタ • コンソール
ブラウザの開発者ツール • 開発者ツールは、Chrome、Firefox、IE それぞれ のブラウザに標準でも入っている • Firefoxだと拡張機能のFirebugでもOK • 愛用しているので、以降のキャプチャはFirebugにて
DOMインスペクタ • 選択した要素がHTML上でどういった構造で書か れているか確認できる • ソース表示で見るより簡単
コンソール • 表示している画面に対してのJavaScriptの実行を手 軽に試せる • 補完も効く(複数行モードの場合はダメ)
コンソール • 複数行まとめて実行できるものもあり、長めの コードでも修正、実行を繰り返し行える
実際に試してみる
例:ヘッダにチケット一覧リンクを追加 • やること 1. どこに要素を追加すればよいか調べる 2. その要素を起点に、リンクを追加するコードを書く 3. うまくいったら、View customize
で設定 (いったんプライベートで) 4. 動作することが確認できたら、プライベートを外し て全体に反映
追加位置を調べる • DOMインスペクタで追加したい位置を選択
追加位置を調べる • パスを確認 • id属性がtop-menuとなっているdiv要素配下のul要素の 最後に追加してあげればよさそう
追加位置を調べる • コンソールで追加対象の要素を取得してみる • div#top-menu > ul (id属性がtop-menuのdiv要素の子 のul要素) で取れた
リンクを追加するコードを書く • 対象のul要素の子要素として、リンクを追加する コードを実行し、思った動作になるまで確認
View customizeで設定 • 画面の描画完了時にコードを実行する必要がある (描画完了前だと、要素が取得できない)ので、 jQueryの$(function)関数を利用 $(function() { // ロード完了時に呼び出される
$('#top-menu > ul') .append('<li><a href="/issues">全てのチケット</a></li>'); });
View customizeで設定 • いったんプライベートで設定し、動作を確認する • 動作OKでプライベートを外して、全体に有効へ
コード(CSS)の書き方
JavaScriptの時と同じ • DOMインスペクタで、変更したい要素を探す • CSSセレクタがどうなりそうかも確認しておく • 要素のスタイルを変えて試す
CSSをView customizeに設定 • Path Patternは絞れるならば絞って問題ないが、 CSSセレクタ自体で対象箇所が絞ってかけるので、 全画面対象でもほとんど問題なし • そのままCSSを書くイメージ
CSSセレクタの書き方
CSSセレクタの確認 • DOMインスペクタを使うことによって、CSSセレ クタはわかる
CSSセレクタの指定 • bodyからすべてのパスを書く必要はなく、id属性 が付与されているものを起点に考えると良い • id属性は、一意のものになるので body div#wrapper div#wrapper2 div#wrapper3
div#header h1 div#header h1 bodyからのフルパス こっちで十分
良く使う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階層 下のみが対象)
CSSセレクタで気を付けること • 必要のない要素と一致させない • 一致してしまう場合には、条件をもっときつく • 単に要素を指定するのではなく、要素+属性で指定す る(idセレクタ、classセレクタなど) • 子孫セレクタではなく子セレクタを使うなど
うまく動作しないときの 確認ポイント
Path patternがあっているか • 画面のソースを表示して、View customizeで指定 したコードが埋め込まれているか確認 • 埋め込まれていない場合、Path patternが間違えている ので、Path
patternを見直す
JavaScriptでエラーが発生していないか • 開発者ツールで、エラーメッセージが出力されて いないか確認 • エラーメッセージが出力されていれば、それをもとに JavaScriptを修正
CSSが上書きされていないか • 複数のCSSが一致する場合、その要素に対してど のようなスタイルが適用されるかは、優先度に よって決まる • 該当の要素を詳細に指定している方が優先される • 型セレクタよりidセレクタで指定したものの方が優先 •
セレクタのレベルが同じならば、後に書かれたものが 優先される
CSSが上書きされていないか • 上にあるほどもの優先度が高い • 取り消し線のものは、優先度が高いものによって上書きさ れているもの
チケットの入力フォームがらみは面倒 • チケットの入力フォームは、トラッカーまたはス テータスが変わると、フォームの再読み込みが行 われる(#all_attributes配下が差し替わる) • これは、トラッカーやステータスによって入力可能な フィールドや選択肢が変わるため • これにより入力フォームの各要素に対する変更(内
容変更や、イベントの登録)は、リセットされてし まう
チケット入力フォームに対するイベント • 入力フォームが差し替わってもハンドリングでき るようにする必要がある • 考え方としては、親の要素に対してイベントを登 録しておいて、イベントが発生した際に発生元が 該当のものか判断するようなイメージ • jQueryのon関数を使うと簡単に書ける
チケット入力フォームに対するイベント • ダメな例 これだと、入力フォームが差し替わったタイミングで登録先の要素 (#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) { // ステータス変更時に実施したい処理 });
チケット入力フォームに対する変更 • 入力フォームが差し替わると、変更した内容も元 に戻ってしまうので、差し替わったタイミングで 処理する必要がある • たとえば、カスタムフィールドの値に応じて、他のカ スタムフィールドで選択可能な値を絞る場合など
チケット入力フォームに対する変更 • 差し替え処理を行っている関数をフックして、差 し替え処理の後に処理を差し込む • replaceIssueFormWith 関数が、差し替え処理を行って いる関数なので、そこを対象に // 関数を別名で退避
var _replaceIssueFormWith = replaceIssueFormWith; // 関数を中身を変更 // 退避した処理を呼び出すような関数として作り変える replaceIssueFormWith = function(html) { // 退避しておいた関数を呼び出し _replaceIssueFormWith(html); // ここでフォーム差し替え後に // やりたい処理を書く };
View customize導入に向けて
試す環境を作る • プロジェクトで使っているRedmineにいきなり適 用するのは敷居が高いという場合には、まずは仮 想環境などで試してみる • Redmineの各バージョンのVagrant boxを公開している ので、そちらを使えばすぐに vagrant
init onozaty/redmine-3.2 vagrant up
スクリプトを書いてみる • この資料を参考に書いてみる • スクリプトのサンプルは、下記リポジトリに貯め ていっているので参考に • https://github.com/onozaty/redmine-view-customize-scripts • これからもだんだん増えていく予定
困ったときには
困ったときには… • @onozaty まで (follow me!!) • 即レスとまでいきませんが、毎日確認してます • スクリプト例などもつぶやいています
困ったときには… • こういうことできませんか?といった質問も、お 気軽にどうぞ • 一応、全部答えている(できるものはBlogでも公開)つ もりですが、拾えてなかったらごめんなさい
おわり