Skip to content

Commit 6ef419a

Browse files
authored
更新文档编辑url和预览链接&优化 WorkingDirectory 判定逻辑 (#1036)
* 更新浏览器地址栏和预览链接 * 修改 WorkingDirectory 判定逻辑
1 parent 5863e0b commit 6ef419a

File tree

10 files changed

+118
-18
lines changed

10 files changed

+118
-18
lines changed

commands/command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ func RegisterFunction() {
353353
}
354354
lang := langItemSplit[0]
355355
i18nMap[lang] = langItemSplit[1]
356-
if err := i18n.SetMessage(lang, "conf/lang/"+lang+".ini"); err != nil {
356+
if err := i18n.SetMessage(lang, conf.WorkingDir("conf", "lang", lang+".ini")); err != nil {
357357
logs.Error("Fail to set message file: " + err.Error())
358358
return
359359
}

commands/daemon/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (d *Daemon) Run() {
6262
f = os.Args[0]
6363
}
6464

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

6767
web.Run()
6868
}

conf/enumerate.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,30 @@ func WorkingDir(elem ...string) string {
367367
return filepath.Join(elems...)
368368
}
369369

370-
func init() {
371-
if p, err := filepath.Abs("./conf/app.conf"); err == nil {
372-
ConfigurationFile = p
373-
}
374-
if p, err := filepath.Abs("./"); err == nil {
375-
WorkingDirectory = p
370+
// resolveBaseDir 按优先级返回程序的工作根目录:
371+
// 1. 可执行文件所在目录(存在 conf/app.conf 则认为有效)
372+
// 2. 当前工作目录
373+
func resolveBaseDir() string {
374+
// 优先:可执行文件所在目录
375+
if exe, err := os.Executable(); err == nil {
376+
exeDir := filepath.Dir(exe)
377+
// 处理 go run 时的临时路径(路径含 go-build)
378+
if !strings.Contains(exeDir, "go-build") {
379+
if _, err := os.Stat(filepath.Join(exeDir, "conf", "app.conf")); err == nil {
380+
return exeDir
381+
}
382+
}
376383
}
377-
if p, err := filepath.Abs("./runtime/logs"); err == nil {
378-
LogFile = p
384+
// 兜底:当前工作目录
385+
if cwd, err := filepath.Abs("."); err == nil {
386+
return cwd
379387
}
388+
return "."
389+
}
390+
391+
func init() {
392+
base := resolveBaseDir()
393+
ConfigurationFile = filepath.Join(base, "conf", "app.conf")
394+
WorkingDirectory = base
395+
LogFile = filepath.Join(base, "runtime", "logs")
380396
}

controllers/DocumentController.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func (c *DocumentController) Index() {
110110
c.Data["IS_DOCUMENT_INDEX"] = true
111111
c.Data["Model"] = bookResult
112112
c.Data["Result"] = template.HTML(tree)
113+
c.Data["DocumentId"] = selected
113114
}
114115

115116
// CheckPassword : Handles password verification for private documents,
@@ -251,7 +252,7 @@ func (c *DocumentController) Read() {
251252
data.DocId = doc.DocumentId
252253
data.DocIdentify = doc.Identify
253254
data.DocTitle = doc.DocumentName
254-
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>"
255+
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>"
255256
data.Title = doc.DocumentName + " - Powered by MinDoc"
256257
data.Version = doc.Version
257258
data.ViewCount = doc.ViewCount
@@ -283,7 +284,7 @@ func (c *DocumentController) Read() {
283284
c.Data["Model"] = bookResult
284285
c.Data["Result"] = template.HTML(tree)
285286
c.Data["Title"] = doc.DocumentName
286-
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>")
287+
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>")
287288
c.Data["ViewCount"] = doc.ViewCount
288289
c.Data["FoldSetting"] = "closed"
289290
if bookResult.Editor == EditorCherryMarkdown {

internal/preinit/preinit.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Package preinit performs os.Chdir to the executable's directory before any
2+
// other package (including beego) initialises. This prevents beego's config
3+
// init() from printing a spurious "open conf/app.conf: no such file" debug
4+
// message when the binary is launched from a directory other than its own.
5+
//
6+
// Import this package as the very first blank import in main.go:
7+
//
8+
// _ "github.com/mindoc-org/mindoc/internal/preinit"
9+
package preinit
10+
11+
import (
12+
"os"
13+
"path/filepath"
14+
"strings"
15+
)
16+
17+
func init() {
18+
exe, err := os.Executable()
19+
if err != nil {
20+
return
21+
}
22+
exeDir := filepath.Dir(exe)
23+
// Skip go-run temporary build directories.
24+
if strings.Contains(exeDir, "go-build") {
25+
return
26+
}
27+
// Only chdir when conf/app.conf actually exists next to the binary.
28+
if _, err := os.Stat(filepath.Join(exeDir, "conf", "app.conf")); err != nil {
29+
return
30+
}
31+
_ = os.Chdir(exeDir)
32+
}

main.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package main
22

33
import (
44
"fmt"
5-
"io/ioutil"
65
"log"
76
"os"
87
"path/filepath"
98
"runtime"
109
"strings"
1110

11+
// preinit must be the first import: it chdirs to the exe directory before
12+
// beego's init() tries to open conf/app.conf via a relative path.
13+
_ "github.com/mindoc-org/mindoc/internal/preinit"
14+
1215
_ "github.com/beego/beego/v2/server/web/session/memcache"
1316
_ "github.com/beego/beego/v2/server/web/session/mysql"
1417
_ "github.com/beego/beego/v2/server/web/session/redis"
@@ -23,7 +26,7 @@ import (
2326
func isViaDaemonUnix() bool {
2427
parentPid := os.Getppid()
2528

26-
cmdLineBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", parentPid))
29+
cmdLineBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", parentPid))
2730
if err != nil {
2831
return false
2932
}

static/js/cherry_markdown.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,20 @@ $(function () {
323323
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 };
324324
pushDocumentCategory(node);
325325
window.selectNode = node;
326+
// 更新浏览器地址栏和预览链接
327+
var docIdentify = res.data.identify;
328+
if (docIdentify && window.history) {
329+
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
330+
var newURL = editBase + docIdentify;
331+
if (window._initialDocLoaded) {
332+
history.pushState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
333+
} else {
334+
history.replaceState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
335+
window._initialDocLoaded = true;
336+
}
337+
var readBase = window.editURL.replace(/\/api\/([^/]+)\/content\/$/, '/docs/$1/');
338+
$('a:has(i[name="preview-open"])').attr('href', readBase + docIdentify);
339+
}
326340
pushVueLists(res.data.attach);
327341
setLastSelectNode($node);
328342
} else {
@@ -510,7 +524,7 @@ $(function () {
510524
"identify": res.data.identify,
511525
"version": res.data.version,
512526
state: { opened: res.data.is_open == 1 },
513-
a_attr: { is_open: res.data.is_open == 1 }
527+
a_attr: { is_open: res.data.is_open == 1, href: window.editURL.replace(/\/content\/$/, '/edit/') + res.data.identify }
514528
};
515529

516530
var node = window.treeCatalog.get_node(data.id);
@@ -535,6 +549,16 @@ $(function () {
535549
/**
536550
* 文档目录树
537551
*/
552+
// 为目录树节点注入 href,使鼠标悬浮时浏览器状态栏显示对应编辑 URL
553+
(function () {
554+
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
555+
window.documentCategory.forEach(function (item) {
556+
if (item.identify && !(item.a_attr && item.a_attr.disabled)) {
557+
if (!item.a_attr) item.a_attr = {};
558+
item.a_attr.href = editBase + item.identify;
559+
}
560+
});
561+
}());
538562
$("#sidebar").jstree({
539563
'plugins': ["wholerow", "types", 'dnd', 'contextmenu'],
540564
"types": {

static/js/markdown.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,20 @@ $(function () {
491491
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 };
492492
pushDocumentCategory(node);
493493
window.selectNode = node;
494+
// 更新浏览器地址栏和预览链接
495+
var docIdentify = res.data.identify;
496+
if (docIdentify && window.history) {
497+
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
498+
var newURL = editBase + docIdentify;
499+
if (window._initialDocLoaded) {
500+
history.pushState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
501+
} else {
502+
history.replaceState({ docId: res.data.doc_id }, res.data.doc_name, newURL);
503+
window._initialDocLoaded = true;
504+
}
505+
var readBase = window.editURL.replace(/\/api\/([^/]+)\/content\/$/, '/docs/$1/');
506+
$('a:has(i[name="preview-open"])').attr('href', readBase + docIdentify);
507+
}
494508
pushVueLists(res.data.attach);
495509
setLastSelectNode($node);
496510
} else {
@@ -620,7 +634,7 @@ $(function () {
620634
"identify": res.data.identify,
621635
"version": res.data.version,
622636
state: { opened: res.data.is_open == 1 },
623-
a_attr: { is_open: res.data.is_open == 1 }
637+
a_attr: { is_open: res.data.is_open == 1, href: window.editURL.replace(/\/content\/$/, '/edit/') + res.data.identify }
624638
};
625639

626640
var node = window.treeCatalog.get_node(data.id);
@@ -645,6 +659,16 @@ $(function () {
645659
/**
646660
* 文档目录树
647661
*/
662+
// 为目录树节点注入 href,使鼠标悬浮时浏览器状态栏显示对应编辑 URL
663+
(function () {
664+
var editBase = window.editURL.replace(/\/content\/$/, '/edit/');
665+
window.documentCategory.forEach(function (item) {
666+
if (item.identify && !(item.a_attr && item.a_attr.disabled)) {
667+
if (!item.a_attr) item.a_attr = {};
668+
item.a_attr.href = editBase + item.identify;
669+
}
670+
});
671+
}());
648672
$("#sidebar").jstree({
649673
'plugins': ["wholerow", "types", 'dnd', 'contextmenu'],
650674
"types": {

views/document/cherry_read.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
{{if gt .Member.MemberId 0}}
7979
{{if eq .Model.RoleId 0 1 2}}
8080
<div class="dropdown pull-left" style="margin-right: 10px;">
81-
<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>
81+
<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>
8282
{{if eq .Model.RoleId 0 1}}
8383
<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>
8484
<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>

views/document/default_read.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
{{if gt .Member.MemberId 0}}
8383
{{if eq .Model.RoleId 0 1 2}}
8484
<div class="dropdown pull-left" style="margin-right: 10px;">
85-
<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>
85+
<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>
8686
{{if eq .Model.RoleId 0 1}}
8787
<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>
8888
<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>

0 commit comments

Comments
 (0)