mirror of
https://github.com/kataras/iris.git
synced 2025-12-27 14:57:05 +00:00
Add notes for the new lead maintainer of the open-source iris project and align with @get-ion/ion by @hiveminded
Former-commit-id: da4f38eb9034daa49446df3ee529423b98f9b331
This commit is contained in:
44
_examples/file-server/single-page-application/basic/main.go
Normal file
44
_examples/file-server/single-page-application/basic/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
"github.com/kataras/iris/view"
|
||||
)
|
||||
|
||||
// same as embedded-single-page-application but without go-bindata, the files are "physical" stored in the
|
||||
// current system directory.
|
||||
|
||||
var page = struct {
|
||||
Title string
|
||||
}{"Welcome"}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.RegisterView(view.HTML("./public", ".html"))
|
||||
|
||||
app.Get("/", func(ctx context.Context) {
|
||||
ctx.ViewData("Page", page)
|
||||
ctx.View("index.html")
|
||||
})
|
||||
|
||||
// or just serve index.html as it is:
|
||||
// app.Get("/", func(ctx context.Context) {
|
||||
// ctx.ServeFile("index.html", false)
|
||||
// })
|
||||
|
||||
assetHandler := app.StaticHandler("./public", false, false)
|
||||
app.SPA(assetHandler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// http://localhost:8080
|
||||
// http://localhost:8080/index.html
|
||||
// http://localhost:8080/app.js
|
||||
// http://localhost:8080/css/main.css
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/httptest"
|
||||
)
|
||||
|
||||
type resource string
|
||||
|
||||
func (r resource) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func (r resource) strip(strip string) string {
|
||||
s := r.String()
|
||||
return strings.TrimPrefix(s, strip)
|
||||
}
|
||||
|
||||
func (r resource) loadFromBase(dir string) string {
|
||||
filename := r.String()
|
||||
|
||||
if filename == "/" {
|
||||
filename = "/index.html"
|
||||
}
|
||||
|
||||
fullpath := filepath.Join(dir, filename)
|
||||
|
||||
b, err := ioutil.ReadFile(fullpath)
|
||||
if err != nil {
|
||||
panic(fullpath + " failed with error: " + err.Error())
|
||||
}
|
||||
|
||||
result := string(b)
|
||||
return result
|
||||
}
|
||||
|
||||
var urls = []resource{
|
||||
"/",
|
||||
"/index.html",
|
||||
"/app.js",
|
||||
"/css/main.css",
|
||||
}
|
||||
|
||||
func TestSPA(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app, httptest.Debug(true))
|
||||
|
||||
for _, u := range urls {
|
||||
url := u.String()
|
||||
contents := u.loadFromBase("./public")
|
||||
contents = strings.Replace(contents, "{{ .Page.Title }}", page.Title, 1)
|
||||
|
||||
e.GET(url).Expect().
|
||||
Status(httptest.StatusOK).
|
||||
Body().Equal(contents)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
window.alert("app.js loaded from \"/");
|
||||
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{ .Page.Title }}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1> Hello from index.html </h1>
|
||||
|
||||
|
||||
<script src="/app.js"> </script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,285 @@
|
||||
// Code generated by go-bindata.
|
||||
// sources:
|
||||
// public/app.js
|
||||
// public/css/main.css
|
||||
// public/index.html
|
||||
// DO NOT EDIT!
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, gz)
|
||||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _publicAppJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2a\xcf\xcc\x4b\xc9\x2f\xd7\x4b\xcc\x49\x2d\x2a\xd1\x50\x4a\x2c\x28\xd0\xcb\x2a\x56\xc8\xc9\x4f\x4c\x49\x4d\x51\x48\x2b\xca\xcf\x55\x88\x51\xd2\x57\xd2\xb4\x06\x04\x00\x00\xff\xff\xa9\x06\xf7\xa3\x27\x00\x00\x00")
|
||||
|
||||
func publicAppJsBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_publicAppJs,
|
||||
"public/app.js",
|
||||
)
|
||||
}
|
||||
|
||||
func publicAppJs() (*asset, error) {
|
||||
bytes, err := publicAppJsBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "public/app.js", size: 39, mode: os.FileMode(438), modTime: time.Unix(1497458456, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _publicCssMainCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\xca\x4f\xa9\x54\xa8\xe6\xe5\x52\x50\x50\x50\x48\x4a\x4c\xce\x4e\x2f\xca\x2f\xcd\x4b\xd1\x4d\xce\xcf\xc9\x2f\xb2\x52\x48\xca\x49\x4c\xce\xb6\xe6\xe5\xaa\xe5\xe5\x02\x04\x00\x00\xff\xff\x03\x25\x9c\x89\x29\x00\x00\x00")
|
||||
|
||||
func publicCssMainCssBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_publicCssMainCss,
|
||||
"public/css/main.css",
|
||||
)
|
||||
}
|
||||
|
||||
func publicCssMainCss() (*asset, error) {
|
||||
bytes, err := publicCssMainCssBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "public/css/main.css", size: 41, mode: os.FileMode(438), modTime: time.Unix(1497455997, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _publicIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x8e\x41\x0e\xc2\x20\x10\x45\xf7\x24\xdc\xe1\xa7\x07\x80\x74\x3f\xb2\x76\xe9\xc2\x0b\x60\x41\xc1\x50\x21\xc0\x42\xd3\xf4\xee\x06\x4a\x97\x93\xf7\x66\xde\x90\xab\x6b\x50\x9c\x71\x46\xce\x6a\xa3\x38\x03\x00\xaa\xbe\x06\xab\xb6\x0d\xe2\xa6\x5f\x56\xdc\xdb\x88\x7d\x27\x79\x00\xce\x48\x0e\x9d\x33\x7a\x44\xf3\x3b\x17\xdd\xac\x70\xb5\x21\x44\x3c\x73\x5c\xe1\x3f\xc6\x7e\x45\x6b\x80\xa4\x9b\xbb\x3f\xcc\xb2\x64\x9f\x2a\x4a\x5e\x2e\x93\xd4\x29\x89\x77\x99\x14\x40\xf2\x00\xbd\x31\x2e\xf7\x5c\xfb\xf3\x1f\x00\x00\xff\xff\x25\xe9\x37\x57\xae\x00\x00\x00")
|
||||
|
||||
func publicIndexHtmlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
_publicIndexHtml,
|
||||
"public/index.html",
|
||||
)
|
||||
}
|
||||
|
||||
func publicIndexHtml() (*asset, error) {
|
||||
bytes, err := publicIndexHtmlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "public/index.html", size: 174, mode: os.FileMode(438), modTime: time.Unix(1497460815, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.bytes, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
|
||||
// MustAsset is like Asset but panics when Asset would return an error.
|
||||
// It simplifies safe initialization of global variables.
|
||||
func MustAsset(name string) []byte {
|
||||
a, err := Asset(name)
|
||||
if err != nil {
|
||||
panic("asset: Asset(" + name + "): " + err.Error())
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// AssetInfo loads and returns the asset info for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func AssetInfo(name string) (os.FileInfo, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.info, nil
|
||||
}
|
||||
return nil, fmt.Errorf("AssetInfo %s not found", name)
|
||||
}
|
||||
|
||||
// AssetNames returns the names of the assets.
|
||||
func AssetNames() []string {
|
||||
names := make([]string, 0, len(_bindata))
|
||||
for name := range _bindata {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"public/app.js": publicAppJs,
|
||||
"public/css/main.css": publicCssMainCss,
|
||||
"public/index.html": publicIndexHtml,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
// directory embedded in the file by go-bindata.
|
||||
// For example if you run go-bindata on data/... and data contains the
|
||||
// following hierarchy:
|
||||
// data/
|
||||
// foo.txt
|
||||
// img/
|
||||
// a.png
|
||||
// b.png
|
||||
// then AssetDir("data") would return []string{"foo.txt", "img"}
|
||||
// AssetDir("data/img") would return []string{"a.png", "b.png"}
|
||||
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
|
||||
// AssetDir("") will return []string{"data"}.
|
||||
func AssetDir(name string) ([]string, error) {
|
||||
node := _bintree
|
||||
if len(name) != 0 {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
pathList := strings.Split(cannonicalName, "/")
|
||||
for _, p := range pathList {
|
||||
node = node.Children[p]
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Func != nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"public": {nil, map[string]*bintree{
|
||||
"app.js": {publicAppJs, map[string]*bintree{}},
|
||||
"css": {nil, map[string]*bintree{
|
||||
"main.css": {publicCssMainCss, map[string]*bintree{}},
|
||||
}},
|
||||
"index.html": {publicIndexHtml, map[string]*bintree{}},
|
||||
}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory
|
||||
func RestoreAsset(dir, name string) error {
|
||||
data, err := Asset(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := AssetInfo(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreAssets restores an asset under the given directory recursively
|
||||
func RestoreAssets(dir, name string) error {
|
||||
children, err := AssetDir(name)
|
||||
// File
|
||||
if err != nil {
|
||||
return RestoreAsset(dir, name)
|
||||
}
|
||||
// Dir
|
||||
for _, child := range children {
|
||||
err = RestoreAssets(dir, filepath.Join(name, child))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/context"
|
||||
"github.com/kataras/iris/view"
|
||||
)
|
||||
|
||||
// $ go get -u github.com/jteeuwen/go-bindata/...
|
||||
// $ go-bindata ./public/...
|
||||
// $ go build
|
||||
// $ ./embedded-single-page-application
|
||||
|
||||
var page = struct {
|
||||
Title string
|
||||
}{"Welcome"}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.RegisterView(view.HTML("./public", ".html").Binary(Asset, AssetNames))
|
||||
|
||||
app.Get("/", func(ctx context.Context) {
|
||||
ctx.ViewData("Page", page)
|
||||
ctx.View("index.html")
|
||||
})
|
||||
|
||||
assetHandler := app.StaticEmbeddedHandler("./public", Asset, AssetNames)
|
||||
app.SPA(assetHandler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// http://localhost:8080
|
||||
// http://localhost:8080/index.html
|
||||
// http://localhost:8080/app.js
|
||||
// http://localhost:8080/css/main.css
|
||||
app.Run(iris.Addr(":8080"))
|
||||
}
|
||||
|
||||
// Note that app.Use/UseGlobal/Done will be executed
|
||||
// only to the registered routes like our index (app.Get("/", ..)).
|
||||
// The file server is clean, but you can still add middleware to that by wrapping its "assetHandler".
|
||||
//
|
||||
// With this method, unlike StaticWeb("/" , "./public") which is not working by-design anymore,
|
||||
// all custom http errors and all routes are working fine with a file server that is registered
|
||||
// to the root path of the server.
|
||||
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/httptest"
|
||||
)
|
||||
|
||||
type resource string
|
||||
|
||||
func (r resource) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func (r resource) strip(strip string) string {
|
||||
s := r.String()
|
||||
return strings.TrimPrefix(s, strip)
|
||||
}
|
||||
|
||||
func (r resource) loadFromBase(dir string) string {
|
||||
filename := r.String()
|
||||
|
||||
if filename == "/" {
|
||||
filename = "/index.html"
|
||||
}
|
||||
|
||||
fullpath := filepath.Join(dir, filename)
|
||||
|
||||
b, err := ioutil.ReadFile(fullpath)
|
||||
if err != nil {
|
||||
panic(fullpath + " failed with error: " + err.Error())
|
||||
}
|
||||
result := string(b)
|
||||
if runtime.GOOS != "windows" {
|
||||
result = strings.Replace(result, "\n", "\r\n", -1)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var urls = []resource{
|
||||
"/",
|
||||
"/index.html",
|
||||
"/app.js",
|
||||
"/css/main.css",
|
||||
}
|
||||
|
||||
func TestSPAEmbedded(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
for _, u := range urls {
|
||||
url := u.String()
|
||||
contents := u.loadFromBase("./public")
|
||||
contents = strings.Replace(contents, "{{ .Page.Title }}", page.Title, 1)
|
||||
|
||||
e.GET(url).Expect().
|
||||
Status(httptest.StatusOK).
|
||||
Body().Equal(contents)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
window.alert("app.js loaded from \"/");
|
||||
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{ .Page.Title }}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1> Hello from index.html </h1>
|
||||
|
||||
|
||||
<script src="/app.js"> </script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user