diff --git a/routers/web/org/home.go b/routers/web/org/home.go index 8f14f8899c..87e69e7a6b 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -5,6 +5,8 @@ package org import ( "fmt" + gotemplate "html/template" + "io" "net/http" "path" "strings" @@ -180,20 +182,30 @@ func prepareOrgProfileReadme(ctx *context.Context, profileGitRepo *git.Repositor } else { defer rc.Close() - if profileContent, err := markdown.RenderReader(&markup.RenderContext{ - Ctx: ctx, - GitRepo: profileGitRepo, - Links: markup.Links{ - // Pass repo link to markdown render for the full link of media elements. - // The profile of default branch would be shown. - Base: profileDbRepo.Link(), - BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)), - }, - Metas: map[string]string{"mode": "document"}, - }, rc); err != nil { - log.Error("failed to RenderString: %v", err) + if markupType := markup.Type(profileReadme.Name()); markupType != "" { + if profileContent, err := markdown.RenderReader(&markup.RenderContext{ + Ctx: ctx, + Type: markupType, + GitRepo: profileGitRepo, + Links: markup.Links{ + // Pass repo link to markdown render for the full link of media elements. + // The profile of default branch would be shown. + Base: profileDbRepo.Link(), + BranchPath: path.Join("branch", util.PathEscapeSegments(profileDbRepo.DefaultBranch)), + }, + Metas: map[string]string{"mode": "document"}, + }, rc); err != nil { + log.Error("failed to RenderString: %v", err) + } else { + ctx.Data["ProfileReadme"] = profileContent + } } else { - ctx.Data["ProfileReadme"] = profileContent + content, err := io.ReadAll(rc) + if err != nil { + log.Error("Read readme content failed: %v", err) + } + ctx.Data["ProfileReadme"] = gotemplate.HTMLEscapeString(util.UnsafeBytesToString(content)) + ctx.Data["IsProfileReadmePlain"] = true } } } diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 379e23cce4..87feb966cb 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -22,6 +22,7 @@ import ( "forgejo.org/modules/markup/markdown" "forgejo.org/modules/optional" "forgejo.org/modules/setting" + "forgejo.org/routers/web/repo" "forgejo.org/services/context" ) @@ -104,7 +105,22 @@ func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profile if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil { log.Error("FindUserProfileReadme failed to GetBranchCommit: %v", err) } else { - profileReadmeBlob, _ = commit.GetBlobByFoldedPath("README.md") + tree, err := commit.SubTree("") + if err != nil { + log.Error("FindUserProfileReadme failed to get SubTree: %v", err) + } else { + entries, err := tree.ListEntries() + if err != nil { + log.Error("FindUserProfileReadme failed to list entries: %v", err) + } else { + _, readmeEntry, err := repo.FindReadmeFileInEntries(ctx, entries, true) + if err != nil { + log.Error("FindUserProfileReadme failed to find readme in entries: %v", err) + } else if readmeEntry != nil { + profileReadmeBlob = readmeEntry.Blob() + } + } + } } } } diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 78dd6c5e7c..02cea05a47 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -8,6 +8,8 @@ package user import ( "errors" "fmt" + gotemplate "html/template" + "io" "net/http" "path" "strings" @@ -269,23 +271,33 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb } else { defer rc.Close() - if profileContent, err := markdown.RenderReader(&markup.RenderContext{ - Ctx: ctx, - GitRepo: profileGitRepo, - 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"}, - }, rc); err != nil { - log.Error("failed to RenderString: %v", err) + if markupType := markup.Type(profileReadme.Name()); markupType != "" { + if profileContent, err := markdown.RenderReader(&markup.RenderContext{ + Ctx: ctx, + Type: markupType, + GitRepo: profileGitRepo, + 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"}, + }, rc); err != nil { + log.Error("failed to RenderString: %v", err) + } else { + ctx.Data["ProfileReadme"] = profileContent + } } else { - ctx.Data["ProfileReadme"] = profileContent + content, err := io.ReadAll(rc) + if err != nil { + log.Error("Read readme content failed: %v", err) + } + ctx.Data["ProfileReadme"] = gotemplate.HTMLEscapeString(util.UnsafeBytesToString(content)) + ctx.Data["IsProfileReadmePlain"] = true } } default: // default to "repositories" diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index a4fafc3432..ba13b9446c 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -11,7 +11,13 @@
{{if .ProfileReadme}} -
{{.ProfileReadme}}
+
+ {{if .IsProfileReadmePlain}} +
{{.ProfileReadme}}
+ {{else}} + {{.ProfileReadme}} + {{end}} +
{{end}} {{template "shared/repo_search" .}} {{template "explore/repo_list" .}} diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 1d62f3eea9..30210a1775 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -51,7 +51,13 @@ {{else if eq .TabName "followers"}} {{template "repo/user_cards" .}} {{else if eq .TabName "overview"}} -
{{.ProfileReadme}}
+
+ {{if .IsProfileReadmePlain}} +
{{.ProfileReadme}}
+ {{else}} + {{.ProfileReadme}} + {{end}} +
{{else}} {{template "shared/repo_search" .}} {{template "explore/repo_list" .}} diff --git a/tests/integration/org_profile_test.go b/tests/integration/org_profile_test.go index 8125c3e6ba..2cd80cc1de 100644 --- a/tests/integration/org_profile_test.go +++ b/tests/integration/org_profile_test.go @@ -64,7 +64,15 @@ func TestOrgProfile(t *testing.T) { checkReadme(t, "README.md", "README.md", 1) checkReadme(t, "readme.md", "readme.md", 1) checkReadme(t, "ReadMe.mD", "ReadMe.mD", 1) - checkReadme(t, "readme.org does not render", "README.org", 0) + checkReadme(t, "readme.org", "README.org", 1) + checkReadme(t, "README.en-us.md", "README.en-us.md", 1) + checkReadme(t, "README.en.md", "README.en.md", 1) + checkReadme(t, "README.txt", "README.txt", 1) + checkReadme(t, "README", "README", 1) + checkReadme(t, "README.mdown", "README.mdown", 1) + checkReadme(t, "README.i18n.md", "README.i18n.md", 1) + checkReadme(t, "readmee", "readmee", 0) + checkReadme(t, "test.md", "test.md", 0) t.Run("readme-size", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/user_profile_test.go b/tests/integration/user_profile_test.go index fb96efcd64..0e3668f1d5 100644 --- a/tests/integration/user_profile_test.go +++ b/tests/integration/user_profile_test.go @@ -64,7 +64,15 @@ func TestUserProfile(t *testing.T) { checkReadme(t, "README.md", "README.md", 1) checkReadme(t, "readme.md", "readme.md", 1) checkReadme(t, "ReadMe.mD", "ReadMe.mD", 1) - checkReadme(t, "readme.org does not render", "README.org", 0) + checkReadme(t, "readme.org", "README.org", 1) + checkReadme(t, "README.en-us.md", "README.en-us.md", 1) + checkReadme(t, "README.en.md", "README.en.md", 1) + checkReadme(t, "README.txt", "README.txt", 1) + checkReadme(t, "README", "README", 1) + checkReadme(t, "README.mdown", "README.mdown", 1) + checkReadme(t, "README.i18n.md", "README.i18n.md", 1) + checkReadme(t, "readmee", "readmee", 0) + checkReadme(t, "test.md", "test.md", 0) t.Run("readme-size", func(t *testing.T) { defer tests.PrintCurrentTest(t)()