Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add directory support for wiki #33000

Closed
wants to merge 6 commits into from
Closed
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
114 changes: 79 additions & 35 deletions routers/web/repo/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"io"
"net/http"
"net/url"
"path"
"path/filepath"
"strings"

Expand Down Expand Up @@ -72,6 +73,7 @@
// PageMeta wiki page meta information
type PageMeta struct {
Name string
IsDir bool
SubURL string
GitEntryName string
UpdatedUnix timeutil.TimeStamp
Expand Down Expand Up @@ -178,7 +180,7 @@
return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry
}

func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry, string) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil {
if wikiRepo != nil {
Expand All @@ -187,17 +189,43 @@
if !git.IsErrNotExist(err) {
ctx.ServerError("GetBranchCommit", err)
}
return nil, nil
return nil, nil, ""
}

reqPath := util.PathJoinRelX(ctx.PathParamRaw("*"))
p, err := url.PathUnescape(reqPath)
if err != nil {
ctx.ServerError("PathUnescape", err)
return nil, nil, ""
}
pTree, err := commit.GetTreeEntryByPath(wiki_service.WebDirPathToGitPath(wiki_service.WebPath(p)))
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("SubTree", err)
return nil, nil, ""
}
if pTree != nil && pTree.IsDir() {
ctx.Redirect(ctx.Repo.RepoLink + fmt.Sprintf("/wiki/%s?action=_pages", p))
return nil, nil, ""
}

dirPath, pageName := path.Split(p)
pageName = strings.TrimSuffix(pageName, ".md")
treePath := wiki_service.WebDirPathToGitPath(wiki_service.WebPath(dirPath))
tree, err := commit.SubTree(treePath)
if err != nil {
ctx.NotFoundOrServerError("SubTree", git.IsErrNotExist, err)
return nil, nil, ""
}
ctx.Data["dirPath"] = dirPath

// Get page list.
entries, err := commit.ListEntries()
entries, err := tree.ListEntries()
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("ListEntries", err)
return nil, nil
return nil, nil, ""
}
pages := make([]PageMeta, 0, len(entries))
for _, entry := range entries {
Expand All @@ -213,27 +241,28 @@
wikiRepo.Close()
}
ctx.ServerError("WikiFilenameToName", err)
return nil, nil
return nil, nil, ""
} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
continue
}
_, displayName := wiki_service.WebPathToUserTitle(wikiName)
pages = append(pages, PageMeta{
Name: displayName,
SubURL: wiki_service.WebPathToURLPath(wikiName),
SubURL: wiki_service.WebPathToURLPath(wiki_service.WebPath(dirPath) + wikiName),
GitEntryName: entry.Name(),
})
}
ctx.Data["Pages"] = pages
ctx.Data["PageURL"] = wiki_service.WebPathToURLPath(wiki_service.WebPath(p))
ctx.Data["PageDir"] = wiki_service.WebPathToURLPath(wiki_service.WebPath(dirPath))

// get requested page name
pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
if len(pageName) == 0 {
pageName = "Home"
p = "Home.md"
}

_, displayName := wiki_service.WebPathToUserTitle(pageName)
ctx.Data["PageURL"] = wiki_service.WebPathToURLPath(pageName)
_, displayName := wiki_service.WebPathToUserTitle(wiki_service.WebPath(pageName))
ctx.Data["old_title"] = displayName
ctx.Data["Title"] = displayName
ctx.Data["title"] = displayName
Expand All @@ -242,18 +271,18 @@
isFooter := pageName == "_Footer"

// lookup filename in wiki - get gitTree entry , real filename
entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, wiki_service.WebPath(p))
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
if isRaw {
ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName)))

Check failure on line 279 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-backend

unnecessary conversion (unconvert)

Check failure on line 279 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

unnecessary conversion (unconvert)

Check failure on line 279 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

unnecessary conversion (unconvert)
}
if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil
return nil, nil, ""
}

// get filecontent
Expand All @@ -262,7 +291,7 @@
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil
return nil, nil, ""
}

var sidebarContent []byte
Expand All @@ -272,7 +301,7 @@
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil
return nil, nil, ""
}
} else {
sidebarContent = data
Expand All @@ -285,7 +314,7 @@
if wikiRepo != nil {
wikiRepo.Close()
}
return nil, nil
return nil, nil, ""
}
} else {
footerContent = data
Expand Down Expand Up @@ -318,7 +347,7 @@
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return nil, nil
return nil, nil, ""
}

if rctx.SidebarTocNode != nil {
Expand All @@ -339,7 +368,7 @@
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return nil, nil
return nil, nil, ""
}
ctx.Data["sidebarPresent"] = sidebarContent != nil
} else {
Expand All @@ -354,7 +383,7 @@
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return nil, nil
return nil, nil, ""
}
ctx.Data["footerPresent"] = footerContent != nil
} else {
Expand All @@ -365,7 +394,7 @@
commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
ctx.Data["CommitCount"] = commitsCount

return wikiRepo, entry
return wikiRepo, entry, pageFilename
}

