Просмотр исходного кода

Merge pull request #289 from weseek/master

release v2.4.2
Yuki Takei 8 лет назад
Родитель
Сommit
720b8ce77b

+ 12 - 1
CHANGES.md

@@ -1,7 +1,17 @@
 CHANGES
 ========
 
-## 2.4.1-RC
+## 2.4.2-RC
+
+* Improvement: Ensure to set absolute url from root when attaching files when `FILE_UPLOAD=local`
+* Fix: Inline code blocks that includes doller sign are broken
+* Fix: Comment count is not updated when a comment of the page is deleted
+* Improvement: i18n in `/admin` (WIP)
+* Support: Upgrade libs
+    * googleapis
+    * markdown-it-plantuml
+
+## 2.4.1
 
 * Feature: Custom Header HTML
 * Improvement: Add highlight.js languages
@@ -12,6 +22,7 @@ CHANGES
     * Introduced by 2.4.0
 * Support: Upgrade libs
     * axios
+    * diff2html
 
 ## 2.4.0
 

+ 53 - 1
lib/locales/en-US/translation.json

@@ -39,6 +39,8 @@
   "Share Link": "Share Link",
   "Markdown Link": "Markdown Link",
 
+  "Management Wiki": "Management Wiki",
+
   "Unportalize": "Unportalize",
 
   "View this version": "View this version",
@@ -134,6 +136,9 @@
   "Current API Token": "Current API Token",
   "Update API Token": "Update API Token",
 
+  "Security settings": "Security settings",
+
+
   "page_page": {
       "notice": {
           "version": "This is not the current version.",
@@ -202,6 +207,53 @@
           "Outdent": "Outdent",
           "Save Page": "Save Page",
           "Delete Line": "Delete Line"
-      }
+
+              }
+  },
+            
+  "admin_top": { 
+    "Management Wiki": "Management Wiki",
+    "System Information": "System Information",
+    "wiki_administrator": "Only Wiki administrator can access this page",
+    "assign_administrator": "You can assign administrator from Assign administrator button in the User management page",
+    "List of installed plugins": "List of installed plugins",
+    "Package name": "Package name",
+    "Specified version": "Specified version",
+    "Installed version": "Installed version"
+    
+  },
+
+  "app_setting": {
+    "Wiki name": "Wiki name",
+    "wiki_change": "You can change Wiki name which is used for header and HTML title.",
+    "header_content": "The contents entered here will be shown in the header etc.",
+    "Confidential name": "Confidential name",
+    "ex): internal use only":"ex): internal use only",
+    "enable_files_except_image": "Enable file upload other than image files.",
+    "attach_enable": "You can attach files other than image files if you enable this option.",
+    "Reload": "Reload",
+    "Mail settings": "Mail settings",
+    "SMTP_used": "If you have SMTP settings, it will be used.",
+    "SMTP_but_AWS": "If you do not have SMTP settings but AWS settings,  e-mails will be sent by SES.",
+    "neihter_of": "If you do not of neither of these, e-mails will not be sent.",
+    "From e-mail address": "From e-mail address",
+    "SMTP settings": "SMTP settings"  , 
+    "Host": "Host",
+    "Port": "Port",
+    "User": "User",
+    "AWS settings": "AWS settings",
+    "AWS_access": "This is for AWS settings. If you complete AWS settings, file upload function, progile picture function etc will be enabled.",
+    "No_SMTP_setting": "If you do not have SMTP settings, e-mails will be sent via SES. You need to verify from e-mail address and production settings.",
+    "change_setting": "Caution:if you change this setting not completed, you will not be able to access files you have uploaded so far.",
+    "region": "region",
+    "packet name": "packet name",
+    "Plugin settings": "Plugin settings",
+    "Enable plugin loading": "Enable plugin loading",
+    "valid": "valid",
+    "invalid": "invalid"
+
+
   }
+
 }
+ 

+ 72 - 3
lib/locales/ja/translation.json

@@ -69,15 +69,34 @@
   "Input page name (optional)": "ページ名を入力(空欄OK)",
   "New Page": "新規ページ",
   "Create under": "<code>%s</code>以下に作成",
-
+  
+  
+ 
+  
   "Table of Contents": "目次",
