概要¶
性質上、RedmineのチケットやWikiにコードを貼り付ける機会は多々あると思います。
と、コードで囲まれている部分の脇にコピーボタンをつけて、コピペの手間を軽減します。
確認した環境¶
Redmine 5.1
さっくりとした手順¶
- 設定ファイル(4個分)のバックアップを取ります。
- パッチファイル(4個分)を作成します。
- 4つのファイルに対してパッチを適用します。
- Webサービスを再起動します。
ファイルのバックアップ¶
app/views/journals/new.js.erb
sudo cp -pi /redmine/root/directory/app/views/journals/new.js.erb /path/to/backup/directory/new.js.erb.$(date +%Y%m%d)
app/views/journals/update.js.erb
sudo cp -pi /redmine/root/directory/app/views/journals/update.js.erb /path/to/backup/directory/update.js.erb.$(date +%Y%m%d)
public/javascripts/application.js
sudo cp -pi /redmine/root/directory/public/javascripts/application.js /path/to/backup/directory/application.js.erb.$(date +%Y%m%d)
public/stylesheets/application.css
sudo cp -pi /redmine/root/directory/public/stylesheets/application.css /path/to/backup/directory/application.css.erb.$(date +%Y%m%d)
/redmine/root/directory
は、自分の環境に合わせます。(var/lib/redmine
など)
また、/path/to/backup/directtory
は任意のバックアップディレクトリを指定します。
ファイルのバックアップ確認¶
app/views/journals/new.js.erb
diff -u /path/to/backup/directory/new.js.erb.$(date +%Y%m%d) /redmine/root/directory/app/views/journals/new.js.erb
app/views/journals/update.js.erb
diff -u /path/to/backup/directory/update.js.erb.$(date +%Y%m%d) /redmine/root/directory/app/views/journals/update.js.erb
public/javascripts/application.js
diff -u /path/to/backup/directory/application.js.erb.$(date +%Y%m%d) /redmine/root/directory/public/javascripts/application.js
public/stylesheets/application.css
diff -u /path/to/backup/directory/application.css.erb.$(date +%Y%m%d) /redmine/root/directory/public/stylesheets/application.css
それぞれ、バックアップしたファイル → バックアップ元ファイルで差分(diff)を取り、エラーがないこと(差分が無いこと)でバックアップを確認します。
パッチファイル作成¶
cd /hoge && pwd
任意の作業ディレクトリに移動します。
- new.js.erb.patch
tee new.js.erb.patch > /dev/null << 'EOF'
--- new.js.erb
+++ new.js.erb.patch
@@ -11,3 +11,4 @@
$('#issue_private_notes').prop('checked', true);
<% end %>
+addCopyButtonToPreTag();
EOF
- update.js.erb.patch
tee update.js.erb.patch > /dev/null << 'EOF'
--- update.js.erb
+++ update.js.erb.patch
@@ -7,6 +7,7 @@
$("#journal-<%= @journal.id %>-notes").replaceWith('<%= escape_javascript(render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))) %>');
$("#journal-<%= @journal.id %>-notes").show();
$("#journal-<%= @journal.id %>-form").remove();
+ addCopyButtonToPreTag();
var journal_header = $("#change-<%= @journal.id %>>div.note>h4.note-header");
var journal_updated_info = journal_header.find("span.update-info");
if (journal_updated_info.length > 0) {
EOF
- application.js.patch
tee application.js.patch > /dev/null << 'EOF'
--- application.js
+++ application.js.patch
@@ -1123,6 +1123,49 @@
});
});
+function addCopyButtonToPreTag() {
+ $('.wiki .copy-contents').remove();
+ var copyContents =
+ $("<div class='copy-contents'>").append(
+ $("<button class='code-copy-button' title='Copy' onclick='copyText($(this).parent().next(\"pre\"), $(this).parent());'>")
+ .append("<span class='icon-only icon-copy'>")
+ );
+ $('.wiki pre').before(copyContents);
+ $('.code-copy-button[title]').tooltip({
+ show: {
+ delay: 400
+ },
+ position: {
+ my: "center bottom-5",
+ at: "center top"
+ }
+ });
+}
+function copyText(target, copyEl) {
+ // Selecting strings in 2 ways for cross-browser support
+ // 1. Use select();
+ copyEl.append("<textarea class='tmp'>");
+ var tmp = copyEl.find('.tmp');
+ tmp.val(target.text());
+ tmp.select();
+ // 2. Use createRange();
+ var range = document.createRange();
+ range.selectNode(target[0]);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ // Copy and Cleanup
+ var copied = document.execCommand('copy');
+ window.getSelection().removeAllRanges();
+ tmp.remove();
+ // Show copied messages
+ if (copied){
+ copyEl.append("<div class='copied-message'>Copied.</div>");
+ var copiedMessage = copyEl.find('.copied-message');
+ copiedMessage.show();
+ copiedMessage.fadeOut('slow', function() { $(this).remove(); });
+ }
+}
+
function inlineAutoComplete(element) {
'use strict';
@@ -1241,6 +1284,7 @@
$(document).ready(setupAttachmentDetail);
$(document).ready(setupTabs);
$(document).ready(setupFilePreviewNavigation);
+$(document).ready(addCopyButtonToPreTag);
$(document).ready(setupWikiTableSortableHeader);
$(document).on('focus', '[data-auto-complete=true]', function(event) {
inlineAutoComplete(event.target);
EOF
- application.css.patch
tee application.css.patch > /dev/null << 'EOF'
--- _old/application.css
+++ application.css.patch
@@ -449,6 +449,30 @@
height: initial;
}
+.copy-contents {
+ position: relative;
+}
+.copy-contents .code-copy-button {
+ position: absolute;
+ display: flex;
+ right: -13px;
+ top: 0px;
+ border: none;
+ background-color: transparent;
+}
+.copy-contents .copied-message {
+ position: absolute;
+ display: flex;
+ right: -13px;
+ top: 20px;
+ display: none;
+ color:#505050;
+}
+.copy-contents .tmp {
+ position: fixed;
+ left: 200%;
+}
+
EOF
パッチファイルの所有権変更¶
- 変更前確認
ls -l *.patch
上記、作成した4つのパッチがあり、作業アカウントが所有者になっていることを確認
- 所有者変更
sudo chown www-data:www-data *.patch
→ redmineの実行ユーザを指定します。
- 変更後確認
ls -l *.patch
4つのパッチの所有者がredminの実行ユーザーになっていることを確認
パッチ適用¶
-
app/views/journals/new.js.erb
にパッチ適用
sudo -u www-data patch /redmine/root/directory/app/views/journals/new.js.erb < /hoge/new.js.erb.patch
-
/app/views/journals/update.js.erb
にパッチ適用
sudo -u www-data patch /redmine/root/directory/app/views/journals/update.js.erb < /hoge/update.js.erb.patch
-
public/javascripts/application.js
にパッチ適用
sudo -u www-data patch /redmine/root/directory/public/javascripts/application.js < /hoge/application.js.patch
-
public/stylesheets/application.css
にパッチ適用
sudo -u www-data patch /redmine/root/directory/public/stylesheets/application.css < /hoge/application.css.patch
それぞれ、ファイルがある箇所を絶対パスで実行してください。特に、application.jsとapplication.cssの取り違えに注意ください。
パッチが上手くいかないときは?¶
エディタなどを利用して、
https://www.redmine.org/attachments/25075
の内容を、追記してください。
diffによるパッチ適用確認¶
- app/views/journals/new.js.erb
diff -u /path/to/backup/directory/new.js.erb.$(date +%Y%m%d) /redmine/root/directory/app/views/journals/new.js.erb
app/views/journals/update.js.erb
diff -u /path/to/backup/directory/update.js.erb.$(date +%Y%m%d) /redmine/root/directory/app/views/journals/update.js.erb
public/javascripts/application.js
diff -u /path/to/backup/directory/application.js.erb.$(date +%Y%m%d) /redmine/root/directory/public/javascripts/application.js
public/stylesheets/application.css
diff -u /path/to/backup/directory/application.css.erb.$(date +%Y%m%d) /redmine/root/directory/public/stylesheets/application.css
として、作成したパッチファイルと同じかを確認します。
設定反映¶
- Webサービス再起動
sudo systemctl restart apache2.service
- Webサービス再起動確認
systemctl status apache2.service
active(running)
を確認します。
上記適用後、
- コードブロックにコピーボタンがあり、
- ボタンクリックで内容がクリップボードに保存される
ことが確認できれば設定完了です。