func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
Expand Down Expand Up @@ -462,13 +491,14 @@
}

// get requested pagename
pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
pageName := wiki_service.WebPath(util.PathJoinRelX(ctx.PathParamRaw("*")))
if len(pageName) == 0 {
pageName = "Home"
}

_, displayName := wiki_service.WebPathToUserTitle(pageName)
ctx.Data["PageURL"] = wiki_service.WebPathToURLPath(pageName)
ctx.Data["PageDir"] = wiki_service.WebPathToURLPath(wiki_service.WebPath(path.Dir(string(pageName))))
ctx.Data["old_title"] = displayName
ctx.Data["Title"] = displayName
ctx.Data["title"] = displayName
Expand Down Expand Up @@ -557,7 +587,7 @@
return
}

wikiRepo, entry := renderViewPage(ctx)
wikiRepo, entry, wikiPath := renderViewPage(ctx)
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
Expand All @@ -572,7 +602,6 @@
return
}

wikiPath := entry.Name()
if markup.DetectMarkupTypeByFileName(wikiPath) != markdown.MarkupName {
ext := strings.ToUpper(filepath.Ext(wikiPath))
ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
Expand Down Expand Up @@ -647,7 +676,8 @@
return
}

treePath := "" // To support list sub folders' pages in the future
dirPath := util.PathJoinRelX(ctx.PathParamRaw("*"))
treePath := wiki_service.WebDirPathToGitPath(wiki_service.WebPath(dirPath))
tree, err := commit.SubTree(treePath)
if err != nil {
ctx.ServerError("SubTree", err)
Expand All @@ -669,26 +699,39 @@

pages := make([]PageMeta, 0, len(entries))
for _, entry := range entries {
if !entry.Entry.IsRegular() {
if !entry.Entry.IsRegular() && !entry.Entry.IsDir() {
continue
}
wikiName, err := wiki_service.GitPathToWebPath(entry.Entry.Name())
if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) {
continue
var wikiName wiki_service.WebPath
if entry.Entry.IsDir() {
wikiName, err = wiki_service.GitDirPathToWebPath(entry.Entry.Name())
if err != nil {
ctx.ServerError("GitDirPathToWebPath", err)
return
}
} else {
wikiName, err = wiki_service.GitPathToWebPath(entry.Entry.Name())
if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) {
continue
}
ctx.ServerError("GitPathToWebPath", err)
return
}
ctx.ServerError("WikiFilenameToName", err)
return
}
_, displayName := wiki_service.WebPathToUserTitle(wikiName)
urlPath := path.Join(string(dirPath), string(wikiName))

Check failure on line 723 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-backend

unnecessary conversion (unconvert)

Check failure on line 723 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

unnecessary conversion (unconvert)

Check failure on line 723 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

unnecessary conversion (unconvert)
pages = append(pages, PageMeta{
Name: displayName,
SubURL: wiki_service.WebPathToURLPath(wikiName),
GitEntryName: entry.Entry.Name(),
IsDir: entry.Entry.IsDir(),
SubURL: wiki_service.WebPathToURLPath(wiki_service.WebPath(urlPath)),
GitEntryName: path.Join(string(dirPath), entry.Entry.Name()),

Check failure on line 728 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-backend

unnecessary conversion (unconvert)

Check failure on line 728 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

unnecessary conversion (unconvert)

Check failure on line 728 in routers/web/repo/wiki.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

unnecessary conversion (unconvert)
UpdatedUnix: timeutil.TimeStamp(entry.Commit.Author.When.Unix()),
})
}
ctx.Data["Pages"] = pages
ctx.Data["PageDir"] = ctx.PathParamRaw("*")
ctx.Data["ParentPageDir"] = path.Dir(ctx.PathParamRaw("*"))

ctx.HTML(http.StatusOK, tplWikiPages)
}
Expand Down Expand Up @@ -772,7 +815,7 @@
return
}

wikiName := wiki_service.UserTitleToWebPath("", form.Title)
wikiName := wiki_service.UserTitleToWebPath(ctx.PathParam("*"), form.Title)

if len(form.Message) == 0 {
form.Message = ctx.Locale.TrString("repo.editor.add", form.Title)
Expand Down Expand Up @@ -823,8 +866,9 @@
return
}

oldWikiName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
newWikiName := wiki_service.UserTitleToWebPath("", form.Title)
p := util.PathJoinRelX(ctx.PathParamRaw("*"))
oldWikiName := wiki_service.WebPath(p)
newWikiName := wiki_service.UserTitleToWebPath(path.Dir(p), form.Title)

