feat: support folder index pages
This commit is contained in:
@@ -60,6 +60,8 @@ type browserItem struct {
|
||||
Path string
|
||||
URL string
|
||||
IsFolder bool
|
||||
IsIndex bool
|
||||
HasIndex bool
|
||||
Active bool
|
||||
}
|
||||
|
||||
@@ -82,12 +84,16 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleDocsIndexRedirect(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
func (s *Server) handleDocsIndex(w http.ResponseWriter, r *http.Request) {
|
||||
s.renderDocumentPage(w, r, "")
|
||||
}
|
||||
|
||||
func (s *Server) handleDocument(w http.ResponseWriter, r *http.Request) {
|
||||
pagePath := chi.URLParam(r, "*")
|
||||
s.renderDocumentPage(w, r, pagePath)
|
||||
}
|
||||
|
||||
func (s *Server) renderDocumentPage(w http.ResponseWriter, r *http.Request, pagePath string) {
|
||||
page, err := s.documents.LoadPage(r.Context(), pagePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
@@ -271,9 +277,13 @@ func writeJSONWithStatus(w http.ResponseWriter, status int, payload any) {
|
||||
func buildBrowser(records []docs.DocumentRecord, activePath string) browserData {
|
||||
paths := make([]string, 0, len(records))
|
||||
titleByPath := make(map[string]string, len(records))
|
||||
indexByFolder := make(map[string]string)
|
||||
for _, record := range records {
|
||||
paths = append(paths, record.Path)
|
||||
titleByPath[record.Path] = record.Title
|
||||
if folder, ok := indexFolder(record.Path); ok {
|
||||
indexByFolder[folder] = record.Path
|
||||
}
|
||||
}
|
||||
|
||||
prefixes := []string{""}
|
||||
@@ -292,7 +302,7 @@ func buildBrowser(records []docs.DocumentRecord, activePath string) browserData
|
||||
for _, prefix := range prefixes {
|
||||
column := browserColumn{
|
||||
Title: columnTitle(prefix),
|
||||
Items: buildBrowserItems(paths, titleByPath, prefix, activePath),
|
||||
Items: buildBrowserItems(paths, titleByPath, indexByFolder, prefix, activePath),
|
||||
}
|
||||
if len(column.Items) > 0 {
|
||||
columns = append(columns, column)
|
||||
@@ -302,7 +312,7 @@ func buildBrowser(records []docs.DocumentRecord, activePath string) browserData
|
||||
return browserData{Columns: columns}
|
||||
}
|
||||
|
||||
func buildBrowserItems(paths []string, titleByPath map[string]string, prefix string, activePath string) []browserItem {
|
||||
func buildBrowserItems(paths []string, titleByPath map[string]string, indexByFolder map[string]string, prefix string, activePath string) []browserItem {
|
||||
seenFolders := make(map[string]browserItem)
|
||||
files := make([]browserItem, 0)
|
||||
prefixWithSlash := ""
|
||||
@@ -311,6 +321,10 @@ func buildBrowserItems(paths []string, titleByPath map[string]string, prefix str
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if shouldHideIndexFile(path, prefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
if prefix != "" && !strings.HasPrefix(path, prefixWithSlash) {
|
||||
continue
|
||||
}
|
||||
@@ -326,21 +340,28 @@ func buildBrowserItems(paths []string, titleByPath map[string]string, prefix str
|
||||
if prefix != "" {
|
||||
folderPath = prefix + "/" + name
|
||||
}
|
||||
indexPath, hasIndex := indexByFolder[folderPath]
|
||||
url := "/?folder=" + folderPath
|
||||
if hasIndex {
|
||||
url = "/docs/" + strings.TrimSuffix(indexPath, "/index.md")
|
||||
}
|
||||
seenFolders[folderPath] = browserItem{
|
||||
Name: name,
|
||||
Name: displayFolderName(name, indexPath, titleByPath),
|
||||
Path: folderPath,
|
||||
URL: "/?folder=" + folderPath,
|
||||
URL: url,
|
||||
IsFolder: true,
|
||||
HasIndex: hasIndex,
|
||||
Active: activePath == folderPath || strings.HasPrefix(activePath, folderPath+"/"),
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
files = append(files, browserItem{
|
||||
Name: displayDocumentName(path, titleByPath[path]),
|
||||
Path: path,
|
||||
URL: "/docs/" + strings.TrimSuffix(path, ".md"),
|
||||
Active: activePath == path,
|
||||
Name: displayDocumentName(path, titleByPath[path]),
|
||||
Path: path,
|
||||
URL: "/docs/" + strings.TrimSuffix(path, ".md"),
|
||||
IsIndex: path == "index.md" || strings.HasSuffix(path, "/index.md"),
|
||||
Active: activePath == path,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -372,3 +393,34 @@ func displayDocumentName(path string, title string) string {
|
||||
}
|
||||
return strings.TrimSuffix(filepath.Base(path), ".md")
|
||||
}
|
||||
|
||||
func displayFolderName(name string, indexPath string, titleByPath map[string]string) string {
|
||||
if indexPath == "" {
|
||||
return name
|
||||
}
|
||||
if title := titleByPath[indexPath]; title != "" && title != "Untitled" {
|
||||
return title
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func indexFolder(path string) (string, bool) {
|
||||
if path == "index.md" {
|
||||
return "", true
|
||||
}
|
||||
if !strings.HasSuffix(path, "/index.md") {
|
||||
return "", false
|
||||
}
|
||||
return strings.TrimSuffix(path, "/index.md"), true
|
||||
}
|
||||
|
||||
func shouldHideIndexFile(path string, prefix string) bool {
|
||||
if path == "index.md" {
|
||||
return false
|
||||
}
|
||||
if !strings.HasSuffix(path, "/index.md") {
|
||||
return false
|
||||
}
|
||||
folder := strings.TrimSuffix(path, "/index.md")
|
||||
return folder == prefix
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user