-
+  "Management Wiki Home": "Wiki管理トップ",
+  "App settings": "アプリ設定",
+  "Security settings": "セキュリティ設定",
+  "Markdown settings": "Markdown設定",
+  "Customize": "カスタマイズ",
+  "Notification settings": "通知設定",
+  "User management": "ユーザー管理",
+  "Basic settings": "基本設定",
+  "Basic authentication": "Basic認証",
+  "Password": "パスワード",
+  "Guest users access": "ゲストユーザーのアクセス",
+  "Register limitation": "登録の制限",
+  "The contents entered here will be shown in the header etc": "ここに入力した内容は、ヘッダー等に表示されます。", 
   "Public": "公開",
   "Anyone with the link": "リンクを知っている人のみ",
   "Specified users": "特定ユーザーのみ",
   "Just me": "自分のみ",
   "Shareable link": "このページの共有用URL",
+  "The whitelist of registration permission E-mail address": "登録許可メールアドレスの<br>ホワイトリスト",
+  "Selecting authentication mechanism": "認証機構選択",
 
+  
+ 
   "Show latest": "最新のページを表示",
   "Load latest": "最新版を読み込む",
   "edited this page": "さんがこのページを編集しました。",
@@ -128,6 +147,8 @@
   "Password is not set": "パスワードが設定されていません",
   "You can sign in with email and password": "<code>%s</code> と設定されたパスワードの組み合わせでログイン可能になります。",
 
+  "Security settings": "セキュリティ設定",
+
   "API Settings": "API設定",
   "API Token Settings": "API Token設定",
   "Current API Token": "現在のAPI Token",
@@ -148,6 +169,9 @@
       }
   },
 
+
+  
+
   "modal_rename": {
     "label": {
       "Rename page": "ページを移動する",
@@ -200,5 +224,50 @@
         "Save Page": "保存",
         "Delete Line": "行削除"
     }
-}
+  },
+   
+  "admin_top": {
+    "Management Wiki": "Wiki管理",
+    "System Information": "システム情報",
+    "wiki_administrator": "この画面はWiki管理者のみがアクセスできる画面です。",
+    "assign_administrator": "「ユーザー管理」から「管理者にする」ボタンを使ってユーザーをWiki管理者に任命することができます。",
+    "List of installed plugins": "インストールされているプラグイン一覧",
+    "Package name": "パッケージ名",
+    "Specified version": "指定バージョン",
+    "Installed version": "インストールされているバージョン"
+  
+  
+  
+  },
+
+  "app_setting": { 
+    "Wiki name": "Wikiの名前",
+    "wiki_change": "ヘッダーやHTMLタイトルに使用されるWikiの名前を変更できます。",
+    "header_content": "ここに入力した内容は、ヘッダー等に表示されます。",
+    "Confidential name": "コンフィデンシャル表示",
+    "コンフィデンシャル表示": "Confidential name",  
+    "enable_files_except_image": "画像以外のファイルアップロードを許可",
+    "attach_enable": "許可をしている場合、画像以外のファイルをページに添付可能になります。",
+    "Reload": "更新",
+    "Mail settings": "メールの設定",
+    "SMTP_used": "SMTPの設定がされている場合、それが利用されます。",
+    "SMTP_but_AWS": "SMTP設定がなく、AWSの設定がある場合、SESでの送信を試みます。",
+    "neihter_of": "どちらの設定もない場合、メールは送信されません。",
+    "From e-mail address": "Fromアドレス",
+    "SMTP settings": "SMTP設定"   ,
+    "Host": "ホスト",
+    "Port": "ポート",
+    "User": "ユーザー",
+    "AWS settings": "AWS設定",
+    "AWS_access": "AWS にアクセスするための設定を行います。AWS の設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。",
+    "No_SMTP_setting": "また、SMTP の設定が無い場合、SES を利用したメール送信が行われます。FromメールアドレスのVerify、プロダクション利用設定をする必要があります。",
+    "change_setting": "この設定を途中で変更すると、これまでにアップロードしたファイル等へのアクセスができなくなりますのでご注意下さい。",
+    "region": "リージョン",
+    "packet name": "パケット名",
+    "Plugin settings": "プラグイン設定",
+    "Enable plugin loading": "プラグインの読み込みを有効にします。",
+    "valid": "有効",
+    "invalid": "無効"
+
+   }
 }