if len(form.Message) == 0 {
form.Message = ctx.Locale.TrString("repo.editor.update", form.Title)
Expand All @@ -842,7 +886,7 @@

// DeleteWikiPagePost delete wiki page
func DeleteWikiPagePost(ctx *context.Context) {
wikiName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
wikiName := wiki_service.WebPath(util.PathJoinRelX(ctx.PathParamRaw("*")))
if len(wikiName) == 0 {
wikiName = "Home"
}
Expand Down
18 changes: 17 additions & 1 deletion services/wiki/wiki_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ func WebPathToGitPath(s WebPath) string {
return util.PathJoinRelX(ret)
}

return WebDirPathToGitPath(s) + ".md"
}

func WebDirPathToGitPath(s WebPath) string {
a := strings.Split(string(s), "/")
for i := range a {
shouldAddDashMarker := hasDashMarker(a[i])
Expand All @@ -107,7 +111,7 @@ func WebPathToGitPath(s WebPath) string {
a[i] = strings.ReplaceAll(a[i], "%20", " ") // space is safe to be kept in git path
a[i] = strings.ReplaceAll(a[i], "+", " ")
}
return strings.Join(a, "/") + ".md"
return strings.Join(a, "/")
}

func GitPathToWebPath(s string) (wp WebPath, err error) {
Expand All @@ -126,6 +130,18 @@ func GitPathToWebPath(s string) (wp WebPath, err error) {
return WebPath(strings.Join(a, "/")), nil
}

func GitDirPathToWebPath(s string) (wp WebPath, err error) {
a := strings.Split(s, "/")
for i := range a {
shouldAddDashMarker := hasDashMarker(a[i])
if a[i], err = unescapeSegment(a[i]); err != nil {
return "", err
}
a[i] = escapeSegToWeb(a[i], shouldAddDashMarker)
}
return WebPath(strings.Join(a, "/")), nil
}

func WebPathToUserTitle(s WebPath) (dir, display string) {
dir = path.Dir(string(s))
display = path.Base(string(s))
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/wiki/new.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div class="ui header flex-text-block tw-justify-between">
{{ctx.Locale.Tr "repo.wiki.new_page"}}
{{if .PageIsWikiEdit}}
<a class="ui tiny primary button" href="{{.RepoLink}}/wiki?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
<a class="ui tiny primary button" href="{{.RepoLink}}/wiki/{{.PageDir}}?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
{{end}}
</div>
<form class="ui form" action="?action={{if .PageIsWikiEdit}}_edit{{else}}_new{{end}}" method="post">
Expand Down
17 changes: 13 additions & 4 deletions templates/repo/wiki/pages.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,28 @@
<span>{{ctx.Locale.Tr "repo.wiki.pages"}}</span>
<span>
{{if and .CanWriteWiki (not .Repository.IsMirror)}}
<a class="ui small primary button" href="{{.RepoLink}}/wiki?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
<a class="ui small primary button" href="{{.RepoLink}}/wiki/{{.PageDir}}?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
{{end}}
</span>
</h2>
{{if .IsRepositoryAdmin}}<div>{{ctx.Locale.Tr "repo.default_branch"}}: {{.Repository.DefaultWikiBranch}}</div>{{end}}
<table class="ui table wiki-pages-list">
<tbody>
{{if .PageDir}}
<tr>
<td>
{{svg "octicon-file-directory-fill"}}
<a href="{{.RepoLink}}/wiki/{{.ParentPageDir}}?action=_pages">..</a>
</td>
<td></td>
</tr>
{{end}}
{{range .Pages}}
<tr>
<td>
{{svg "octicon-file"}}
<a href="{{$.RepoLink}}/wiki/{{.SubURL}}">{{.Name}}</a>
<a class="wiki-git-entry" href="{{$.RepoLink}}/wiki/{{.GitEntryName | PathEscape}}" data-tooltip-content="{{ctx.Locale.Tr "repo.wiki.original_git_entry_tooltip"}}">{{svg "octicon-chevron-right"}}</a>
{{if .IsDir}}{{svg "octicon-file-directory-fill"}}{{else}}{{svg "octicon-file"}}{{end}}
<a href="{{$.RepoLink}}/wiki/{{.SubURL}}{{if .IsDir}}?action=_pages{{end}}">{{.Name}}</a>
<a class="wiki-git-entry" href="{{$.RepoLink}}/wiki/{{.SubURL}}{{if .IsDir}}?action=_pages{{end}}" data-tooltip-content="{{ctx.Locale.Tr "repo.wiki.original_git_entry_tooltip"}}">{{svg "octicon-chevron-right"}}</a>
</td>
{{$timeSince := DateUtils.TimeSince .UpdatedUnix}}
<td class="text right">{{ctx.Locale.Tr "repo.wiki.last_updated" $timeSince}}</td>
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/wiki/view.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
{{end}}
{{if and .CanWriteWiki (not .Repository.IsMirror)}}
<a class="ui small button" href="{{.RepoLink}}/wiki/{{.PageURL}}?action=_edit">{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}</a>
<a class="ui small primary button" href="{{.RepoLink}}/wiki?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
<a class="ui small primary button" href="{{.RepoLink}}/wiki/{{.PageDir}}?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a>
<a class="ui small red button delete-button" href="" data-url="{{.RepoLink}}/wiki/{{.PageURL}}?action=_delete" data-id="{{.PageURL}}">{{ctx.Locale.Tr "repo.wiki.delete_page_button"}}</a>
{{end}}
</div>
Expand Down
Loading
Loading