diff options
author | Gary Wang <wzc782970009@gmail.com> | 2022-08-01 06:36:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-01 01:36:58 +0300 |
commit | c35535ce071c221fa0e529b89c3df462df769377 (patch) | |
tree | a52e3dd8847da9553bba5b27d7518ae9005d629a /routers/web/repo/view.go | |
parent | 335e918b1129ef6e0dd03a4713de90e68fbb23e3 (diff) | |
download | gitea-c35535ce071c221fa0e529b89c3df462df769377.tar.gz gitea-c35535ce071c221fa0e529b89c3df462df769377.zip |
Support localized README (#20508)
* Support localized README
* Slightly simplify getting the readme file and add some tests. Ensure that i18n also
works for docs/ etc.
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Update modules/markup/renderer.go
* Update modules/markup/renderer.go
* Update modules/markup/renderer.go
Co-authored-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'routers/web/repo/view.go')
-rw-r--r-- | routers/web/repo/view.go | 123 |
1 files changed, 54 insertions, 69 deletions
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index c5657aa675..6a9c6b9bba 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -57,7 +57,7 @@ type namedBlob struct { } // FIXME: There has to be a more efficient way of doing this -func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, error) { +func getReadmeFileFromPath(ctx *context.Context, commit *git.Commit, treePath string) (*namedBlob, error) { tree, err := commit.SubTree(treePath) if err != nil { return nil, err @@ -68,50 +68,33 @@ func getReadmeFileFromPath(commit *git.Commit, treePath string) (*namedBlob, err return nil, err } - var readmeFiles [4]*namedBlob - exts := []string{".md", ".txt", ""} // sorted by priority + // Create a list of extensions in priority order + // 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md + // 2. Txt files - e.g. README.txt + // 3. No extension - e.g. README + exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority + extCount := len(exts) + readmeFiles := make([]*namedBlob, extCount+1) for _, entry := range entries { if entry.IsDir() { continue } - for i, ext := range exts { - if markup.IsReadmeFile(entry.Name(), ext) { - if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) { - name := entry.Name() - isSymlink := entry.IsLink() - target := entry - if isSymlink { - target, err = entry.FollowLinks() - if err != nil && !git.IsErrBadLink(err) { - return nil, err - } - } - if target != nil && (target.IsExecutable() || target.IsRegular()) { - readmeFiles[i] = &namedBlob{ - name, - isSymlink, - target.Blob(), - } - } - } - } - } - - if markup.IsReadmeFile(entry.Name()) { - if readmeFiles[3] == nil || base.NaturalSortLess(readmeFiles[3].name, entry.Blob().Name()) { + if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok { + if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].name, entry.Blob().Name()) { name := entry.Name() isSymlink := entry.IsLink() + target := entry if isSymlink { - entry, err = entry.FollowLinks() + target, err = entry.FollowLinks() if err != nil && !git.IsErrBadLink(err) { return nil, err } } - if entry != nil && (entry.IsExecutable() || entry.IsRegular()) { - readmeFiles[3] = &namedBlob{ + if target != nil && (target.IsExecutable() || target.IsRegular()) { + readmeFiles[i] = &namedBlob{ name, isSymlink, - entry.Blob(), + target.Blob(), } } } @@ -151,13 +134,38 @@ func renderDirectory(ctx *context.Context, treeLink string) { renderReadmeFile(ctx, readmeFile, readmeTreelink) } +// localizedExtensions prepends the provided language code with and without a +// regional identifier to the provided extenstion. +// Note: the language code will always be lower-cased, if a region is present it must be separated with a `-` +// Note: ext should be prefixed with a `.` +func localizedExtensions(ext, languageCode string) (localizedExts []string) { + if len(languageCode) < 1 { + return []string{ext} + } + + lowerLangCode := "." + strings.ToLower(languageCode) + + if strings.Contains(lowerLangCode, "-") { + underscoreLangCode := strings.ReplaceAll(lowerLangCode, "-", "_") + indexOfDash := strings.Index(lowerLangCode, "-") + // e.g. [.zh-cn.md, .zh_cn.md, .zh.md, .md] + return []string{lowerLangCode + ext, underscoreLangCode + ext, lowerLangCode[:indexOfDash] + ext, ext} + } + + // e.g. [.en.md, .md] + return []string{lowerLangCode + ext, ext} +} + func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) (*namedBlob, string) { - // 3 for the extensions in exts[] in order - // the last one is for a readme that doesn't - // strictly match an extension - var readmeFiles [4]*namedBlob - var docsEntries [3]*git.TreeEntry - exts := []string{".md", ".txt", ""} // sorted by priority + // Create a list of extensions in priority order + // 1. Markdown files - with and without localisation - e.g. README.en-us.md or README.md + // 2. Txt files - e.g. README.txt + // 3. No extension - e.g. README + exts := append(localizedExtensions(".md", ctx.Language()), ".txt", "") // sorted by priority + extCount := len(exts) + readmeFiles := make([]*namedBlob, extCount+1) + + docsEntries := make([]*git.TreeEntry, 3) // (one of docs/, .gitea/ or .github/) for _, entry := range entries { if entry.IsDir() { lowerName := strings.ToLower(entry.Name()) @@ -178,47 +186,24 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) continue } - for i, ext := range exts { - if markup.IsReadmeFile(entry.Name(), ext) { - log.Debug("%s", entry.Name()) - name := entry.Name() - isSymlink := entry.IsLink() - target := entry - if isSymlink { - var err error - target, err = entry.FollowLinks() - if err != nil && !git.IsErrBadLink(err) { - ctx.ServerError("FollowLinks", err) - return nil, "" - } - } - log.Debug("%t", target == nil) - if target != nil && (target.IsExecutable() || target.IsRegular()) { - readmeFiles[i] = &namedBlob{ - name, - isSymlink, - target.Blob(), - } - } - } - } - - if markup.IsReadmeFile(entry.Name()) { + if i, ok := markup.IsReadmeFileExtension(entry.Name(), exts...); ok { + log.Debug("Potential readme file: %s", entry.Name()) name := entry.Name() isSymlink := entry.IsLink() + target := entry if isSymlink { var err error - entry, err = entry.FollowLinks() + target, err = entry.FollowLinks() if err != nil && !git.IsErrBadLink(err) { ctx.ServerError("FollowLinks", err) return nil, "" } } - if entry != nil && (entry.IsExecutable() || entry.IsRegular()) { - readmeFiles[3] = &namedBlob{ + if target != nil && (target.IsExecutable() || target.IsRegular()) { + readmeFiles[i] = &namedBlob{ name, isSymlink, - entry.Blob(), + target.Blob(), } } } @@ -239,7 +224,7 @@ func findReadmeFile(ctx *context.Context, entries git.Entries, treeLink string) continue } var err error - readmeFile, err = getReadmeFileFromPath(ctx.Repo.Commit, entry.GetSubJumpablePathName()) + readmeFile, err = getReadmeFileFromPath(ctx, ctx.Repo.Commit, entry.GetSubJumpablePathName()) if err != nil { ctx.ServerError("getReadmeFileFromPath", err) return nil, "" |