mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
simplify some examples
This commit is contained in:
parent
7a19cfb211
commit
7b6a8f1e26
|
@ -28,6 +28,7 @@ The codebase for Dependency Injection, Internationalization and localization and
|
||||||
|
|
||||||
## Fixes and Improvements
|
## Fixes and Improvements
|
||||||
|
|
||||||
|
- Add `iris.DirOptions.SPA bool` field to allow [Single Page Applications](https://github.com/kataras/iris/tree/master/_examples/file-server/single-page-application/basic/main.go) under a file server.
|
||||||
- A generic User interface, see the `Context.SetUser/User` methods in the New Context Methods section for more. In-short, the basicauth middleware's stored user can now be retrieved through `Context.User()` which provides more information than the native `ctx.Request().BasicAuth()` method one. Third-party authentication middleware creators can benefit of these two methods, plus the Logout below.
|
- A generic User interface, see the `Context.SetUser/User` methods in the New Context Methods section for more. In-short, the basicauth middleware's stored user can now be retrieved through `Context.User()` which provides more information than the native `ctx.Request().BasicAuth()` method one. Third-party authentication middleware creators can benefit of these two methods, plus the Logout below.
|
||||||
- A `Context.Logout` method is added, can be used to invalidate [basicauth](https://github.com/kataras/iris/blob/master/_examples/auth/basicauth/main.go) or [jwt](https://github.com/kataras/iris/blob/master/_examples/auth/jwt/blocklist/main.go) client credentials.
|
- A `Context.Logout` method is added, can be used to invalidate [basicauth](https://github.com/kataras/iris/blob/master/_examples/auth/basicauth/main.go) or [jwt](https://github.com/kataras/iris/blob/master/_examples/auth/jwt/blocklist/main.go) client credentials.
|
||||||
- Add the ability to [share functions](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-funcs) between handlers chain and add an [example](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-services) on sharing Go structures (aka services).
|
- Add the ability to [share functions](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-funcs) between handlers chain and add an [example](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-services) on sharing Go structures (aka services).
|
||||||
|
|
|
@ -57,7 +57,7 @@ func h(ctx iris.Context) {
|
||||||
// OR:
|
// OR:
|
||||||
user := ctx.User()
|
user := ctx.User()
|
||||||
username, _ := user.GetUsername()
|
username, _ := user.GetUsername()
|
||||||
password, _ := user.GetPassword
|
password, _ := user.GetPassword()
|
||||||
ctx.Writef("%s %s:%s", ctx.Path(), username, password)
|
ctx.Writef("%s %s:%s", ctx.Path(), username, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.1.2
|
||||||
github.com/kataras/iris/v12 v12.2.0-alpha.0.20201031040657-23d4c411cadb
|
github.com/kataras/iris/v12 v12.2.0-alpha.0.20201106220849-7a19cfb2112f
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/kataras/iris/v12"
|
||||||
"github.com/kataras/iris/v12"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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 {
|
func newApp() *iris.Application {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
app.RegisterView(iris.HTML("./public", ".html"))
|
|
||||||
|
|
||||||
app.Get("/", func(ctx iris.Context) {
|
app.HandleDir("/", iris.Dir("./public"), iris.DirOptions{
|
||||||
ctx.ViewData("Page", page)
|
IndexName: "index.html",
|
||||||
ctx.View("index.html")
|
SPA: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
app.HandleDir("/", iris.Dir("./public"))
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +17,7 @@ func main() {
|
||||||
app := newApp()
|
app := newApp()
|
||||||
|
|
||||||
// http://localhost:8080
|
// http://localhost:8080
|
||||||
// http://localhost:8080/index.html
|
// http://localhost:8080/about
|
||||||
// http://localhost:8080/app.js
|
// http://localhost:8080/a_notfound
|
||||||
// http://localhost:8080/css/main.css
|
|
||||||
app.Listen(":8080")
|
app.Listen(":8080")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/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(false))
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
window.alert("app.js loaded from \"/");
|
|
|
@ -1,3 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
|
@ -1,14 +1,19 @@
|
||||||
<html>
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>{{ .Page.Title }}</title>
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Iris SPA Router Example</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1> Hello from index.html </h1>
|
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="/app.js"> </script>
|
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
|
||||||
|
<script src="./index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,21 @@
|
||||||
|
const NotFound = { template: '<p>Page not found</p>' }
|
||||||
|
const Home = { template: '<p>home page</p>' }
|
||||||
|
const About = { template: '<p>about page</p>' }
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
'/': Home,
|
||||||
|
'/about': About
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {
|
||||||
|
currentRoute: window.location.pathname
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
ViewComponent () {
|
||||||
|
return routes[this.currentRoute] || NotFound
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render (h) { return h(this.ViewComponent) }
|
||||||
|
})
|
|
@ -44,7 +44,7 @@ func newApp() *iris.Application {
|
||||||
//
|
//
|
||||||
// First parameter: Glob filpath patern,
|
// First parameter: Glob filpath patern,
|
||||||
// Second variadic parameter: Optional language tags, the first one is the default/fallback one.
|
// Second variadic parameter: Optional language tags, the first one is the default/fallback one.
|
||||||
err := app.I18n.Load("./locales/*/*.ini", "en-US", "el-GR", "zh-CN")
|
err := app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[forms]
|
[forms]
|
||||||
member = μέλος
|
member = μέλος
|
||||||
register = Γίνε {{tr "forms.member" }}
|
register = Γίνε {{uppercase (tr "forms.member") }}
|
||||||
registered = εγγεγραμμένοι
|
registered = εγγεγραμμένοι
|
||||||
registered_members = Υπάρχουν {{ concat (plural (tr "forms.member") .count) (tr "forms.registered") }}
|
|
|
@ -1 +0,0 @@
|
||||||
HiDogs: Hi %d {{plural (tr "Dog") .count }}
|
|
|
@ -1,5 +1,4 @@
|
||||||
[forms]
|
[forms]
|
||||||
member = member
|
member = member
|
||||||
register = Become a {{tr "forms.member" }}
|
register = Become a {{uppercase (tr "forms.member") }}
|
||||||
registered = registered
|
registered = registered
|
||||||
registered_members = There are {{ concat (plural (tr "forms.member") .count) (tr "forms.registered") }}
|
|
|
@ -1,2 +0,0 @@
|
||||||
Dog: "dog"
|
|
||||||
HiDogs: Hi %d {{plural (tr "Dog") .count }}
|
|
|
@ -5,20 +5,11 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
|
|
||||||
// go get -u golang.org/x/text/message
|
|
||||||
|
|
||||||
"golang.org/x/text/feature/plural"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
"golang.org/x/text/message"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Iris I18n supports text/template inside the translation values.
|
Iris I18n supports text/template inside the translation values.
|
||||||
Follow this example to learn how to use that feature.
|
Follow this example to learn how to use that feature.
|
||||||
|
|
||||||
This is just an example on how to use template functions.
|
|
||||||
See the "plurals" example for a more comprehensive pluralization support instead.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -29,75 +20,29 @@ func main() {
|
||||||
func newApp() *iris.Application {
|
func newApp() *iris.Application {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
||||||
// set the printers after load, so they can be done by loop of available languages.
|
|
||||||
printers := make(map[string]*message.Printer)
|
|
||||||
|
|
||||||
message.Set(language.Greek, "Hello %d dog",
|
|
||||||
plural.Selectf(1, "%d",
|
|
||||||
"one", "Γεια σου σκυλί",
|
|
||||||
"other", "Γεια σας %[1]d σκυλιά",
|
|
||||||
))
|
|
||||||
|
|
||||||
/* by variable, single word:
|
|
||||||
message.Set(language.Greek, "Hi %d dog(s)",
|
|
||||||
catalog.Var("dogs", plural.Selectf(1, "%d", "one", "σκυλί", "other", "σκυλιά")),
|
|
||||||
catalog.String("Γεια %[1]d ${dogs}"))
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set custom functions per locale!
|
// Set custom functions per locale!
|
||||||
app.I18n.Loader.Funcs = func(current iris.Locale) template.FuncMap {
|
app.I18n.Loader.Funcs = func(current iris.Locale) template.FuncMap {
|
||||||
return template.FuncMap{
|
return template.FuncMap{
|
||||||
"plural": func(word string, count int) string {
|
|
||||||
// Your own implementation or use a 3rd-party package
|
|
||||||
// like we do here.
|
|
||||||
return printers[current.Language()].Sprintf(word, count)
|
|
||||||
},
|
|
||||||
"uppercase": func(word string) string {
|
"uppercase": func(word string) string {
|
||||||
return strings.ToUpper(word)
|
return strings.ToUpper(word)
|
||||||
},
|
},
|
||||||
"concat": func(words ...string) string {
|
|
||||||
return strings.Join(words, " ")
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := app.I18n.Load("./locales/*/*", "en-US", "el-GR")
|
err := app.I18n.Load("./locales/*/*.ini", "en-US", "el-GR")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tag := range app.I18n.Tags() {
|
|
||||||
printers[tag.String()] = message.NewPrinter(tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
message.NewPrinter(language.Greek).Printf("Hello %d dog", 2)
|
|
||||||
|
|
||||||
app.Get("/", func(ctx iris.Context) {
|
app.Get("/", func(ctx iris.Context) {
|
||||||
text := ctx.Tr("HiDogs", iris.Map{
|
text := ctx.Tr("forms.register") // en-US: prints "Become a MEMBER".
|
||||||
"count": 2,
|
|
||||||
}) // en-US: prints "Hi 2 dogs".
|
|
||||||
ctx.WriteString(text)
|
ctx.WriteString(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/singular", func(ctx iris.Context) {
|
app.Get("/title", func(ctx iris.Context) {
|
||||||
text := ctx.Tr("HiDogs", iris.Map{
|
text := ctx.Tr("user.connections.Title") // en-US: prints "Accounts Connections".
|
||||||
"count": 1,
|
|
||||||
}) // en-US: prints "Hi 1 dog".
|
|
||||||
ctx.WriteString(text)
|
ctx.WriteString(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/members", func(ctx iris.Context) {
|
|
||||||
text := ctx.Tr("forms.registered_members", iris.Map{
|
|
||||||
"count": 42,
|
|
||||||
}) // en-US: prints "There are 42 members registered".
|
|
||||||
ctx.WriteString(text)
|
|
||||||
})
|
|
||||||
|
|
||||||
// showcases the other.ini translation file.
|
|
||||||
app.Get("/other", func(ctx iris.Context) {
|
|
||||||
ctx.Writef(`AccessLogClear: %s
|
|
||||||
Title: %s`, ctx.Tr("debug.AccessLogClear"), ctx.Tr("user.connections.Title"))
|
|
||||||
})
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,11 @@ func TestI18nLoaderFuncMap(t *testing.T) {
|
||||||
|
|
||||||
e := httptest.New(t, app)
|
e := httptest.New(t, app)
|
||||||
e.GET("/").Expect().Status(httptest.StatusOK).
|
e.GET("/").Expect().Status(httptest.StatusOK).
|
||||||
Body().Equal("Hi 2 dogs")
|
Body().Equal("Become a MEMBER")
|
||||||
e.GET("/singular").Expect().Status(httptest.StatusOK).
|
e.GET("/title").Expect().Status(httptest.StatusOK).
|
||||||
Body().Equal("Hi 1 dog")
|
Body().Equal("Account Connections")
|
||||||
e.GET("/members").Expect().Status(httptest.StatusOK).
|
|
||||||
Body().Equal("There are 42 members registered")
|
|
||||||
e.GET("/").WithHeader("Accept-Language", "el").Expect().Status(httptest.StatusOK).
|
e.GET("/").WithHeader("Accept-Language", "el").Expect().Status(httptest.StatusOK).
|
||||||
Body().Equal("Γειά 2 σκυλί")
|
Body().Equal("Γίνε ΜΈΛΟΣ")
|
||||||
|
e.GET("/title").WithHeader("Accept-Language", "el").Expect().Status(httptest.StatusOK).
|
||||||
e.GET("/other").Expect().Status(httptest.StatusOK).
|
Body().Equal("Λογαριασμός Συνδέσεις")
|
||||||
Body().Equal("AccessLogClear: Clear Access Log\nTitle: Account Connections")
|
|
||||||
e.GET("/other").WithHeader("Accept-Language", "el").Expect().Status(httptest.StatusOK).
|
|
||||||
Body().Equal("AccessLogClear: Καθαρισμός Πρόσβαση στο αρχείο καταγραφής\nTitle: Λογαριασμός Συνδέσεις")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,7 +365,7 @@ func (i *I18n) getLocaleMessage(loc context.Locale, langInput string, key string
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg == "" && i.DefaultMessageFunc != nil {
|
if msg == "" && i.DefaultMessageFunc != nil {
|
||||||
msg = i.DefaultMessageFunc(langInput, langMatched, key, args)
|
msg = i.DefaultMessageFunc(langInput, langMatched, key, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue
Block a user