internal/frontend: group digits for import and importer counts

Display the number of imported or importing packages with a digit
separator.

Change-Id: I2552b4e46b4948bbb11dda4c371a916711b7edf4
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/347408
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/frontend/imports.go b/internal/frontend/imports.go
index 624af4c..7203adb 100644
--- a/internal/frontend/imports.go
+++ b/internal/frontend/imports.go
@@ -6,14 +6,14 @@
 
 import (
 	"context"
-	"fmt"
-	"strconv"
 	"strings"
 
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/log"
+	"golang.org/x/pkgsite/internal/middleware"
 	"golang.org/x/pkgsite/internal/postgres"
 	"golang.org/x/pkgsite/internal/stdlib"
+	"golang.org/x/text/message"
 )
 
 // ImportsDetails contains information for a package's imports.
@@ -126,6 +126,7 @@
 	// Display the number of importers, taking into account the number we
 	// actually retrieved, the limit on that number, and the imported-by count
 	// in the search_documents table.
+	pr := message.NewPrinter(middleware.LanguageTag(ctx))
 	var (
 		display string
 		pkgword = "package"
@@ -137,21 +138,21 @@
 	// If there are more importers than the limit, and the search number is
 	// greater, use the search number and indicate that we're displaying fewer.
 	case numImportedBy >= importedByLimit && numImportedBySearch > numImportedBy:
-		display = fmt.Sprintf("%d (displaying %d %s)", numImportedBySearch, importedByLimit-1, pkgword)
+		display = pr.Sprintf("%d (displaying %d %s)", numImportedBySearch, importedByLimit-1, pkgword)
 	// If we've exceeded the limit but the search number is smaller, we don't
 	// know the true number, so say so.
 	case numImportedBy >= importedByLimit:
-		display = fmt.Sprintf("%d (displaying more than %d %s, including internal and invalid packages)", numImportedBySearch, importedByLimit-1, pkgword)
+		display = pr.Sprintf("%d (displaying more than %d %s, including internal and invalid packages)", numImportedBySearch, importedByLimit-1, pkgword)
 	// If we haven't exceeded the limit and we have more than the search number,
 	// then display both numbers so users coming from the search page won't see
 	// a mismatch.
 	case numImportedBy > numImportedBySearch:
-		display = fmt.Sprintf("%d (displaying %d %s, including internal and invalid packages)", numImportedBySearch, numImportedBy, pkgword)
+		display = pr.Sprintf("%d (displaying %d %s, including internal and invalid packages)", numImportedBySearch, numImportedBy, pkgword)
 	// Otherwise, we have all the packages, and the search number is either
 	// wrong (perhaps it hasn't been recomputed yet) or it is the same as the
 	// retrieved number. In that case, just display the retrieved number.
 	default:
-		display = strconv.Itoa(numImportedBy)
+		display = pr.Sprint(numImportedBy)
 	}
 	return &ImportedByDetails{
 		ModulePath:           modulePath,
diff --git a/internal/frontend/main.go b/internal/frontend/main.go
index a78dec5..7e445aa 100644
--- a/internal/frontend/main.go
+++ b/internal/frontend/main.go
@@ -18,6 +18,7 @@
 	"golang.org/x/pkgsite/internal/log"
 	"golang.org/x/pkgsite/internal/middleware"
 	"golang.org/x/pkgsite/internal/version"
+	"golang.org/x/text/message"
 )
 
 // MainDetails contains data needed to render the unit template.
@@ -30,7 +31,7 @@
 	Licenses []LicenseMetadata
 
 	// NumImports is the number of imports for the package.
-	NumImports int
+	NumImports string
 
 	// CommitTime is time that this version was published, or the time that
 	// has elapsed since this version was committed if it was done so recently.
@@ -59,7 +60,7 @@
 	// ImportedByCount is the number of packages that import this path.
 	// When the count is > limit it will read as 'limit+'. This field
 	// is not supported when using a datasource proxy.
-	ImportedByCount int
+	ImportedByCount string
 
 	DocBody       safehtml.HTML
 	DocOutline    safehtml.HTML
@@ -194,6 +195,7 @@
 	}
 	isTaggedVersion := versionType != version.TypePseudo
 	isStableVersion := semver.Major(um.Version) != "v0" && versionType == version.TypeRelease
+	pr := message.NewPrinter(middleware.LanguageTag(ctx))
 	return &MainDetails{
 		ExpandReadme:      expandReadme,
 		Directories:       unitDirectories(append(subdirectories, nestedModules...)),
@@ -214,8 +216,8 @@
 		RepositoryURL:     um.SourceInfo.RepoURL(),
 		SourceURL:         um.SourceInfo.DirectoryURL(internal.Suffix(um.Path, um.ModulePath)),
 		MobileOutline:     docParts.MobileOutline,
-		NumImports:        unit.NumImports,
-		ImportedByCount:   unit.NumImportedBy,
+		NumImports:        pr.Sprint(unit.NumImports),
+		ImportedByCount:   pr.Sprint(unit.NumImportedBy),
 		IsPackage:         unit.IsPackage(),
 		ModFileURL:        um.SourceInfo.ModuleURL() + "/go.mod",
 		IsTaggedVersion:   isTaggedVersion,