Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion commands/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ func RegisterFunction() {
}
lang := langItemSplit[0]
i18nMap[lang] = langItemSplit[1]
if err := i18n.SetMessage(lang, "conf/lang/"+lang+".ini"); err != nil {
if err := i18n.SetMessage(lang, conf.WorkingDir("conf", "lang", lang+".ini")); err != nil {
logs.Error("Fail to set message file: " + err.Error())
return
}
Expand Down
2 changes: 1 addition & 1 deletion commands/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (d *Daemon) Run() {
f = os.Args[0]
}

fmt.Printf("MinDoc version => %s\nbuild time => %s\nstart directory => %s\n%s\n", conf.VERSION, conf.BUILD_TIME, f, conf.GO_VERSION)
fmt.Printf("MinDoc version => %s\nbuild time => %s\nexecutable => %s\n%s\n", conf.VERSION, conf.BUILD_TIME, f, conf.GO_VERSION)

web.Run()
}
Expand Down
32 changes: 24 additions & 8 deletions conf/enumerate.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,30 @@ func WorkingDir(elem ...string) string {
return filepath.Join(elems...)
}

func init() {
if p, err := filepath.Abs("./conf/app.conf"); err == nil {
ConfigurationFile = p
}
if p, err := filepath.Abs("./"); err == nil {
WorkingDirectory = p
// resolveBaseDir 按优先级返回程序的工作根目录:
// 1. 可执行文件所在目录(存在 conf/app.conf 则认为有效)
// 2. 当前工作目录
func resolveBaseDir() string {
// 优先:可执行文件所在目录
if exe, err := os.Executable(); err == nil {
exeDir := filepath.Dir(exe)
// 处理 go run 时的临时路径(路径含 go-build)
if !strings.Contains(exeDir, "go-build") {
if _, err := os.Stat(filepath.Join(exeDir, "conf", "app.conf")); err == nil {
return exeDir
}
}
}
if p, err := filepath.Abs("./runtime/logs"); err == nil {
LogFile = p
// 兜底:当前工作目录
if cwd, err := filepath.Abs("."); err == nil {
return cwd
}
return "."
}

func init() {
base := resolveBaseDir()
ConfigurationFile = filepath.Join(base, "conf", "app.conf")
WorkingDirectory = base
LogFile = filepath.Join(base, "runtime", "logs")
}
5 changes: 3 additions & 2 deletions controllers/DocumentController.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func (c *DocumentController) Index() {
c.Data["IS_DOCUMENT_INDEX"] = true
c.Data["Model"] = bookResult
c.Data["Result"] = template.HTML(tree)
c.Data["DocumentId"] = selected
}

// CheckPassword : Handles password verification for private documents,
Expand Down Expand Up @@ -251,7 +252,7 @@ func (c *DocumentController) Read() {
data.DocId = doc.DocumentId
data.DocIdentify = doc.Identify
data.DocTitle = doc.DocumentName
data.Body = doc.Release + "<div class='wiki-bottom-left'>"+ i18n.Tr(c.Lang, "doc.prev") + ": <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />" + i18n.Tr(c.Lang, "doc.next") + ": <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>"
data.Body = doc.Release + "<div class='wiki-bottom-left'>" + i18n.Tr(c.Lang, "doc.prev") + ": <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />" + i18n.Tr(c.Lang, "doc.next") + ": <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>"
data.Title = doc.DocumentName + " - Powered by MinDoc"
data.Version = doc.Version
data.ViewCount = doc.ViewCount
Expand Down Expand Up @@ -283,7 +284,7 @@ func (c *DocumentController) Read() {
c.Data["Model"] = bookResult
c.Data["Result"] = template.HTML(tree)
c.Data["Title"] = doc.DocumentName
c.Data["Content"] = template.HTML(doc.Release + "<div class='wiki-bottom-left'>"+ i18n.Tr(c.Lang, "doc.prev") + ": <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />" + i18n.Tr(c.Lang, "doc.next") + ": <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>")
c.Data["Content"] = template.HTML(doc.Release + "<div class='wiki-bottom-left'>" + i18n.Tr(c.Lang, "doc.prev") + ": <a href='/docs/" + PrevPath + "' rel='prev'>" + PrevName + "</a><br />" + i18n.Tr(c.Lang, "doc.next") + ": <a href='/docs/" + NextPath + "' rel='next'>" + NextName + "</a><br /></div>")
c.Data["ViewCount"] = doc.ViewCount
c.Data["FoldSetting"] = "closed"
if bookResult.Editor == EditorCherryMarkdown {
Expand Down
32 changes: 32 additions & 0 deletions internal/preinit/preinit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Package preinit performs os.Chdir to the executable's directory before any
// other package (including beego) initialises. This prevents beego's config
// init() from printing a spurious "open conf/app.conf: no such file" debug
// message when the binary is launched from a directory other than its own.
//
// Import this package as the very first blank import in main.go:
//
// _ "github.com/mindoc-org/mindoc/internal/preinit"
package preinit

import (
"os"
"path/filepath"
"strings"
)

func init() {
exe, err := os.Executable()
if err != nil {
return
}
exeDir := filepath.Dir(exe)
// Skip go-run temporary build directories.
if strings.Contains(exeDir, "go-build") {
return
}
// Only chdir when conf/app.conf actually exists next to the binary.
if _, err := os.Stat(filepath.Join(exeDir, "conf", "app.conf")); err != nil {
return
}
_ = os.Chdir(exeDir)
}
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"runtime"
"strings"

// preinit must be the first import: it chdirs to the exe directory before
// beego's init() tries to open conf/app.conf via a relative path.
_ "github.com/mindoc-org/mindoc/internal/preinit"

_ "github.com/beego/beego/v2/server/web/session/memcache"
_ "github.com/beego/beego/v2/server/web/session/mysql"
_ "github.com/beego/beego/v2/server/web/session/redis"
Expand All @@ -23,7 +26,7 @@ import (
func isViaDaemonUnix() bool {
parentPid := os.Getppid()

cmdLineBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", parentPid))
cmdLineBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", parentPid))
if err != nil {
return false
}
Expand Down
26 changes: 25 additions & 1 deletion static/js/cherry_markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,20 @@ $(function () {
var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
pushDocumentCategory(node);
window.selectNode = node;
// 更新浏览器地址栏和预览链接
var docIdentify = res.data.identify;
if (docIdentify && window.history) {
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
var newURL = editBase + docIdentify;
if (window._initialDocLoaded) {
history.pushState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
} else {
history.replaceState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
window._initialDocLoaded = true;
}
var readBase = window.editURL.replace(/\/api\/([^/]+)\/content\/$/, '/docs/$1/');
$('a:has(i[name="preview-open"])').attr('href', readBase + docIdentify);
}
pushVueLists(res.data.attach);
setLastSelectNode($node);
} else {
Expand Down Expand Up @@ -510,7 +524,7 @@ $(function () {
"identify": res.data.identify,
"version": res.data.version,
state: { opened: res.data.is_open == 1 },
a_attr: { is_open: res.data.is_open == 1 }
a_attr: { is_open: res.data.is_open == 1, href: window.editURL.replace(/\/content\/$/, '/edit/') + res.data.identify }
};

var node = window.treeCatalog.get_node(data.id);
Expand All @@ -535,6 +549,16 @@ $(function () {
/**
* 文档目录树
*/
// 为目录树节点注入 href,使鼠标悬浮时浏览器状态栏显示对应编辑 URL
(function () {
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
window.documentCategory.forEach(function (item) {
if (item.identify && !(item.a_attr && item.a_attr.disabled)) {
if (!item.a_attr) item.a_attr = {};
item.a_attr.href = editBase + item.identify;
}
});
}());
$("#sidebar").jstree({
'plugins': ["wholerow", "types", 'dnd', 'contextmenu'],
"types": {
Expand Down
26 changes: 25 additions & 1 deletion static/js/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,20 @@ $(function () {
var node = { "id": res.data.doc_id, 'parent': res.data.parent_id === 0 ? '#' : res.data.parent_id, "text": res.data.doc_name, "identify": res.data.identify, "version": res.data.version };
pushDocumentCategory(node);
window.selectNode = node;
// 更新浏览器地址栏和预览链接
var docIdentify = res.data.identify;
if (docIdentify && window.history) {
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
var newURL = editBase + docIdentify;
if (window._initialDocLoaded) {
history.pushState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
} else {
history.replaceState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
window._initialDocLoaded = true;
}
var readBase = window.editURL.replace(/\/api\/([^/]+)\/content\/$/, '/docs/$1/');
$('a:has(i[name="preview-open"])').attr('href', readBase + docIdentify);
}
pushVueLists(res.data.attach);
setLastSelectNode($node);
} else {
Expand Down Expand Up @@ -620,7 +634,7 @@ $(function () {
"identify": res.data.identify,
"version": res.data.version,
state: { opened: res.data.is_open == 1 },
a_attr: { is_open: res.data.is_open == 1 }
a_attr: { is_open: res.data.is_open == 1, href: window.editURL.replace(/\/content\/$/, '/edit/') + res.data.identify }
};

var node = window.treeCatalog.get_node(data.id);
Expand All @@ -645,6 +659,16 @@ $(function () {
/**
* 文档目录树
*/
// 为目录树节点注入 href,使鼠标悬浮时浏览器状态栏显示对应编辑 URL
(function () {
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
window.documentCategory.forEach(function (item) {
if (item.identify && !(item.a_attr && item.a_attr.disabled)) {
if (!item.a_attr) item.a_attr = {};
item.a_attr.href = editBase + item.identify;
}
});
}());
$("#sidebar").jstree({
'plugins': ["wholerow", "types", 'dnd', 'contextmenu'],
"types": {
Expand Down
2 changes: 1 addition & 1 deletion views/document/cherry_read.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
{{if gt .Member.MemberId 0}}
{{if eq .Model.RoleId 0 1 2}}
<div class="dropdown pull-left" style="margin-right: 10px;">
<a href="{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" .DocumentId}}" class="btn btn-danger" id="editDocumentLink"><i class="fa fa-edit" aria-hidden="true"></i> {{i18n .Lang "blog.edit"}}</a>
<a href="{{if gt .DocumentId 0}}{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" .DocumentId}}{{else}}{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" ""}}{{end}}" class="btn btn-danger" id="editDocumentLink"><i class="fa fa-edit" aria-hidden="true"></i> {{i18n .Lang "blog.edit"}}</a>
{{if eq .Model.RoleId 0 1}}
<a href="{{urlfor "BookController.Users" ":key" .Model.Identify}}" class="btn btn-success"><i class="fa fa-user" aria-hidden="true"></i> {{i18n .Lang "blog.member"}}</a>
<a href="{{urlfor "BookController.Setting" ":key" .Model.Identify}}" class="btn btn-primary"><i class="fa fa-gear" aria-hidden="true"></i> {{i18n .Lang "common.setting"}}</a>
Expand Down
2 changes: 1 addition & 1 deletion views/document/default_read.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
{{if gt .Member.MemberId 0}}
{{if eq .Model.RoleId 0 1 2}}
<div class="dropdown pull-left" style="margin-right: 10px;">
<a href="{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" .DocumentId}}" class="btn btn-danger" id="editDocumentLink"><i class="fa fa-edit" aria-hidden="true"></i> {{i18n .Lang "blog.edit"}}</a>
<a href="{{if gt .DocumentId 0}}{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" .DocumentId}}{{else}}{{urlfor "DocumentController.Edit" ":key" .Model.Identify ":id" ""}}{{end}}" class="btn btn-danger" id="editDocumentLink"><i class="fa fa-edit" aria-hidden="true"></i> {{i18n .Lang "blog.edit"}}</a>
{{if eq .Model.RoleId 0 1}}
<a href="{{urlfor "BookController.Users" ":key" .Model.Identify}}" class="btn btn-success"><i class="fa fa-user" aria-hidden="true"></i> {{i18n .Lang "blog.member"}}</a>
<a href="{{urlfor "BookController.Setting" ":key" .Model.Identify}}" class="btn btn-primary"><i class="fa fa-gear" aria-hidden="true"></i> {{i18n .Lang "common.setting"}}</a>
Expand Down
Loading