Backport #26745 Fixes #26548 This PR refactors the rendering of markup links. The old code uses `strings.Replace` to change some urls while the new code uses more context to decide which link should be generated. The added tests should ensure the same output for the old and new behaviour (besides the bug). We may need to refactor the rendering a bit more to make it clear how the different helper methods render the input string. There are lots of options (resolve links / images / mentions / git hashes / emojis / ...) but you don't really know what helper uses which options. For example, we currently support images in the user description which should not be allowed I think: <details> <summary>Profile</summary> https://try.gitea.io/KN4CK3R  </details>
This commit is contained in:
@@ -51,9 +51,11 @@ func toReleaseLink(ctx *context.Context, act *activities_model.Action) string {
|
||||
// If rendering fails, the original markdown text is returned
|
||||
func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) string {
|
||||
markdownCtx := &markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: act.GetRepoLink(ctx),
|
||||
Type: markdown.MarkupName,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: act.GetRepoLink(ctx),
|
||||
},
|
||||
Type: markdown.MarkupName,
|
||||
Metas: map[string]string{
|
||||
"user": act.GetRepoUserName(ctx),
|
||||
"repo": act.GetRepoName(ctx),
|
||||
@@ -199,7 +201,6 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
|
||||
switch act.OpType {
|
||||
case activities_model.ActionCommitRepo, activities_model.ActionMirrorSyncPush:
|
||||
push := templates.ActionContent2Commits(act)
|
||||
repoLink := act.GetRepoAbsoluteLink(ctx)
|
||||
|
||||
for _, commit := range push.Commits {
|
||||
if len(desc) != 0 {
|
||||
@@ -208,7 +209,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
|
||||
desc += fmt.Sprintf("<a href=\"%s\">%s</a>\n%s",
|
||||
html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoAbsoluteLink(ctx), commit.Sha1)),
|
||||
commit.Sha1,
|
||||
templates.RenderCommitMessage(ctx, commit.Message, repoLink, nil),
|
||||
templates.RenderCommitMessage(ctx, commit.Message, nil),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -288,9 +289,11 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i
|
||||
|
||||
link := &feeds.Link{Href: rel.HTMLURL()}
|
||||
content, err = markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: rel.Repo.Link(),
|
||||
Metas: rel.Repo.ComposeMetas(),
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: rel.Repo.Link(),
|
||||
},
|
||||
Metas: rel.Repo.ComposeMetas(),
|
||||
}, rel.Note)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -42,8 +42,10 @@ func showUserFeed(ctx *context.Context, formatType string) {
|
||||
}
|
||||
|
||||
ctxUserDescription, err := markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: ctx.ContextUser.HTMLURL(),
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.ContextUser.HTMLURL(),
|
||||
},
|
||||
Metas: map[string]string{
|
||||
"user": ctx.ContextUser.GetDisplayName(),
|
||||
},
|
||||
|
||||
@@ -44,10 +44,8 @@ func Home(ctx *context.Context) {
|
||||
ctx.Data["Title"] = org.DisplayName()
|
||||
if len(org.Description) != 0 {
|
||||
desc, err := markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
}, org.Description)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -7,7 +7,9 @@ package repo
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
@@ -21,7 +23,9 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitgraph"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
git_service "code.gitea.io/gitea/services/repository"
|
||||
)
|
||||
@@ -370,9 +374,21 @@ func Diff(ctx *context.Context) {
|
||||
note := &git.Note{}
|
||||
err = git.GetNote(ctx, ctx.Repo.GitRepo, commitID, note)
|
||||
if err == nil {
|
||||
ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message))
|
||||
ctx.Data["NoteCommit"] = note.Commit
|
||||
ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(ctx, note.Commit)
|
||||
ctx.Data["NoteRendered"], err = markup.RenderCommitMessage(&markup.RenderContext{
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
BranchPath: path.Join("commit", util.PathEscapeSegments(commitID)),
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message))))
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderCommitMessage", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["BranchName"], err = commit.GetBranchName()
|
||||
|
||||
@@ -1424,12 +1424,13 @@ func ViewIssue(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
ctx.Data["IssueWatch"] = iw
|
||||
|
||||
issue.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, issue.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -1589,10 +1590,12 @@ func ViewIssue(ctx *context.Context) {
|
||||
}
|
||||
|
||||
comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, comment.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -1666,10 +1669,12 @@ func ViewIssue(ctx *context.Context) {
|
||||
}
|
||||
} else if comment.Type.HasContentSupport() {
|
||||
comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, comment.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -2220,10 +2225,12 @@ func UpdateIssueContent(ctx *context.Context) {
|
||||
}
|
||||
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, issue.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -3129,10 +3136,12 @@ func UpdateCommentContent(ctx *context.Context) {
|
||||
}
|
||||
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, comment.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -81,10 +81,12 @@ func Milestones(ctx *context.Context) {
|
||||
}
|
||||
for _, m := range miles {
|
||||
m.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, m.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -275,10 +277,12 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
|
||||
}
|
||||
|
||||
milestone.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, milestone.Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -86,10 +86,12 @@ func Projects(ctx *context.Context) {
|
||||
|
||||
for i := range projects {
|
||||
projects[i].RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, projects[i].Description)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -353,10 +355,12 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["LinkedPRs"] = linkedPrsMap
|
||||
|
||||
project.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, project.Description)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -175,10 +175,12 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
|
||||
}
|
||||
|
||||
r.Note, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, r.Note)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -281,10 +283,12 @@ func SingleRelease(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
release.Note, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
}, release.Note)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -57,16 +57,15 @@ func RenderFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
treeLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
||||
if ctx.Repo.TreePath != "" {
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
|
||||
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts")
|
||||
err = markup.Render(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
RelativePath: ctx.Repo.TreePath,
|
||||
URLPrefix: path.Dir(treeLink),
|
||||
Ctx: ctx,
|
||||
RelativePath: ctx.Repo.TreePath,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
BranchPath: ctx.Repo.BranchNameSubURL(),
|
||||
TreePath: path.Dir(ctx.Repo.TreePath),
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
InStandalonePage: true,
|
||||
|
||||
@@ -158,7 +158,7 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry, try
|
||||
return "", readmeFile, nil
|
||||
}
|
||||
|
||||
func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
func renderDirectory(ctx *context.Context) {
|
||||
entries := renderDirectoryFiles(ctx, 1*time.Second)
|
||||
if ctx.Written() {
|
||||
return
|
||||
@@ -175,7 +175,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
return
|
||||
}
|
||||
|
||||
renderReadmeFile(ctx, subfolder, readmeFile, treeLink)
|
||||
renderReadmeFile(ctx, subfolder, readmeFile)
|
||||
}
|
||||
|
||||
// localizedExtensions prepends the provided language code with and without a
|
||||
@@ -259,7 +259,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
|
||||
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
|
||||
}
|
||||
|
||||
func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry, readmeTreelink string) {
|
||||
func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry) {
|
||||
target := readmeFile
|
||||
if readmeFile != nil && readmeFile.IsLink() {
|
||||
target, _ = readmeFile.FollowLinks()
|
||||
@@ -312,9 +312,13 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
|
||||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.Name()), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
|
||||
URLPrefix: path.Join(readmeTreelink, subfolder),
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
BranchPath: ctx.Repo.BranchNameSubURL(),
|
||||
TreePath: path.Join(ctx.Repo.TreePath, subfolder),
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
}, rd)
|
||||
if err != nil {
|
||||
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
|
||||
@@ -333,7 +337,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
|
||||
}
|
||||
}
|
||||
|
||||
func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink string) {
|
||||
func renderFile(ctx *context.Context, entry *git.TreeEntry) {
|
||||
ctx.Data["IsViewFile"] = true
|
||||
ctx.Data["HideRepoInfo"] = true
|
||||
blob := entry.Blob()
|
||||
@@ -347,7 +351,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
|
||||
ctx.Data["FileIsSymlink"] = entry.IsLink()
|
||||
ctx.Data["FileName"] = blob.Name()
|
||||
ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
if ctx.Repo.TreePath == ".editorconfig" {
|
||||
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
|
||||
@@ -475,9 +479,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
Ctx: ctx,
|
||||
Type: markupType,
|
||||
RelativePath: ctx.Repo.TreePath,
|
||||
URLPrefix: path.Dir(treeLink),
|
||||
Metas: metas,
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
BranchPath: ctx.Repo.BranchNameSubURL(),
|
||||
TreePath: path.Dir(ctx.Repo.TreePath),
|
||||
},
|
||||
Metas: metas,
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
}, rd)
|
||||
if err != nil {
|
||||
ctx.ServerError("Render", err)
|
||||
@@ -576,9 +584,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
RelativePath: ctx.Repo.TreePath,
|
||||
URLPrefix: path.Dir(treeLink),
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
BranchPath: ctx.Repo.BranchNameSubURL(),
|
||||
TreePath: path.Dir(ctx.Repo.TreePath),
|
||||
},
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
}, rd)
|
||||
if err != nil {
|
||||
ctx.ServerError("Render", err)
|
||||
@@ -936,14 +948,6 @@ func renderCode(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Title"] = title
|
||||
|
||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
||||
treeLink := branchLink
|
||||
rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
|
||||
|
||||
if len(ctx.Repo.TreePath) > 0 {
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
|
||||
// Get Topics of this repo
|
||||
renderRepoTopics(ctx)
|
||||
if ctx.Written() {
|
||||
@@ -968,9 +972,9 @@ func renderCode(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if entry.IsDir() {
|
||||
renderDirectory(ctx, treeLink)
|
||||
renderDirectory(ctx)
|
||||
} else {
|
||||
renderFile(ctx, entry, treeLink, rawLink)
|
||||
renderFile(ctx, entry)
|
||||
}
|
||||
if ctx.Written() {
|
||||
return
|
||||
@@ -1011,6 +1015,12 @@ func renderCode(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Data["Paths"] = paths
|
||||
|
||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
||||
treeLink := branchLink
|
||||
if len(ctx.Repo.TreePath) > 0 {
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
ctx.Data["TreeLink"] = treeLink
|
||||
ctx.Data["TreeNames"] = treeNames
|
||||
ctx.Data["BranchLink"] = branchLink
|
||||
|
||||
@@ -238,10 +238,12 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
}
|
||||
|
||||
rctx := &markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
IsWiki: true,
|
||||
Ctx: ctx,
|
||||
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
|
||||
Links: markup.Links{
|
||||
Base: ctx.Repo.RepoLink,
|
||||
},
|
||||
IsWiki: true,
|
||||
}
|
||||
buf := &strings.Builder{}
|
||||
|
||||
|
||||
@@ -44,10 +44,8 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
|
||||
|
||||
if len(ctx.ContextUser.Description) != 0 {
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.Repo.RepoLink,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
Ctx: ctx,
|
||||
}, ctx.ContextUser.Description)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
@@ -84,7 +82,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
|
||||
func FindUserProfileReadme(ctx *context.Context) (profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
|
||||
profileDbRepo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile")
|
||||
if err == nil && !profileDbRepo.IsEmpty && !profileDbRepo.IsPrivate {
|
||||
if profileGitRepo, err = git.OpenRepository(ctx, profileDbRepo.RepoPath()); err != nil {
|
||||
@@ -97,7 +95,7 @@ func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository
|
||||
}
|
||||
}
|
||||
}
|
||||
return profileGitRepo, profileReadmeBlob, func() {
|
||||
return profileDbRepo, profileGitRepo, profileReadmeBlob, func() {
|
||||
if profileGitRepo != nil {
|
||||
_ = profileGitRepo.Close()
|
||||
}
|
||||
@@ -107,7 +105,7 @@ func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository
|
||||
func RenderUserHeader(ctx *context.Context) {
|
||||
prepareContextForCommonProfile(ctx)
|
||||
|
||||
_, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx)
|
||||
_, _, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx)
|
||||
defer profileClose()
|
||||
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
|
||||
}
|
||||
|
||||
@@ -246,9 +246,11 @@ func Milestones(ctx *context.Context) {
|
||||
}
|
||||
|
||||
milestones[i].RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: milestones[i].Repo.Link(),
|
||||
Metas: milestones[i].Repo.ComposeMetas(),
|
||||
Ctx: ctx,
|
||||
Links: markup.Links{
|
||||
Base: milestones[i].Repo.Link(),
|
||||
},
|
||||
Metas: milestones[i].Repo.ComposeMetas(),
|
||||
Ctx: ctx,
|
||||
}, milestones[i].Content)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
||||
@@ -7,6 +7,7 @@ package user
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
@@ -64,17 +65,17 @@ func userProfile(ctx *context.Context) {
|
||||
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
|
||||
}
|
||||
|
||||
profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx)
|
||||
profileDbRepo, profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx)
|
||||
defer profileClose()
|
||||
|
||||
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
|
||||
prepareUserProfileTabData(ctx, showPrivate, profileGitRepo, profileReadmeBlob)
|
||||
prepareUserProfileTabData(ctx, showPrivate, profileDbRepo, profileGitRepo, profileReadmeBlob)
|
||||
// call PrepareContextForProfileBigAvatar later to avoid re-querying the NumFollowers & NumFollowing
|
||||
shared_user.PrepareContextForProfileBigAvatar(ctx)
|
||||
ctx.HTML(http.StatusOK, tplProfile)
|
||||
}
|
||||
|
||||
func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGitRepo *git.Repository, profileReadme *git.Blob) {
|
||||
func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadme *git.Blob) {
|
||||
// if there is a profile readme, default to "overview" page, otherwise, default to "repositories" page
|
||||
// if there is not a profile readme, the overview tab should be treated as the repositories tab
|
||||
tab := ctx.FormString("tab")
|
||||
@@ -236,7 +237,16 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
|
||||
if profileContent, err := markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
GitRepo: profileGitRepo,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
Links: markup.Links{
|
||||
// Give the repo link to the markdown render for the full link of media element.
|
||||
// the media link usually be like /[user]/[repoName]/media/branch/[branchName],
|
||||
// Eg. /Tom/.profile/media/branch/main
|
||||
// The branch shown on the profile page is the default branch, this need to be in sync with doc, see:
|
||||
// https://docs.gitea.com/usage/profile-readme
|
||||
Base: profileDbRepo.Link(),
|
||||
BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)),
|
||||
},
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
}, bytes); err != nil {
|
||||
log.Error("failed to RenderString: %v", err)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user