Ctrl K
ComunidadGuías…

templates/embed.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package templates

import (
	"bytes"
	"embed"
	"io"
	"io/fs"
	"os"
	"path"
	"strings"

	"github.com/cockroachdb/errors"
	"gopkg.in/macaron.v1"

	"gogs.io/gogs/internal/osx"
)

//go:embed **/*
var files embed.FS

// fileSystem implements the macaron.TemplateFileSystem interface.
type fileSystem struct {
	files []macaron.TemplateFile
}

func (fs *fileSystem) ListFiles() []macaron.TemplateFile {
	return fs.files
}

func (fs *fileSystem) Get(name string) (io.Reader, error) {
	for i := range fs.files {
		if fs.files[i].Name()+fs.files[i].Ext() == name {
			return bytes.NewReader(fs.files[i].Data()), nil
		}
	}
	return nil, errors.Newf("file %q not found", name)
}

func mustNames(fsys fs.FS) []string {
	var names []string
	walkDirFunc := func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if !d.IsDir() {
			names = append(names, path)
		}
		return nil
	}
	if err := fs.WalkDir(fsys, ".", walkDirFunc); err != nil {
		panic("assetNames failure: " + err.Error())
	}
	return names
}

// MailFileNames returns the embedded template file paths under "mail/",
// each relative to the "mail" directory (e.g. "auth/activate.tmpl").
func MailFileNames() []string {
	var names []string
	for _, name := range mustNames(files) {
		if rel, ok := strings.CutPrefix(name, "mail/"); ok {
			names = append(names, rel)
		}
	}
	return names
}

// ReadMailFile returns the embedded mail template bytes at the given path
// relative to the "mail" directory.
func ReadMailFile(name string) ([]byte, error) {
	return files.ReadFile(path.Join("mail", name))
}

// ReadInjectFile returns the content of the named injection template.
func ReadInjectFile(customDir, name string) ([]byte, error) {
	fpath := path.Join(customDir, "inject", name)
	if osx.IsFile(fpath) {
		return os.ReadFile(fpath)
	}
	return files.ReadFile(path.Join("inject", name))
}

// NewTemplateFileSystem returns a macaron.TemplateFileSystem instance for embedded assets.
// The argument "dir" can be used to serve subset of embedded assets. Template file
// found under the "customDir" on disk has higher precedence over embedded assets.
func NewTemplateFileSystem(dir, customDir string) macaron.TemplateFileSystem {
	if dir != "" && !strings.HasSuffix(dir, "/") {
		dir += "/"
	}

	var err error
	var tmplFiles []macaron.TemplateFile
	names := mustNames(files)
	for _, name := range names {
		if !strings.HasPrefix(name, dir) {
			continue
		}
		// Check if corresponding custom file exists
		var data []byte
		fpath := path.Join(customDir, name)
		if osx.IsFile(fpath) {
			data, err = os.ReadFile(fpath)
		} else {
			data, err = files.ReadFile(name)
		}
		if err != nil {
			panic(err)
		}
		name = strings.TrimPrefix(name, dir)
		ext := path.Ext(name)
		name = strings.TrimSuffix(name, ext)
		tmplFiles = append(tmplFiles, macaron.NewTplFile(name, data, ext))
	}
	return &fileSystem{files: tmplFiles}
}