staticfiles

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2019 License: MIT Imports: 12 Imported by: 1

README

Overview

Build Status GoDoc

staticfiles collect files from a different directories (including subdirectories), compute hash of each file, append hash sum to the filenames and copy files to the output directory. This approach allows to use aggressive caching on CDN and HTTP headers for static files and to implement so called cache hierarchy strategy. If you ever worked with Django you'll find it very similar to the staticfiles application.

Installation

go get -u github.com/catcombo/go-staticfiles/...

Usage

There are two ways to collect files:

  1. Using command line tool

    Run collectstatic --output web/staticfiles --input assets/static --input media/.

    Init storage in your code:

    storage := staticfiles.NewStorage("web/staticfiles")
    err := storage.LoadManifest()
    

    Pros: Run separately from the main application and doesn't influence it start up time. Also can be run on a docker container build stage to automate the process.

    Cons: You may forget to run the command if you do not configure it to run automatically.

  2. Collect files every time the program starts

    storage := staticfiles.NewStorage("web/staticfiles")
    storage.AddInputDir("assets/static")
    storage.AddInputDir("media")
    
    err := storage.CollectStatic()
    

    Pros: Collecting files runs automatically every time the program starts.

    Cons: Collecting files need a time. Thus, the application is running but is not accept incoming connections until collecting is finished.

For use in templates, define a static files prefix and register the template function for resolving files in the storage at the original relative path:

staticFilesPrefix := "/static/"
staticFilesRoot := "output/dir"

storage := NewStorage(staticFilesRoot)
err := storage.LoadManifest()

funcs := template.FuncMap{
    "static": func(relPath string) string {
        return staticFilesPrefix + storage.Resolve(relPath)
    },
}
tmpl := template.Must(
    template.New("").Funcs(funcs).ParseFiles("templates/main.tpl")
)

Now you can call static function in templates like this {{static "css/style.css"}}. The call will be automatically converted to /static/css/style.d41d8cd98f00b204e9800998ecf8427e.css (hash may vary).

Post-processing

staticfiles by default post-process .css files to fix files references.

Sample input file css/style.css

@import "import.css";

div {
    background: url("../img/pix.png");
}

Output file css/style.d41d8cd98f00b204e9800998ecf8427e.css (hashes may vary)

@import "import.5f15d96d5cdb4d0d5eb6901181826a04.css";

div {
    background: url("../img/pix.3eaf17869bb51bf27bd7c91bc9853973.png");
}

Writing custom post-processing rules

You can add custom rule to post-process files. A rule is a simple function with a signature func(*Storage, *StaticFile) error which must be registered by call storage.RegisterRule(CustomRule) See postprocess.go as an example of .css post-processing implementation.

Disable static directory listing

Its often require to disable directory listing when serving static files via http.FileServer. staticfiles comes with staticfiles.FileSystem which implements this feature. Usage:

fs := staticfiles.FileSystem(staticFilesRoot, true)
h := http.StripPrefix(staticFilesPrefix, http.FileServer(fs))

Documentation

Index

Constants

View Source
const ManifestFilename string = "staticfiles.json"
View Source
const ManifestVersion int = 1

Variables

View Source
var ErrManifestVersionMismatch = errors.New("manifest version mismatch")

Functions

func FileSystem

func FileSystem(path string, disableDirList bool) http.FileSystem

Returns http.FileSystem implementation to be used in http.FileServer to serve static files. disableDirList param allows to disable directories listing (in opposite to as it goes by default with http.Dir).

func PostProcessCSS

func PostProcessCSS(storage *Storage, file *StaticFile) error

Post-process CSS files to fix references to the static files in the following cases: - url("../path/file.ext") - @import "path/file.ext" - sourceMappingURL=style.css.map

Types

type ManifestScheme

type ManifestScheme struct {
	Paths   map[string]string `json:"paths"`
	Version int               `json:"version"`
}

type PostProcessRule

type PostProcessRule func(*Storage, *StaticFile) error

type StaticFile

type StaticFile struct {
	Path           string
	RelPath        string
	StoragePath    string
	StorageRelPath string
}

type Storage

type Storage struct {
	Root     string
	FilesMap map[string]*StaticFile
	// contains filtered or unexported fields
}

func NewStorage

func NewStorage(root string) *Storage

func (*Storage) AddInputDir

func (s *Storage) AddInputDir(path string)

func (*Storage) CollectStatic

func (s *Storage) CollectStatic() error

Collects files from Storage.inputDir (including subdirectories), compute hash of each file, append hash sum to the filenames, apply post-process rules, copy files to the Storage.Root directory along with the manifest file, containing map original paths to the storage paths.

func (*Storage) LoadManifest

func (s *Storage) LoadManifest() error

Loads data from ManifestFilename, stored in the Storage.Root directory, to the Storage.FilesMap. Manifest contains files mapping from the original relative paths to the storage relative paths.

func (*Storage) RegisterRule

func (s *Storage) RegisterRule(rule PostProcessRule)

func (*Storage) Resolve

func (s *Storage) Resolve(relPath string) string

Resolve file path relative to the one of the Storage.inputDirs to the storage path relative to the Storage.Root.

func (*Storage) SetVerboseOutput

func (s *Storage) SetVerboseOutput(verbose bool)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL