فهرست منبع

enable to enter and db-reflect the value of custom-title-tag-contents.

Knaito163 8 سال پیش
والد
کامیت
c1b99d0160

+ 9 - 0
lib/form/admin/customtitle.js

@@ -0,0 +1,9 @@
+'use strict';
+
+var form = require('express-form')
+  , field = form.field
+  ;
+
+module.exports = form(
+  field('settingForm[customize:title]')
+);

+ 1 - 0
lib/form/index.js

@@ -23,6 +23,7 @@ module.exports = {
     customcss: require('./admin/customcss'),
     customscript: require('./admin/customscript'),
     customheader: require('./admin/customheader'),
+    customtitle: require('./admin/customtitle'),
     custombehavior: require('./admin/custombehavior'),
     customlayout: require('./admin/customlayout'),
     customfeatures: require('./admin/customfeatures'),

+ 7 - 0
lib/models/config.js

@@ -85,6 +85,7 @@ module.exports = function(crowi) {
       'customize:css' : '',
       'customize:script' : '',
       'customize:header' : '',
+      'customize:title' : '',
       'customize:behavior' : 'crowi',
       'customize:layout' : 'crowi',
       'customize:isEnabledTimeline' : true,
@@ -358,6 +359,12 @@ module.exports = function(crowi) {
     return getValueForCrowiNS(config, key);
   }
 
+  configSchema.statics.customTitle = function(config)
+  {
+    const key = 'customize:title';
+    return getValueForCrowiNS(config, key);
+  }
+
   configSchema.statics.behaviorType = function(config)
   {
     const key = 'customize:behavior';

+ 1 - 0
lib/routes/index.js

@@ -74,6 +74,7 @@ module.exports = function(crowi, app) {
   app.post('/_api/admin/customize/css'      , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customcss, admin.api.customizeSetting);
   app.post('/_api/admin/customize/script'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customscript, admin.api.customizeSetting);
   app.post('/_api/admin/customize/header'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customheader, admin.api.customizeSetting);
+  app.post('/_api/admin/customize/title'    , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customtitle, admin.api.customizeSetting);
   app.post('/_api/admin/customize/behavior' , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.custombehavior, admin.api.customizeSetting);
   app.post('/_api/admin/customize/layout'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customlayout, admin.api.customizeSetting);
   app.post('/_api/admin/customize/features' , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.customfeatures, admin.api.customizeSetting);

+ 37 - 1
lib/views/admin/customize.html

@@ -241,6 +241,42 @@
       </fieldset>
       </form>
 
+      <form action="/_api/admin/customize/title" method="post" class="form-horizontal" id="customtitleSettingForm" role="form">
+        <fieldset>
+          <legend>カスタムヘッダータイトルHTML</legend>
+
+          <p class="well">
+            &lt;title&gt;タグのコンテンツをカスタムできる。具体的にはユーザ、ページタイトル、サイト名の3つの順番入れ替えや表示・非表示がカスタマイズできる。<br>
+          </p>
+
+          <p class="help-block">
+            Examples:
+            <pre><code>\{% block html_title %}{% endblock %} {{ config.crowi['app:title']|default('Crowi') }}\</code></pre>
+          </p>
+
+          <div class="form-group">
+            <div class="col-xs-12">
+              <div id="custom-title-editor"></div>
+              <input type="hidden" id="inputCustomTitle" name="settingForm[customize:title]" value="{{ settingForm['customize:title'] }}">
+            </div>
+            <div class="col-xs-12">
+              <p class="help-block text-right">
+                <i class="fa fa-fw fa-keyboard-o" aria-hidden="true"></i>
+                Ctrl+Space でコード補完
+              </p>
+            </div>
+          </div>
+
+          <div class="form-group">
+            <div class="col-xs-offset-5 col-xs-6">
+              <input type="hidden" name="_csrf" value="{{ csrf() }}">
+              <button type="submit" class="btn btn-primary">更新</button>
+            </div>
+          </div>
+
+        </fieldset>
+        </form>
+
       <form action="/_api/admin/customize/css" method="post" class="form-horizontal" id="cutomcssSettingForm" role="form">
       <fieldset>
         <legend>{{ t('customize_page.Custom CSS') }}</legend>
@@ -335,7 +371,7 @@ window.addEventListener('load', (event) => {
   </div>
 
   <script>
-    $('#cutomcssSettingForm, #cutomscriptSettingForm, #cutomlayoutSettingForm, #cutombehaviorSettingForm, #customfeaturesSettingForm, #cutomheaderSettingForm').each(function() {
+    $('#cutomcssSettingForm, #cutomscriptSettingForm, #cutomlayoutSettingForm, #cutombehaviorSettingForm, #customfeaturesSettingForm, #cutomheaderSettingForm, #customtitleSettingForm').each(function() {
       $(this).submit(function()
       {
         function showMessage(formId, msg, status) {

+ 25 - 14
resource/js/app.js

@@ -26,6 +26,7 @@ import SearchTypeahead  from './components/SearchTypeahead';
 import CustomCssEditor  from './components/Admin/CustomCssEditor';
 import CustomScriptEditor from './components/Admin/CustomScriptEditor';
 import CustomHeaderEditor from './components/Admin/CustomHeaderEditor';
+import CustomTitleEditor from './components/Admin/CustomTitleEditor';
 
 import * as entities from 'entities';
 
@@ -152,10 +153,10 @@ if (pageEditorElem) {
 
   pageEditor = ReactDOM.render(
     <PageEditor crowi={crowi} crowiRenderer={crowiRenderer}
-        pageId={pageId} revisionId={pageRevisionId} pagePath={pagePath}
-        markdown={markdown}
-        editorOptions={editorOptions} previewOptions={previewOptions}
-        onSaveSuccess={onSaveSuccess} />,
+      pageId={pageId} revisionId={pageRevisionId} pagePath={pagePath}
+      markdown={markdown}
+      editorOptions={editorOptions} previewOptions={previewOptions}
+      onSaveSuccess={onSaveSuccess} />,
     pageEditorElem
   );
   // set refs for pageEditor
@@ -166,15 +167,15 @@ const pageEditorOptionsSelectorElem = document.getElementById('page-editor-optio
 if (pageEditorOptionsSelectorElem) {
   ReactDOM.render(
     <OptionsSelector crowi={crowi}
-        editorOptions={editorOptions} previewOptions={previewOptions}
-        onChange={(newEditorOptions, newPreviewOptions) => { // set onChange event handler
-          // set options
-          pageEditor.setEditorOptions(newEditorOptions);
-          pageEditor.setPreviewOptions(newPreviewOptions);
-          // save
-          crowi.saveEditorOptions(newEditorOptions);
-          crowi.savePreviewOptions(newPreviewOptions);
-        }} />,
+      editorOptions={editorOptions} previewOptions={previewOptions}
+      onChange={(newEditorOptions, newPreviewOptions) => { // set onChange event handler
+        // set options
+        pageEditor.setEditorOptions(newEditorOptions);
+        pageEditor.setPreviewOptions(newPreviewOptions);
+        // save
+        crowi.saveEditorOptions(newEditorOptions);
+        crowi.savePreviewOptions(newPreviewOptions);
+      }} />,
     pageEditorOptionsSelectorElem
   );
 }
@@ -208,7 +209,17 @@ if (customHeaderEditorElem != null) {
   ReactDOM.render(
     <CustomHeaderEditor inputElem={customHeaderInputElem} />,
     customHeaderEditorElem
-  )
+  );
+}
+const customTitleEditorElem = document.getElementById('custom-title-editor');
+if (customTitleEditorElem != null) {
+  // get input[type=hidden] element
+  const customTitleInputElem = document.getElementById('inputCustomTitle');
+
+  ReactDOM.render(
+    <CustomTitleEditor inputElem={customTitleInputElem} />,
+    customTitleEditorElem
+  );
 }
 
 // うわーもうー

+ 60 - 0
resource/js/components/Admin/CustomTitleEditor.js

@@ -0,0 +1,60 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { UnControlled as CodeMirror } from 'react-codemirror2';
+require('codemirror/lib/codemirror.css');
+require('codemirror/addon/display/autorefresh');
+require('codemirror/addon/hint/show-hint');
+require('codemirror/addon/edit/matchbrackets');
+require('codemirror/addon/edit/closebrackets');
+require('codemirror/mode/htmlmixed/htmlmixed');
+require('codemirror/theme/eclipse.css');
+
+require('jquery-ui/ui/widgets/resizable');
+
+export default class CustomTitleEditor extends React.Component {
+
+  constructor(props) {
+    super(props);
+  }
+
+  render() {
+    // get initial value from inputElem
+
+    const value = this.props.inputElem.value;
+
+    return (
+      <CodeMirror
+        value={value}
+        autoFocus={true}
+        options={{
+          mode: 'htmlmixed',
+          lineNumbers: true,
+          tabSize: 2,
+          indentUnit: 2,
+          theme: 'eclipse',
+          autoRefresh: true,
+          matchBrackets: true,
+          autoCloseBrackets: true,
+          extraKeys: {'Ctrl-Space': 'autocomplete'},
+        }}
+        editorDidMount={(editor, next) => {
+          // resizable with jquery.ui
+          $(editor.getWrapperElement()).resizable({
+            resize: function() {
+              editor.setSize($(this).width(), $(this).height());
+            }
+          });
+        }}
+        onChange={(editor, data, value) => {
+          this.props.inputElem.value = value;
+        }}
+      />
+    );
+  }
+
+}
+
+CustomTitleEditor.propTypes = {
+  inputElem: PropTypes.object.isRequired,
+};