Ctrl K
ComunidadGuías…

engine/renderer.go

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

Archivo original ↗Preguntar a KiBot
package engine

import (
	"net/http"

	"github.com/sirupsen/logrus"
)

// Renderer handles a small file extension by reading it through the cache and
// writing a response. Extensions that need more request context stay in the FilePage switch.
type Renderer interface {
	// Extensions returns the lowercased file extensions (with the dot) handled by this renderer
	Extensions() []string
	// Render writes the response for the given file. Returned errors are logged by the caller.
	Render(ac *Config, w http.ResponseWriter, req *http.Request, filename, ext string) error
}

// rendererRegistry maps a file extension to its Renderer
type rendererRegistry struct {
	byExt map[string]Renderer
}

func newRendererRegistry() *rendererRegistry {
	return &rendererRegistry{byExt: make(map[string]Renderer)}
}

// register adds a Renderer under each of its declared extensions, and panics on collision
func (r *rendererRegistry) register(rd Renderer) {
	for _, ext := range rd.Extensions() {
		if _, exists := r.byExt[ext]; exists {
			panic("engine: duplicate renderer registered for extension " + ext)
		}
		r.byExt[ext] = rd
	}
}

// lookup returns the Renderer for ext, or (nil, false) if none is registered
func (r *rendererRegistry) lookup(ext string) (Renderer, bool) {
	rd, ok := r.byExt[ext]
	return rd, ok
}

// defaultRenderers is the package-level registry, populated by init() in renderers_builtin.go
var defaultRenderers = newRendererRegistry()

// dispatchRenderer invokes the Renderer registered for ext, if any.
// Returns true if a renderer was invoked, false if the caller should fall through.
func (ac *Config) dispatchRenderer(w http.ResponseWriter, req *http.Request, filename, ext string) bool {
	rd, ok := defaultRenderers.lookup(ext)
	if !ok {
		return false
	}
	if err := rd.Render(ac, w, req, filename, ext); err != nil {
		logrus.Error(err)
	}
	return true
}