Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Redmineカスタムフィールド表示改善

11,343 views

Published on

Redmine Custom field layout improvement technique
(Japanese Only)

Published in: Software
  • Be the first to comment

Redmineカスタムフィールド表示改善

  1. 1. Redmineカスタムフィールド 表示改善方法 2016/5/14 redmine.tokyo 第10回勉強会 @y503unavailable 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 1
  2. 2. 自己紹介 • 名前:奈良 裕記 ( y503unavailable <- httpエラーコード503) • 製造業で製品開発部門のadminやってます。 • 部門サーバ、LAN、PC、全般の構築/運用/子守 (全社単位の情報システムとは別、部門所属) • Redmine歴 • 2009年から利用 • 部内SaaSの積りで各種運用中。 • Redmine.Tokyoには第4回から参加 • 第7回勉強会にてRedmineサーバ統合事例を発表 http://www.slideshare.net/y503unavailable/redmine-42182169 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 2
  3. 3. お断り • 発表内容は、自分が管理する環境における実施事例 です。 •あくまで参考程度にお願いします。 • 使用していない機能は検証していません。 • 各自環境への適合性は勿論保証できません。 • データ破損が後日発見されるかもしれません。 • 異常処理は何も行っていません. • より効率的な方法もあるでしょう。 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 3
  4. 4. カスタムフィールド表示改善 Redmineで多数のカスタムフィールドを使用すると、 チケット編集/表示画面が見難くなります。 (固定2列表示・項目区切り無。サイズ調整不可) しかし、Redmineソースを数個修正するだけで、 編集/表示画面を大幅に改善できます。 サンプルデータ(次頁以降) • 管理項目:チケット駆動開発本のP39(Redmine)とP70(Mantis) • Redmine3.2.1ベースで改造 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 4
  5. 5. Redmineデフォルトの編集画面 (カスタムフィールド-14個) ・項目の区切り不明 ・長文編集困難(猫の額) 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 5
  6. 6. 改造後のRedmine入力画面 • セクション区切り • 見出し表示 • 行項目数調整 • 編集枠サイズ調整 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 6
  7. 7. 改造後の表示画面 • セクション区切り • 見出し表示 • 行項目数調整 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 7
  8. 8. 改造作業手順 1. CFを実際の表示順に並べる(Redmine標準機能) 2. CFの配置/改行位置、入力枠の幅・高さを検討 3. 各項目のCFIDを確認(Redmine標準機能) 4. 区切線/見出しを付ける場合は、直後のCFIDを確認 5. ソース調整/CSS調整 (ソース変更時はRedmine再起動要,CSSは再起動不要) 注意事項 ・Redmineコアのソースファイルを編集します。 VUP毎に実施必要(大半はコピペ) ・ファイルはUTF-8で保存必要 ・(以下、カスタムフィールド=CFと略記) 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 8
  9. 9. ソース変更内容 対象ソースファイ ル (機能)変更内容 VUP時作業 項目変更 時対応 /app/views/issues/sh ow.html.erb (表示)render_custom_fields_rows呼 び出し箇所を別名に変更 Patch/コピペ 不要 /app/helpers/issues_ helper.rb (表示)render_custom_fields_rowsを 別名で保存し変更 ・CFを一列表示化 ・指定CF直前に見出表示 ・CF種別毎タグ調整(改行有無の対 応など) Patch/コピペ 変更有 /app/views/issues/_f orm_custom_fields.h tml.erb (編集) 表示一列化 CFID毎に処理変更(見出し、改行、、) Patch/コピペ+ α 変更有 /app/helpers/custom _fields_helper.rb (編集)CF表示制御処理を追加 (label,preタグ有無、定型処理) Patch/コピペ 不要 /public/themes/名 前/application.css 各CFの編集幅/高さ指定 ファイルコ ピー 変更有 単純にチケット表示/編集のHTML出力部分 を変更しているだけです。。。 CF:カスタムフィールド、UTF-8でファイル保存 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 9
  10. 10. HTMLタグ変更内容 • 行単位出力化 • <p> </p>行頭/行末のみ出力 • <tr><th>1行単位</th></tr>、<td>項目単位</td> • 項目名の太字化は<th>の代わりに<b>利用 • ThのCSSは無視、tdのCSSは出力 • 区切り線と見出しは、単に<hr><h2>見出しを出 力 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 10
  11. 11. 実施効果 • Redmineの利用可能分野拡大 (カスタムフィールドの管理項目多用、既存帳票移行) • 利用者の作業効率向上 • →Redmine管理者の株価上昇 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 11
  12. 12. 禁断のソース変更 • ソース変更はVUPの妨げとなる為、一般に非推奨です。 • 今回の変更は単純で見通し良いので、自分はコピペ 程度の作業で3年間更新し続けました。 • 変更はViewのみでDB差異無し→戻せばOKの安心感 • テキストファイルのため、再コンパイル等は無用。 Redmine自身の再起動のみ。(愛しのInternalError500 (嘘)) • Gem,RAILS,Ruby,,依存関係/Ver非互換でハマるより楽。 • 自分はソース変更でペイしたと考えています。 しかし、、、→次頁 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 12
  13. 13. パッチの関係、3年でついに破局 • Redmine3.2で、改造部分の処理が大幅に変更された。 (rev14846 helpers/issues_helper.rb) • http://www.redmine.org/projects/redmine/repository/revisions/14846 • Use #issue_fields_rows to render custom fields values. • 3.2上の従来改造コードでも、現時点では正常に動作 しているが、今後の動作は不明。 • Rev14846は、関連チケット番号が記入されず、 本家ロードマップにも無く、redmine.jpにも記載無し。 SVNから追掛け必要?。。チケット駆動.. • 本稿作成過程で判明。 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 13
  14. 14. 今後の対応(他力本願) • 本手法は、Redmineソース変更以外に、 プラグイン/標準取込により実装可能です。 • 1行表示の選択切替(トラッカー、プロジェクト選択) • 各カスタムフィールド前後のHTMLタグ出力をWeb上で設定 可能にする。 (CF前後の改行有無、見出し、入力幅/高さ) • カスタムフィールドの表示幅-CSSファイルの書換 • メリット • ソース変更不可の環境でも利用可能になる。 • 追加/変更時のRedmine再起動不要 • ということで、どなたか、、 #本家チケット要?アカウント作成しましたが 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 14
  15. 15. 結論 • ソース修正で対応できるのはOSSの特権 • Plugin/運用対応より、楽に見通し良く解決できる場合もある。 • 過度に恐れず、適材適所で利用。 できるだけ単純に見通し良く。 ・より多くの環境で有効利用できれば良い • 標準取込/プラグイン対応も選択肢(役に立つなら) • パッチの賞味期限→標準取込最強。 • みんなでRedmineを(もっと)良くしよう 自分ができることから。 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 15
  16. 16. ソース変更内容詳細 • お断り • 実際のカスタムフィールドIDに合わせて設定必要です。 間違うと画面が福笑いになります。 • 処理不十分な箇所もあります。参考程度にお願いしま す。 • 最新(3.2以降)の処理には追随できていません。 (3.2で一応動いてはいますが) 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 16
  17. 17. _form_custom_fields.html.erb (編集画面のHTML出力) <% custom_field_values = @issue.editable_custom_field_values %> <% if custom_field_values.present? %> <div class="splitcontent"> <% split_on = custom_field_values.size %> <% custom_field_values.each do |value| %> <% case value.custom_field_id when 4 %> <hr><h2>障害現象</h2> <% when 3 %> <hr><h2>原因</h2> <% when 10 %> <hr><h2>処置</h2> <% end %> <% case (0+value.custom_field_id) when 4,6,3 %> <p> <%= custom_field_tag_with_label_nopre :issue, value , :required => @issue.required_attribute?(value.custom_field_id) %> <% when 5,1,7 %> <%= custom_field_tag_without_label_nopre :issue, value , :required => @issue.required_attribute?(value.custom_field_id) %> <% when 13,2,8 %> <%= custom_field_tag_without_label_nopre :issue, value , :required => @issue.required_attribute?(value.custom_field_id) %> </p> <% else %> <p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p > <% end %> <% end %> </div> <% end %> セクション 最初のフィールド 区切り線+見出し 行頭 行末 行途中 1項目1行 CFID場合分け CFID場合分け 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 17
  18. 18. custom_fields_helper.rb 追加分 (編集画面の共通処理追加) # modified from custom_field_label_tag # remove label tag , field name BOLD tag def custom_field_nolabel_tag(name, custom_value, options={}) required = options[:required] || custom_value.custom_field.is_required? title = custom_value.custom_field.description.presence content = content_tag 'span', custom_value.custom_field.name, :title => title content_required= (required ? " <span class="required">*</span>".html_safe : "") "<B>"+content + "</B>" + content_required end # Return custom field tag with its label, p tag exclude # Top <p><label -> <label # Buttom </p> -> None def custom_field_tag_with_label_nopre(name, custom_value, options={}) tag_org=(custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)).strip tag_org.sub(/A<p>/,'').sub(/</p>Z/,'').html_safe end # Return custom field tag with its label, p tag exclude # Top <p><label -> None # Buttom </p> -> None # label tag -> None def custom_field_tag_without_label_nopre(name, custom_value, options={}) tag_org=(custom_field_nolabel_tag(name, custom_value, options) + custom_field_tag(name, custom_value)).strip tag_org.sub(/A<p>/,'').sub(/</p>Z/,'').html_safe • end 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 18
  19. 19. issues_helper.rb 追加分(1) (表示画面のHTML出力) # modified from render_custom_fields_rows def render_custom_fields_rows_example(issue) return if issue.custom_field_values.empty? # HTML出力文字列の生成(1列化) s = "" issue.custom_field_values.compact.each do |value| css = "cf_#{value.custom_field.id}" case value.custom_field_id when 4 s << "n<hr>n" s << "<tr>nt<th><h2>障害現象 </h2></th><td></td>n</tr>n" when 3 s << "n<hr>n" s << "<tr>nt<th><h2>原因 </h2></th><td></td>n</tr>n" when 10 s << "n<hr>n" s << "<tr>nt<th><h2>処置 </h2></th><td></td>n</tr>n" end case value.custom_field_id when 4,6,3 # 編集では <p><%= custom_field_tag_with_label_nopre :issue, value %> # 1列目(2列目あり) # 表の行を終わらせない s << "<tr>nt<th><b>#{ h(value.custom_field.name) }</b>: " s << "</th>" s << "<td>#{ simple_format_without_paragraph(h(show_value( value))) } " 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 19
  20. 20. issues_helper.rb 追加分(2) (表示画面のHTML出力) when 13,2,8 # 編集では <%= custom_field_tag_without_label_nopre :issue, value %></p> # 最終列(2列目以降で) # <td>後の途中から始まるth,tdはSP2つで代替 # 最終列なので</td>以降は変化無し s << "、<b>#{ h(value.custom_field.name) }</b>:" s << " " s << "#{ simple_format_without_paragraph(h(show_value(value ))) }</td>n</tr><br>" when 5,1,7 # 編集では <%= custom_field_tag_without_label_nopre :issue, value %> # 3列以上の途中 # <td>後の途中から始まるth,tdはSP2つで代替 # 最終列ではないので</td>以降も省略する。 s << "、<b>#{ h(value.custom_field.name) }</b>:" s << " " s << "#{ simple_format_without_paragraph(h(show_value(value ))) } " else # 編集では <p> <%= custom_field_tag_with_label :issue, value %> </p> # 1列のみ項目-オリジナルを基にした。(CSS対応含む) s << "<tr>n" s << "t<th class="#{css}"><b>#{ h(value.custom_field.name) }</ b>:</th><td class="#{css}">#{ h(show_value(value)) }</td><br>" end end s.html_safe end 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 20
  21. 21. application.css show.html.erb変更分 Application.css 末尾追加分 textarea#issue_custom_field_values_14 { width: 95%; max-height: 150px; height: 70px; } select#issue_custom_field_values_4 { width: 5em; } select#issue_custom_field_values_5 { width: 5em; } select#issue_custom_field_values_13 { width: 15em; } select#issue_custom_field_values_6 { width: 7em; } select#issue_custom_field_values_1 { width: 12em; } select#issue_custom_field_values_2 { width: 12em; } select#issue_custom_field_values_11 { width: 7em; } textarea#issue_custom_field_values_9 { width: 95%; max-height: 150px; height: 50px; } select#issue_custom_field_values_3 { width: 12em; } select#issue_custom_field_values_7 { width: 8em; } select#issue_custom_field_values_8 { width: 8em; } textarea#issue_custom_field_values_10 { width: 95%; max-height: 150px; height: 50px; } Show.html.erb (表示)render_custom_fields_rows呼び出し箇所を別名に変更 2016/5/15 第10回redmine.tokyo 勉強会 Redminekカスタムフィールド表示改善 @y503unavailable 21 CSSの設定/確認については、onozaty さんの下記資料など参照 application.cssを変更しなくとも、View customize上で対応可能と思います。 View customize plugin を使いこなす! http://www.slideshare.net/onozaty/vie w-customizeplugin-62005780 Redmineの画面で振られているclass属 性について http://blog.enjoyxstudy.com/entry/201 4/10/11/000000

×