+ 2 - 4
lib/models/comment.js

@@ -122,10 +122,8 @@ module.exports = function(crowi) {
       , Comment = crowi.model('Comment')
     ;
 
-    Comment.countCommentByPageId(savedComment.page)
-    .then(function(count) {
-      return Page.updateCommentCount(savedComment.page, count);
-    }).then(function(page) {
+    Page.updateCommentCount(savedComment.page)
+    .then(function(page) {
       debug('CommentCount Updated', page);
     }).catch(function() {
     });

+ 9 - 7
lib/models/page.js

@@ -16,7 +16,8 @@ module.exports = function(crowi) {
 
     , pageEvent = crowi.event('page')
 
-    , pageSchema;
+    , pageSchema
+    , Comment = crowi.model('Comment');
 
   function isPortalPath(path) {
     if (path.match(/.*\/$/)) {
@@ -305,18 +306,19 @@ module.exports = function(crowi) {
     });
   };
 
-  pageSchema.statics.updateCommentCount = function (page, num)
+  pageSchema.statics.updateCommentCount = function (pageId)
   {
     var self = this;
-
-    return new Promise(function(resolve, reject) {
-      self.update({_id: page}, {commentCount: num}, {}, function(err, data) {
+    var Comment = crowi.model("Comment");
+    return Comment.countCommentByPageId(pageId)
+    .then(function(count) {
+      self.update({_id: pageId}, {commentCount: count}, {}, function(err, data) {
         if (err) {
           debug('Update commentCount Error', err);
-          return reject(err);
+          throw err;
         }
 
-        return resolve(data);
+        return data;
       });
     });
   };

+ 0 - 5
lib/routes/attachment.js

@@ -145,11 +145,6 @@ module.exports = function(crowi, app) {
           var fileUrl = data.fileUrl;
           var config = crowi.getConfig();
 
-          // isLocalUrl??
-          if (!fileUrl.match(/^https?/)) {
-            fileUrl = (config.crowi['app:url'] || '') + fileUrl;
-          }
-
           var result = {
             page: page.toObject(),
             attachment: data.toObject(),

+ 14 - 6
lib/routes/comment.js

@@ -82,15 +82,23 @@ module.exports = function(crowi, app) {
   api.remove = function(req, res){
     var commentId = req.body.comment_id;
     if (!commentId) {
-      return res.json(ApiResponse.error(`'comment_id' is undefined`));
+      return Promise.resolve(res.json(ApiResponse.error(`'comment_id' is undefined`)));
     }
 
-    return Comment.remove({_id: commentId})
-      .then(function() {
-        return res.json(ApiResponse.success({}));
-      }).catch(function(err) {
-        return res.json(ApiResponse.error(err));
+    return Comment.findById(commentId).exec()
+      .then(function(comment) {
+        return comment.remove()
+        .then(function() {
+           return Page.updateCommentCount(comment.page);
+        })
+        .then(function() {
+           return res.json(ApiResponse.success({})); 
+        });
+      })
+      .catch(function(err) {
+        return res.json(ApiResponse.error(err)); 
       });
+
   };
 
   return actions;

+ 22 - 22
lib/views/admin/app.html

@@ -1,11 +1,11 @@
 {% extends '../layout/admin.html' %}
 
-{% block html_title %}アプリ設定 · {% endblock %}
+{% block html_title %}{{ t('App settings') }} · {% endblock %}
 
 {% block content_head %}
 <div class="header-wrap">
   <header id="page-header">
-    <h1 class="title" id="">アプリ設定</h1>
+    <h1 class="title" id="">{{ t('App settings') }}</h1>
   </header>
 </div>
 {% endblock %}
@@ -34,21 +34,21 @@
 
       <form action="/_api/admin/settings/app" method="post" class="form-horizontal" id="appSettingForm" role="form">
       <fieldset>
-        <legend>アプリ設定</legend>
+        <legend>{{ t('App settings') }}</legend>
         <div class="form-group">
-          <label for="settingForm[app:title]" class="col-xs-3 control-label">Wikiの名前</label>
+          <label for="settingForm[app:title]" class="col-xs-3 control-label">{{ t('app_setting.Wiki name') }}</label>
           <div class="col-xs-6">
             <input class="form-control" type="text" name="settingForm[app:title]" value="{{ settingForm['app:title'] }}">
 
-            <p class="help-block">ヘッダーやHTMLタイトルに使用されるWikiの名前を変更できます。</p>
+            <p class="help-block">{{ t("app_setting.wiki_change") }}</p>
           </div>
         </div>
 
         <div class="form-group">
-          <label for="settingForm[app:confidential]" class="col-xs-3 control-label">コンフィデンシャル表示</label>
+          <label for="settingForm[app:confidential]" class="col-xs-3 control-label">{{ t('app_setting.Confidential name') }}</label>
           <div class="col-xs-6">
-            <input class="form-control" type="text" name="settingForm[app:confidential]" value="{{ settingForm['app:confidential'] }}" placeholder="例: 社外秘">
-            <p class="help-block">ここに入力した内容は、ヘッダー等に表示されます。</p>
+            <input class="form-control" type="text" name="settingForm[app:confidential]" value="{{ settingForm['app:confidential'] }}" placeholder="{{ t('app_setting. ex): internal use only') }}">
+            <p class="help-block">{{ t("app_setting.header_content") }}</p>
           </div>
         </div>
 
@@ -63,11 +63,11 @@
               {% else %}
               {% endif %}
               >
-              <label for="settingForm[app:fileUpload]" class="">画像以外のファイルアップロードを許可</label>
+              <label for="settingForm[app:fileUpload]" class="">{{ t("app_setting.enable_files_except_image") }}</label>
 
               <p class="help-block">
-                ファイルアップロードの設定を有効にしている場合にのみ、選択可能です。<br>
-                許可をしている場合、画像以外のファイルをページに添付可能になります。
+                {{ t("app_setting.enable_files_except_image") }}<br>
+                {{ t("app_setting.attach_enable") }}
               </p>
           </div>
         </div>
@@ -75,7 +75,7 @@
         <div class="form-group">
           <div class="col-xs-offset-3 col-xs-6">
             <input type="hidden" name="_csrf" value="{{ csrf() }}">
-            <button type="submit" class="btn btn-primary">更新</button>
+            <button type="submit" class="btn btn-primary">{{ t('app_setting.Reload') }}</button>
           </div>
         </div>
       </fieldset>
@@ -83,35 +83,35 @@
 
       <form action="/_api/admin/settings/mail" method="post" class="form-horizontal" id="mailSettingForm" role="form">
       <fieldset>
-      <legend>メールの設定</legend>
-      <p class="well">SMTPの設定がされている場合、それが利用されます。SMTP設定がなく、AWSの設定がある場合、SESでの送信を試みます。<br>どちらの設定もない場合、メールは送信されません。</p>
+      <legend>{{ t('app_setting.Mail settings') }}</legend>
+      <p class="well">{{ t("app_setting.SMTP_used") }} {{ t("app_setting.SMTP_but_AWS") }}<br>{{ t("app_setting.neihter_of") }}</p>
 
         <div class="form-group">
-          <label for="settingForm[mail.from]" class="col-xs-3 control-label">Fromアドレス</label>
+          <label for="settingForm[mail.from]" class="col-xs-3 control-label">{{ t('app_setting.From e-mail address') }}</label>
           <div class="col-xs-6">
             <input class="form-control" type="text" name="settingForm[mail:from]" placeholder="例: mail@crowi.wiki" value="{{ settingForm['mail:from'] }}">
           </div>
         </div>
 
         <div class="form-group">
-          <label class="col-xs-3 control-label">SMTP設定</label>
+          <label class="col-xs-3 control-label">{{ t('app_setting.SMTP settings') }}</label>
           <div class="col-xs-4">
-            <label for="">ホスト</label>
+            <label for="">{{ t('app_setting.Host') }}</label>
             <input class="form-control" type="text" name="settingForm[mail:smtpHost]"   value="{{ settingForm['mail:smtpHost']|default('') }}">
           </div>
           <div class="col-xs-2">
-            <label for="">ポート</label>
+            <label for="">{{ t('app_setting.Port') }}</label>
             <input class="form-control" type="text" name="settingForm[mail:smtpPort]" value="{{ settingForm['mail:smtpPort']|default('') }}">
           </div>
         </div>
 
         <div class="form-group">
           <div class="col-xs-3 col-xs-offset-3">
-            <label for="">ユーザー</label>
+            <label for="">{{ t('app_setting.User') }}</label>
             <input class="form-control" type="text" name="settingForm[mail:smtpUser]"   value="{{ settingForm['mail:smtpUser']|default('') }}">
           </div>
           <div class="col-xs-3">
-            <label for="">パスワード</label>
+            <label for="">{{ t('Password') }}</label>
             <input class="form-control" type="password" name="settingForm[mail:smtpPassword]" value="{{ settingForm['mail:smtpPassword']|default('') }}">
           </div>
         </div>
@@ -119,7 +119,7 @@
         <div class="form-group">
           <div class="col-xs-offset-3 col-xs-6">
             <input type="hidden" name="_csrf" value="{{ csrf() }}">
-            <button type="submit" class="btn btn-primary">更新</button>
+            <button type="submit" class="btn btn-primary">{{ t('app_setting.Reload') }}</button>
           </div>
         </div>
 
@@ -128,7 +128,7 @@
 
       <form action="/_api/admin/settings/aws" method="post" class="form-horizontal" id="awsSettingForm" role="form">
       <fieldset>
-      <legend>AWS設定</legend>
+      <legend>{{ t('app_setting.AWS settings') }}</legend>
         <p class="well">AWS にアクセスするための設定を行います。AWS の設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。<br>
         また、SMTP の設定が無い場合、SES を利用したメール送信が行われます。FromメールアドレスのVerify、プロダクション利用設定をする必要があります。<br>
           <br>

+ 9 - 10
lib/views/admin/index.html

@@ -1,11 +1,11 @@
 {% extends '../layout/admin.html' %}
 
-{% block html_title %}Wiki管理 · {{ path }}{% endblock %}
+{% block html_title %}Wiki管理· {{ path }}{% endblock %}
 
 {% block content_head %}
 <div class="header-wrap">
   <header id="page-header">
-    <h1 class="title" id="">Wiki管理</h1>
+    <h1 class="title" id=""> {{ t('admin_top.Management Wiki') }}</h1>
   </header>
 </div>
 {% endblock %}
@@ -25,12 +25,11 @@
       {% include './widget/menu.html' %}
     </div>
     <div class="col-md-9">
-      <p>
-      この画面はWiki管理者のみがアクセスできる画面です。<br>
-      「ユーザー管理」から「管理者にする」ボタンを使ってユーザーをWiki管理者に任命することができます。
+      <p> {{ t("admin_top.wiki_administrator") }}<br>
+      {{ t("admin_top.assign_administrator") }}
       </p>
 
-      <h3>システム情報</h3>
+      <h3>{{ t('admin_top.System Information') }}</h3>
       <table class="table table-bordered">
         <tr>
           <th class="col-sm-4">crowi-plus</th>
@@ -50,16 +49,16 @@
         </tr>
       </table>
 
-      <h3>インストールされているプラグイン一覧</h3>
+      <h3>{{ t('admin_top.List of installed plugins') }}</h3>
       <table class="table table-bordered">
         <th class="text-center">
-          パッケージ名
+          {{ t('admin_top.Package name') }}
         </th>
         <th class="text-center">
-          指定バージョン
+          {{ t('admin_top.Specified version') }}
         </th>
         <th class="text-center">
-          インストールされているバージョン
+          {{ t('admin_top.Installed version') }}
         </th>
         {% for pluginName in Object.keys(plugins) %}
         <tr>

+ 9 - 9
lib/views/admin/security.html

@@ -5,7 +5,7 @@
 {% block content_head %}
 <div class="header-wrap">
   <header id="page-header">
-    <h1 class="title" id="">カスタマイズ</h1>
+    <h1 class="title" id="">{{ t('Security settings') }}</h1>
   </header>
 </div>
 {% endblock %}
@@ -38,16 +38,16 @@
 
       <form action="/_api/admin/security/general" method="post" class="form-horizontal" id="generalSetting" role="form">
         <fieldset>
-        <legend>基本設定</legend>
+        <legend>{{ t('Security settings') }}</legend>
 
           <div class="form-group">
-            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">Basic認証</label>
+            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">{{ t('Basic authentication') }}</label>
             <div class="col-xs-3">
               <label for="">ID</label>
               <input class="form-control" type="text" name="settingForm[security:basicName]"   value="{{ settingForm['security:basicName']|default('') }}">
             </div>
             <div class="col-xs-3">
-              <label for="">パスワード</label>
+              <label for="">{{ t('Password') }}</label>
               <input class="form-control" type="text" name="settingForm[security:basicSecret]" value="{{ settingForm['security:basicSecret']|default('') }}">
             </div>
             <div class="col-xs-offset-3 col-xs-9">
@@ -59,7 +59,7 @@
           </div>
 
           <div class="form-group">
-            <label for="settingForm[security:restrictGuestMode]" class="col-xs-3 control-label">ゲストユーザーのアクセス</label>
+            <label for="settingForm[security:restrictGuestMode]" class="col-xs-3 control-label">{{ t('Guest users access') }}</label>
             <div class="col-xs-6">
               <select class="form-control" name="settingForm[security:restrictGuestMode]" value="{{ settingForm['security:restrictGuestMode'] }}">
                 {% for modeValue, modeLabel in consts.restrictGuestMode %}
@@ -70,19 +70,19 @@
           </div>
 
           <div class="form-group">
-            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">登録の制限</label>
+            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">{{ t('Register limitation') }}</label>
             <div class="col-xs-6">
               <select class="form-control" name="settingForm[security:registrationMode]" value="{{ settingForm['security:registrationMode'] }}">
                 {% for modeValue, modeLabel in consts.registrationMode %}
                 <option value="{{ modeValue }}" {% if modeValue == settingForm['security:registrationMode'] %}selected{% endif %} >{{ modeLabel }}</option>
                 {% endfor %}
               </select>
-              <p class="help-block">ここに入力した内容は、ヘッダー等に表示されます。</p>
+              <p class="help-block">{{ t('The contents entered here will be shown in the header etc') }}</p>
             </div>
           </div>
 
           <div class="form-group">
-            <label for="settingForm[security:registrationWhiteList]" class="col-xs-3 control-label">登録許可メールアドレスの<br>ホワイトリスト</label>
+            <label for="settingForm[security:registrationWhiteList]" class="col-xs-3 control-label">{{ t('The whitelist of registration permission E-mail address') }}</label>
             <div class="col-xs-8">
               <textarea class="form-control" type="textarea" name="settingForm[security:registrationWhiteList]" placeholder="例: @crowi.wiki">{{ settingForm['security:registrationWhiteList']|join('&#13')|raw }}</textarea>
               <p class="help-block">登録可能なメールアドレスを制限することができます。例えば、会社で使う場合、<code>@crowi.wiki</code> などと記載すると、その会社のメールアドレスを持っている人のみ登録可能になります。<br>
@@ -102,7 +102,7 @@
 
       <form action="/_api/admin/security/mechanism" method="post" class="form-horizontal" id="mechanismSetting" role="form">
         <fieldset>
-          <legend>認証機構選択</legend>
+          <legend>{{ t('Selecting authentication mechanism') }}</legend>
           <p class="alert alert-info"><b>NOTE: </b>Restarting the server is needed if you switch the auth mechanism.</p>
           <div class="form-group">
             <div class="col-xs-6">

+ 7 - 7
lib/views/admin/widget/menu.html

@@ -2,13 +2,13 @@
   {% set current = 'index' %}
 {% endif  %}
 <ul class="nav nav-pills nav-stacked">
-  <li class="{% if current == 'index'%}active{% endif %}"><a href="/admin"><i class="fa fa-cube"></i> Wiki管理トップ</a></li>
-  <li class="{% if current == 'app'%}active{% endif %}"><a href="/admin/app"><i class="fa fa-gears"></i> アプリ設定</a></li>
-  <li class="{% if current == 'security'%}active{% endif %}"><a href="/admin/security"><i class="fa fa-shield"></i> セキュリティ設定</a></li>
-  <li class="{% if current == 'markdown'%}active{% endif %}"><a href="/admin/markdown"><i class="fa fa-pencil"></i> Markdown設定</a></li>
-  <li class="{% if current == 'customize'%}active{% endif %}"><a href="/admin/customize"><i class="fa fa-object-group"></i> カスタマイズ</a></li>
-  <li class="{% if current == 'notification'%}active{% endif %}"><a href="/admin/notification"><i class="fa fa-bell"></i> 通知設定</a></li>
-  <li class="{% if current == 'user' || current == 'external-account' %}active{% endif %}"><a href="/admin/users"><i class="fa fa-users"></i> ユーザー管理</a></li>
+  <li class="{% if current == 'index'%}active{% endif %}"><a href="/admin"><i class="fa fa-cube"></i> {{ t('Management Wiki Home') }}</a></li>
+  <li class="{% if current == 'app'%}active{% endif %}"><a href="/admin/app"><i class="fa fa-gears"></i>{{ t('App settings') }}</a></li>
+  <li class="{% if current == 'security'%}active{% endif %}"><a href="/admin/security"><i class="fa fa-shield"></i> {{ t('Security settings') }}</a></li>
+  <li class="{% if current == 'markdown'%}active{% endif %}"><a href="/admin/markdown"><i class="fa fa-pencil"></i> {{ t('Markdown settings') }}</a></li>
+  <li class="{% if current == 'customize'%}active{% endif %}"><a href="/admin/customize"><i class="fa fa-object-group"></i> {{ t('Customize') }}</a></li>
+  <li class="{% if current == 'notification'%}active{% endif %}"><a href="/admin/notification"><i class="fa fa-bell"></i> {{ t('Notification settings') }}</a></li>
+  <li class="{% if current == 'user' || current == 'external-account' %}active{% endif %}"><a href="/admin/users"><i class="fa fa-users"></i> {{ t('User management') }}</a></li>
   {% if searchConfigured() %}
   <li class="{% if current == 'search'%}active{% endif %}"><a href="/admin/search"><i class="fa fa-search"></i> 検索管理</a></li>
   {% endif %}

+ 3 - 3
package.json

@@ -1,6 +1,6 @@
 {
   "name": "crowi-plus",
-  "version": "2.4.1-RC",
+  "version": "2.4.2-RC",
   "description": "Enhanced Crowi",
   "tags": [
     "wiki",
@@ -84,7 +84,7 @@
     "express-session": "~1.15.0",
     "express-webpack-assets": "^0.1.0",
     "file-loader": "^1.1.0",
-    "googleapis": "^26.0.0",
+    "googleapis": "^27.0.0",
     "graceful-fs": "^4.1.11",
     "i18next": "^10.0.1",
     "i18next-express-middleware": "^1.0.5",
@@ -98,7 +98,7 @@
     "markdown-it-footnote": "^3.0.1",
     "markdown-it-mathjax": "^2.0.0",
     "markdown-it-named-headers": "^0.0.4",
-    "markdown-it-plantuml": "^0.3.1",
+    "markdown-it-plantuml": "^1.0.0",
     "markdown-it-task-lists": "^2.1.0",
     "markdown-it-toc-and-anchor-with-slugid": "^1.1.2",
     "md5": "^2.2.1",

+ 3 - 4
resource/js/util/interceptor/detach-code-blocks.js

@@ -1,6 +1,3 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
 import { BasicInterceptor } from 'crowi-pluginkit';
 
 
@@ -107,7 +104,9 @@ export class RestoreCodeBlockInterceptor extends BasicInterceptor {
       // get context object from context
       let dcbContext = context.dcbContextMap[replaceId];
 
-      context.markdown = context.markdown.replace(dcbContext.substituteContent, dcbContext.content);
+      // replace it with content by using getter function so that the doller sign does not work
+      // see: https://github.com/weseek/crowi-plus/issues/285
+      context.markdown = context.markdown.replace(dcbContext.substituteContent, () => { return dcbContext.content; });
     });
 
     // resolve

+ 1 - 1
resource/js/util/markdown-it/plantuml.js

@@ -13,7 +13,7 @@ export default class PlantUMLConfigurer {
   }
 
   configure(md) {
-    md.use(require('markdown-it-plantuml'), 'name', {
+    md.use(require('markdown-it-plantuml'), {
       generateSource: this.generateSource,
     });
   }

+ 36 - 13
yarn.lock

@@ -2348,7 +2348,7 @@ express@^4.15.2, express@^4.16.1:
     utils-merge "1.0.1"
     vary "~1.1.2"
 
-extend@3, extend@~3.0.0, extend@~3.0.1:
+extend@3, extend@^3.0.1, extend@~3.0.0, extend@~3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
 
@@ -2603,6 +2603,14 @@ gaze@^1.0.0:
   dependencies:
     globule "^1.0.0"
 
+gcp-metadata@^0.6.0:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-0.6.1.tgz#62d54871fc6aeeac6a688e094abc886cb7aaacd0"
+  dependencies:
+    axios "^0.17.1"
+    extend "^3.0.1"
+    retry-axios "0.3.0"
+
 generate-function@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
@@ -2687,15 +2695,17 @@ good-listener@^1.2.2:
   dependencies:
     delegate "^3.1.2"
 
-google-auth-library@^1.1.0:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.2.1.tgz#20eb9d585b1837a703712abdb787da4984982b64"
+google-auth-library@^1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.3.1.tgz#a0456166c9538ee062c51b8e70765a5a0e13e757"
   dependencies:
-    axios "^0.17.1"
+    axios "^0.18.0"
+    gcp-metadata "^0.6.0"
     gtoken "^2.1.0"
     jws "^3.1.4"
     lodash.isstring "^4.0.1"
     lru-cache "^4.1.1"
+    retry-axios "^0.3.2"
 
 google-p12-pem@^1.0.0:
   version "1.0.0"
@@ -2704,14 +2714,15 @@ google-p12-pem@^1.0.0:
     node-forge "^0.7.1"
     pify "^3.0.0"
 
-googleapis@^26.0.0:
-  version "26.0.1"
-  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-26.0.1.tgz#e1efb43b00546b1ad8c055a83cf210d5422b7f42"
+googleapis@^27.0.0:
+  version "27.0.0"
+  resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-27.0.0.tgz#c210633b43e7047b65d33da40c489b6d8f9c02b8"
   dependencies:
-    google-auth-library "^1.1.0"
+    google-auth-library "^1.3.1"
+    pify "^3.0.0"
     qs "^6.5.1"
     string-template "1.0.0"
-    uuid "^3.1.0"
+    uuid "^3.2.1"
 
 graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.1.11"
@@ -3732,9 +3743,9 @@ markdown-it-named-headers@^0.0.4:
   dependencies:
     string "^3.0.1"
 
-markdown-it-plantuml@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/markdown-it-plantuml/-/markdown-it-plantuml-0.3.1.tgz#f338df4d691a5561364e65809b6812bcb3d8b047"
+markdown-it-plantuml@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/markdown-it-plantuml/-/markdown-it-plantuml-1.0.0.tgz#7b6a351a1d9275705c09626b02d873301e5899c2"
 
 markdown-it-task-lists@^2.1.0:
   version "2.1.0"
@@ -5501,6 +5512,14 @@ resolve@^1.0.0:
   dependencies:
     path-parse "^1.0.5"
 
+retry-axios@0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/retry-axios/-/retry-axios-0.3.0.tgz#7858ad369872d6acaf05fd97b0490969c9c35ee2"
+
+retry-axios@^0.3.2:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/retry-axios/-/retry-axios-0.3.2.tgz#5757c80f585b4cc4c4986aa2ffd47a60c6d35e13"
+
 retry@^0.9.0:
   version "0.9.0"
   resolved "https://registry.yarnpkg.com/retry/-/retry-0.9.0.tgz#6f697e50a0e4ddc8c8f7fb547a9b60dead43678d"
@@ -6298,6 +6317,10 @@ uuid@3.1.0, uuid@^3.0.0, uuid@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
 
+uuid@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
+
 uws@~0.14.4:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/uws/-/uws-0.14.5.tgz#67aaf33c46b2a587a5f6666d00f7691328f149dc"