fix wrong link in user and organization profile when using relative url (#28617)

fix #28436.
the doc https://docs.gitea.com/usage/profile-readme maybe also need to
be updated to tell that
the main branch is necessary,which means the following three conditions
should be satisfied:
- repo: **.profile**
- branch: **[default branch]**
- markdown: **README.md**
This commit is contained in:
katsu 2023-12-27 16:32:27 +08:00 committed by GitHub
parent baf0d402d9
commit 42149ff1a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 15 deletions

View file

@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
shared_user "code.gitea.io/gitea/routers/web/shared/user" shared_user "code.gitea.io/gitea/routers/web/shared/user"
) )
@ -157,14 +158,14 @@ func Home(ctx *context.Context) {
ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0 ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0
profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer) profileDbRepo, profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose() defer profileClose()
prepareOrgProfileReadme(ctx, profileGitRepo, profileReadmeBlob) prepareOrgProfileReadme(ctx, profileGitRepo, profileDbRepo, profileReadmeBlob)
ctx.HTML(http.StatusOK, tplOrgHome) ctx.HTML(http.StatusOK, tplOrgHome)
} }
func prepareOrgProfileReadme(ctx *context.Context, profileGitRepo *git.Repository, profileReadme *git.Blob) { func prepareOrgProfileReadme(ctx *context.Context, profileGitRepo *git.Repository, profileDbRepo *repo_model.Repository, profileReadme *git.Blob) {
if profileGitRepo == nil || profileReadme == nil { if profileGitRepo == nil || profileReadme == nil {
return return
} }
@ -172,10 +173,14 @@ func prepareOrgProfileReadme(ctx *context.Context, profileGitRepo *git.Repositor
if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil { if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("failed to GetBlobContent: %v", err) log.Error("failed to GetBlobContent: %v", err)
} else { } else {
// Pass URLPrefix to markdown render for the full link of media elements.
// The profile of default branch would be shown.
prefix := profileDbRepo.Link() + "/src/branch/" + util.PathEscapeSegments(profileDbRepo.DefaultBranch)
if profileContent, err := markdown.RenderString(&markup.RenderContext{ if profileContent, err := markdown.RenderString(&markup.RenderContext{
Ctx: ctx, Ctx: ctx,
GitRepo: profileGitRepo, GitRepo: profileGitRepo,
Metas: map[string]string{"mode": "document"}, URLPrefix: prefix,
Metas: map[string]string{"mode": "document"},
}, bytes); err != nil { }, bytes); err != nil {
log.Error("failed to RenderString: %v", err) log.Error("failed to RenderString: %v", err)
} else { } else {

View file

@ -87,7 +87,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
} }
} }
func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) { func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ".profile") profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ".profile")
if err == nil { if err == nil {
perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer) perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer)
@ -105,7 +105,7 @@ func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profile
} else if !repo_model.IsErrRepoNotExist(err) { } else if !repo_model.IsErrRepoNotExist(err) {
log.Error("FindUserProfileReadme failed to GetRepositoryByName: %v", err) log.Error("FindUserProfileReadme failed to GetRepositoryByName: %v", err)
} }
return profileGitRepo, profileReadmeBlob, func() { return profileDbRepo, profileGitRepo, profileReadmeBlob, func() {
if profileGitRepo != nil { if profileGitRepo != nil {
_ = profileGitRepo.Close() _ = profileGitRepo.Close()
} }
@ -115,7 +115,7 @@ func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profile
func RenderUserHeader(ctx *context.Context) { func RenderUserHeader(ctx *context.Context) {
prepareContextForCommonProfile(ctx) prepareContextForCommonProfile(ctx)
_, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx, ctx.Doer) _, _, profileReadmeBlob, profileClose := FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose() defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
} }

View file

@ -64,17 +64,17 @@ func userProfile(ctx *context.Context) {
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data) ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
} }
profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer) profileDbRepo, profileGitRepo, profileReadmeBlob, profileClose := shared_user.FindUserProfileReadme(ctx, ctx.Doer)
defer profileClose() defer profileClose()
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) 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 // call PrepareContextForProfileBigAvatar later to avoid re-querying the NumFollowers & NumFollowing
shared_user.PrepareContextForProfileBigAvatar(ctx) shared_user.PrepareContextForProfileBigAvatar(ctx)
ctx.HTML(http.StatusOK, tplProfile) 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 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 // if there is not a profile readme, the overview tab should be treated as the repositories tab
tab := ctx.FormString("tab") tab := ctx.FormString("tab")
@ -233,10 +233,18 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil { if bytes, err := profileReadme.GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("failed to GetBlobContent: %v", err) log.Error("failed to GetBlobContent: %v", err)
} else { } else {
// Give the URLPrefix 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
prefix := profileDbRepo.Link() + "/src/branch/" + util.PathEscapeSegments(profileDbRepo.DefaultBranch)
if profileContent, err := markdown.RenderString(&markup.RenderContext{ if profileContent, err := markdown.RenderString(&markup.RenderContext{
Ctx: ctx, Ctx: ctx,
GitRepo: profileGitRepo, GitRepo: profileGitRepo,
Metas: map[string]string{"mode": "document"}, URLPrefix: prefix,
Metas: map[string]string{"mode": "document"},
}, bytes); err != nil { }, bytes); err != nil {
log.Error("failed to RenderString: %v", err) log.Error("failed to RenderString: %v", err)
} else { } else {