mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
Update to version 10.0.1 - read more at: https://github.com/kataras/iris/blob/master/HISTORY.md#mo-15-jenuary-2018--v1001
Former-commit-id: 292d155c877ba3f9d1210db54c3df3fedd1d0c1c
This commit is contained in:
parent
ad9c76adb3
commit
a19e570c8a
10
FAQ.md
10
FAQ.md
|
@ -1,5 +1,15 @@
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
|
## [![iris](https://img.shields.io/badge/iris-powered-2196f3.svg?style=for-the-badge)](https://github.com/kataras/iris)
|
||||||
|
|
||||||
|
Add a `badge` to your open-source projects powered by [Iris](https://iris-go.com) by pasting the below code snippet to the project repo's README.md:
|
||||||
|
|
||||||
|
```md
|
||||||
|
[![iris](https://img.shields.io/badge/iris-powered-2196f3.svg?style=for-the-badge)](https://github.com/kataras/iris)
|
||||||
|
```
|
||||||
|
|
||||||
|
> The badge is optionally, of course, it is just a simple and fast way to support Iris. The badge is work of a third-party, taken from https://github.com/blob-go/blob-go which was published by our friend @clover113 and we loved it<3
|
||||||
|
|
||||||
## How to upgrade
|
## How to upgrade
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
2
Gopkg.lock
generated
2
Gopkg.lock
generated
|
@ -173,7 +173,7 @@
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/satori/go.uuid"
|
name = "github.com/satori/go.uuid"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "5bf94b69c6b68ee1b541973bb8e1144db23a194b"
|
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
|
@ -63,8 +63,8 @@
|
||||||
name = "github.com/ryanuber/columnize"
|
name = "github.com/ryanuber/columnize"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
|
branch = "v1.2.0"
|
||||||
name = "github.com/satori/go.uuid"
|
name = "github.com/satori/go.uuid"
|
||||||
revision = "5bf94b69c6b68ee1b541973bb8e1144db23a194b"
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
28
HISTORY.md
28
HISTORY.md
|
@ -17,6 +17,34 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
|
|
||||||
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
||||||
|
|
||||||
|
# Mo, 15 Jenuary 2018 | v10.0.1
|
||||||
|
|
||||||
|
Not any serious problems were found to be resolved here but one, the first one which is important for devs that used the [cache](cache) package.
|
||||||
|
|
||||||
|
- fix a single one cache handler didn't work across multiple route handlers at the same time https://github.com/kataras/iris/pull/852, as reported at https://github.com/kataras/iris/issues/850
|
||||||
|
- merge PR https://github.com/kataras/iris/pull/862
|
||||||
|
- do not allow concurrent access to the `ExecuteWriter -> Load` when `view#Engine##Reload` was true, as requested at https://github.com/kataras/iris/issues/872
|
||||||
|
- badge for open-source projects powered by Iris, learn how to add that badge to your open-source project at [FAQ.md](FAQ.md) file
|
||||||
|
|
||||||
|
## New Backers
|
||||||
|
|
||||||
|
1. https://opencollective.com/cetin-basoz
|
||||||
|
|
||||||
|
## New Translations
|
||||||
|
|
||||||
|
1. The Chinese README_ZH.md and HISTORY_ZH.md was translated by @Zeno-Code via https://github.com/kataras/iris/pull/858
|
||||||
|
2. New Russian README_RU.md translations by @merrydii via https://github.com/kataras/iris/pull/857
|
||||||
|
3. New Greek README_GR.md and HISTORY_GR.md translations via https://github.com/kataras/iris/commit/8c4e17c2a5433c36c148a51a945c4dc35fbe502a#diff-74b06c740d860f847e7b577ad58ddde0 and https://github.com/kataras/iris/commit/bb5a81c540b34eaf5c6c8e993f644a0e66a78fb8
|
||||||
|
|
||||||
|
## New Examples
|
||||||
|
|
||||||
|
1. [MVC - Register Middleware](_examples/mvc/middleware)
|
||||||
|
|
||||||
|
## New Articles
|
||||||
|
|
||||||
|
1. [A Todo MVC Application using Iris and Vue.js](https://hackernoon.com/a-todo-mvc-application-using-iris-and-vue-js-5019ff870064)
|
||||||
|
2. [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](bit.ly/2lmKaAZ)
|
||||||
|
|
||||||
# Mo, 01 Jenuary 2018 | v10.0.0
|
# Mo, 01 Jenuary 2018 | v10.0.0
|
||||||
|
|
||||||
We must thanks [Mrs. Diana](https://www.instagram.com/merry.dii/) for our awesome new [logo](https://iris-go.com/images/icon.svg)!
|
We must thanks [Mrs. Diana](https://www.instagram.com/merry.dii/) for our awesome new [logo](https://iris-go.com/images/icon.svg)!
|
||||||
|
|
|
@ -17,6 +17,31 @@
|
||||||
|
|
||||||
**Πώς να αναβαθμίσετε**: Ανοίξτε την γραμμή εντολών σας και εκτελέστε αυτήν την εντολή: `go get -u github.com/kataras/iris` ή αφήστε το αυτόματο updater να το κάνει αυτό για σας.
|
**Πώς να αναβαθμίσετε**: Ανοίξτε την γραμμή εντολών σας και εκτελέστε αυτήν την εντολή: `go get -u github.com/kataras/iris` ή αφήστε το αυτόματο updater να το κάνει αυτό για σας.
|
||||||
|
|
||||||
|
# Mo, 15 Jenuary 2018 | v10.0.1
|
||||||
|
|
||||||
|
- διόρθωση του cache handler που δεν δούλευε όπως έπρεπε όταν γινόταν εγγραφή σε πάνω από ένα handler, παλιότερα ήταν ένα cache handler προς ένα route handler, τώρα το ίδιο handler μπορεί να καταχωρηθεί σε όσα route handlers θέλετε https://github.com/kataras/iris/pull/852, όπως είχε αναφερθεί στο https://github.com/kataras/iris/issues/850
|
||||||
|
- συγχώνευση PR https://github.com/kataras/iris/pull/862
|
||||||
|
- απαγόρευση της ταυτόχρονης προσπέλασης του `ExecuteWriter -> Load` όταν το `view#Engine##Reload` είναι true, όπως είχε ζητηθεί στο https://github.com/kataras/iris/issues/872
|
||||||
|
|
||||||
|
## Νέοι Υποστηρικτές
|
||||||
|
|
||||||
|
1. https://opencollective.com/cetin-basoz
|
||||||
|
|
||||||
|
## Νέες Μεταφράσεις
|
||||||
|
|
||||||
|
1. Aναβαθμίσεις για την Κινέζικη μετάφραση README_ZH.md (νέο) και HISTORY_ZH.md από @Zeno-Code μέσω του https://github.com/kataras/iris/pull/858
|
||||||
|
2. Το Ρώσικο README_RU.md μεταφράστηκε από την @merrydii μέσω του https://github.com/kataras/iris/pull/857
|
||||||
|
3. Τα Ελληνικά README_GR.md και HISTORY_GR.md μεταφράστηκαν μέσω των https://github.com/kataras/iris/commit/8c4e17c2a5433c36c148a51a945c4dc35fbe502a#diff-74b06c740d860f847e7b577ad58ddde0 και https://github.com/kataras/iris/commit/bb5a81c540b34eaf5c6c8e993f644a0e66a78fb8
|
||||||
|
|
||||||
|
## Νέα Παραδείγματα
|
||||||
|
|
||||||
|
1. [MVC - Register Middleware](_examples/mvc/middleware)
|
||||||
|
|
||||||
|
## Νέα Άρθρα
|
||||||
|
|
||||||
|
1. [A Todo MVC Application using Iris and Vue.js](https://hackernoon.com/a-todo-mvc-application-using-iris-and-vue-js-5019ff870064)
|
||||||
|
2. [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](bit.ly/2lmKaAZ)
|
||||||
|
|
||||||
# Mo, 01 Jenuary 2018 | v10.0.0
|
# Mo, 01 Jenuary 2018 | v10.0.0
|
||||||
|
|
||||||
Πρέπει να ευχαριστήσουμε την [Κυρία Diana](https://www.instagram.com/merry.dii/) για το νέο μας [λογότυπο](https://iris-go.com/images/icon.svg)!
|
Πρέπει να ευχαριστήσουμε την [Κυρία Diana](https://www.instagram.com/merry.dii/) για το νέο μας [λογότυπο](https://iris-go.com/images/icon.svg)!
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
**如何升级**: 打开命令行执行以下命令: `go get -u github.com/kataras/iris` 或者等待自动更新。
|
**如何升级**: 打开命令行执行以下命令: `go get -u github.com/kataras/iris` 或者等待自动更新。
|
||||||
|
|
||||||
|
# Mo, 15 Jenuary 2018 | v10.0.1
|
||||||
|
|
||||||
|
Translation is missing for this specific history entry, please navigate through [english version of HISTORY.md](HISTORY.md#mo-15-jenuary-2018--v1001) instead or check back later on.
|
||||||
|
|
||||||
# 2018 元旦 | v10.0.0 版本发布
|
# 2018 元旦 | v10.0.0 版本发布
|
||||||
|
|
||||||
我们必须感谢 [Mrs. Diana](https://www.instagram.com/merry.dii/) 帮我们绘制的漂亮 [logo](https://iris-go.com/images/icon.svg)!
|
我们必须感谢 [Mrs. Diana](https://www.instagram.com/merry.dii/) 帮我们绘制的漂亮 [logo](https://iris-go.com/images/icon.svg)!
|
||||||
|
|
|
@ -106,7 +106,7 @@ _Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
- [HISTORY](HISTORY.md#mo-01-jenuary-2018--v1000) file is your best friend, it contains information about the latest features and changes
|
- [HISTORY](HISTORY.md#mo-15-jenuary-2018--v1001) file is your best friend, it contains information about the latest features and changes
|
||||||
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues)
|
||||||
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com)
|
||||||
- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -108,7 +108,7 @@ _Η τελευταία ενημέρωση έγινε την [Τρίτη, 21 Νο
|
||||||
|
|
||||||
## Υποστήριξη
|
## Υποστήριξη
|
||||||
|
|
||||||
- To [HISTORY](HISTORY_GR.md#mo-01-jenuary-2018--v1000) αρχείο είναι ο καλύτερος σας φίλος, περιέχει πληροφορίες σχετικά με τις τελευταίες λειτουργίες(features) και αλλαγές
|
- To [HISTORY](HISTORY_GR.md#mo-15-jenuary-2018--v1001) αρχείο είναι ο καλύτερος σας φίλος, περιέχει πληροφορίες σχετικά με τις τελευταίες λειτουργίες(features) και αλλαγές
|
||||||
- Μήπως τυχαίνει να βρήκατε κάποιο bug; Δημοσιεύστε το στα [github issues](https://github.com/kataras/iris/issues)
|
- Μήπως τυχαίνει να βρήκατε κάποιο bug; Δημοσιεύστε το στα [github issues](https://github.com/kataras/iris/issues)
|
||||||
- Έχετε οποιεσδήποτε ερωτήσεις ή πρέπει να μιλήσετε με κάποιον έμπειρο για την επίλυση ενός προβλήματος σε πραγματικό χρόνο; Ελάτε μαζί μας στην [συνομιλία κοινότητας](https://chat.iris-go.com)
|
- Έχετε οποιεσδήποτε ερωτήσεις ή πρέπει να μιλήσετε με κάποιον έμπειρο για την επίλυση ενός προβλήματος σε πραγματικό χρόνο; Ελάτε μαζί μας στην [συνομιλία κοινότητας](https://chat.iris-go.com)
|
||||||
- Συμπληρώστε την αναφορά εμπειρίας χρήστη κάνοντας κλικ [εδώ](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Συμπληρώστε την αναφορά εμπειρίας χρήστη κάνοντας κλικ [εδώ](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -106,7 +106,7 @@ _Обновлено: [Вторник, 21 ноября 2017 г.](_benchmarks/READ
|
||||||
|
|
||||||
## Поддержка
|
## Поддержка
|
||||||
|
|
||||||
- Файл [HISTORY](HISTORY.md#mo-01-jenuary-2018--v1000) - ваш лучший друг, он содержит информацию о последних особенностях и всех изменениях
|
- Файл [HISTORY](HISTORY.md#mo-15-jenuary-2018--v1001) - ваш лучший друг, он содержит информацию о последних особенностях и всех изменениях
|
||||||
- Вы случайно обнаружили ошибку? Опубликуйте ее на [Github вопросы](https://github.com/kataras/iris/issues)
|
- Вы случайно обнаружили ошибку? Опубликуйте ее на [Github вопросы](https://github.com/kataras/iris/issues)
|
||||||
- У Вас есть какие-либо вопросы или Вам нужно поговорить с кем-то, кто бы смог решить Вашу проблему в режиме реального времени? Присоединяйтесь к нам в [чате сообщества](https://chat.iris-go.com)
|
- У Вас есть какие-либо вопросы или Вам нужно поговорить с кем-то, кто бы смог решить Вашу проблему в режиме реального времени? Присоединяйтесь к нам в [чате сообщества](https://chat.iris-go.com)
|
||||||
- Заполните наш отчет о пользовательском опыте на основе формы, нажав [здесь](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- Заполните наш отчет о пользовательском опыте на основе формы, нажав [здесь](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
|
@ -102,7 +102,7 @@ _更新于: [2017年11月21日星期二](_benchmarks/README_UNIX.md)_
|
||||||
|
|
||||||
## 支持
|
## 支持
|
||||||
|
|
||||||
- [更新记录](HISTORY_ZH.md#mo-01-jenuary-2018--v1000) 是您最好的朋友,它包含有关最新功能和更改的信息
|
- [更新记录](HISTORY_ZH.md#mo-15-jenuary-2018--v1001) 是您最好的朋友,它包含有关最新功能和更改的信息
|
||||||
- 你碰巧找到了一个错误? 请提交 [github issues](https://github.com/kataras/iris/issues)
|
- 你碰巧找到了一个错误? 请提交 [github issues](https://github.com/kataras/iris/issues)
|
||||||
- 您是否有任何疑问或需要与有经验的人士交谈以实时解决问题? [加入我们的聊天](https://chat.iris-go.com)
|
- 您是否有任何疑问或需要与有经验的人士交谈以实时解决问题? [加入我们的聊天](https://chat.iris-go.com)
|
||||||
- [点击这里完成我们基于表单的用户体验报告](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
- [点击这里完成我们基于表单的用户体验报告](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
10.0.0:https://github.com/kataras/iris/blob/master/HISTORY.md#mo-01-jenuary-2018--v1000
|
10.0.1:https://github.com/kataras/iris/blob/master/HISTORY.md#mo-15-jenuary-2018--v1001
|
|
@ -119,6 +119,12 @@ func newApp() *iris.Application {
|
||||||
ctx.Write(b)
|
ctx.Write(b)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.HandleMany("POST PUT", "/postvalue", func(ctx iris.Context) {
|
||||||
|
name := ctx.PostValueDefault("name", "iris")
|
||||||
|
headervale := ctx.GetHeader("headername")
|
||||||
|
ctx.Writef("Hello %s | %s", name, headervale)
|
||||||
|
})
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +158,13 @@ func main() {
|
||||||
http://mysubdomain.localhost:8080/
|
http://mysubdomain.localhost:8080/
|
||||||
|
|
||||||
// PUT
|
// PUT
|
||||||
|
http://localhost:8080/postvalue
|
||||||
http://localhost:8080/games/42/players/93
|
http://localhost:8080/games/42/players/93
|
||||||
http://localhost:8080/games/42/clans/clan/93
|
http://localhost:8080/games/42/clans/clan/93
|
||||||
|
|
||||||
// POST
|
// POST
|
||||||
http://localhost:8080/
|
http://localhost:8080/
|
||||||
|
http://localhost:8080/postvalue
|
||||||
http://localhost:8080/games/42/clans
|
http://localhost:8080/games/42/clans
|
||||||
http://localhost:8080/games/42/players
|
http://localhost:8080/games/42/players
|
||||||
http://localhost:8080/games/42/clans/93/leave
|
http://localhost:8080/games/42/clans/93/leave
|
||||||
|
|
|
@ -129,4 +129,13 @@ func TestRouting(t *testing.T) {
|
||||||
// test with larger body sent and wait for the custom response
|
// test with larger body sent and wait for the custom response
|
||||||
largerBSent := make([]byte, maxBodySize+1, maxBodySize+1)
|
largerBSent := make([]byte, maxBodySize+1, maxBodySize+1)
|
||||||
e.POST("/").WithBytes(largerBSent).Expect().Status(httptest.StatusBadRequest).Body().Equal("http: request body too large")
|
e.POST("/").WithBytes(largerBSent).Expect().Status(httptest.StatusBadRequest).Body().Equal("http: request body too large")
|
||||||
|
|
||||||
|
// test the post value (both post and put) and headers.
|
||||||
|
e.PUT("/postvalue").WithFormField("name", "test_put").
|
||||||
|
WithHeader("headername", "headervalue_put").Expect().
|
||||||
|
Status(httptest.StatusOK).Body().Equal("Hello test_put | headervalue_put")
|
||||||
|
|
||||||
|
e.POST("/postvalue").WithFormField("name", "test_post").
|
||||||
|
WithHeader("headername", "headervalue_post").Expect().
|
||||||
|
Status(httptest.StatusOK).Body().Equal("Hello test_post | headervalue_post")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/kataras/iris"
|
||||||
"github.com/kataras/iris"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the string representation of the current local Iris Web Framework version.
|
// Version is the string representation of the current local Iris Web Framework version.
|
||||||
Version = "10.0.0"
|
Version = "10.0.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckForUpdates checks for any available updates
|
// CheckForUpdates checks for any available updates
|
||||||
|
|
|
@ -20,9 +20,8 @@ type AmberEngine struct {
|
||||||
namesFn func() []string // for embedded, in combination with directory & extension
|
namesFn func() []string // for embedded, in combination with directory & extension
|
||||||
reload bool
|
reload bool
|
||||||
//
|
//
|
||||||
rmu sync.RWMutex // locks for funcs
|
rmu sync.RWMutex // locks for `ExecuteWiter` when `reload` is true.
|
||||||
funcs map[string]interface{}
|
funcs map[string]interface{}
|
||||||
mu sync.Mutex // locks for template files load
|
|
||||||
templateCache map[string]*template.Template
|
templateCache map[string]*template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +56,10 @@ func (s *AmberEngine) Binary(assetFn func(name string) ([]byte, error), namesFn
|
||||||
// Reload if setted to true the templates are reloading on each render,
|
// Reload if setted to true the templates are reloading on each render,
|
||||||
// use it when you're in development and you're boring of restarting
|
// use it when you're in development and you're boring of restarting
|
||||||
// the whole app when you edit a template file.
|
// the whole app when you edit a template file.
|
||||||
|
//
|
||||||
|
// Note that if `true` is passed then only one `View -> ExecuteWriter` will be render each time,
|
||||||
|
// no concurrent access across clients, use it only on development status.
|
||||||
|
// It's good to be used side by side with the https://github.com/kataras/rizla reloader for go source files.
|
||||||
func (s *AmberEngine) Reload(developmentMode bool) *AmberEngine {
|
func (s *AmberEngine) Reload(developmentMode bool) *AmberEngine {
|
||||||
s.reload = developmentMode
|
s.reload = developmentMode
|
||||||
return s
|
return s
|
||||||
|
@ -116,8 +119,6 @@ func (s *AmberEngine) loadDirectory() error {
|
||||||
|
|
||||||
templates, err := amber.CompileDir(dir, opt, amber.DefaultOptions) // this returns the map with stripped extension, we want extension so we copy the map
|
templates, err := amber.CompileDir(dir, opt, amber.DefaultOptions) // this returns the map with stripped extension, we want extension so we copy the map
|
||||||
if err == nil {
|
if err == nil {
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
s.templateCache = make(map[string]*template.Template)
|
s.templateCache = make(map[string]*template.Template)
|
||||||
for k, v := range templates {
|
for k, v := range templates {
|
||||||
name := filepath.ToSlash(k + opt.Ext)
|
name := filepath.ToSlash(k + opt.Ext)
|
||||||
|
@ -155,9 +156,6 @@ func (s *AmberEngine) loadAssets() error {
|
||||||
}
|
}
|
||||||
amber.FuncMap = funcs //set the funcs
|
amber.FuncMap = funcs //set the funcs
|
||||||
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
names := namesFn()
|
names := namesFn()
|
||||||
|
|
||||||
for _, path := range names {
|
for _, path := range names {
|
||||||
|
@ -192,21 +190,22 @@ func (s *AmberEngine) loadAssets() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AmberEngine) fromCache(relativeName string) *template.Template {
|
func (s *AmberEngine) fromCache(relativeName string) *template.Template {
|
||||||
s.mu.Lock()
|
|
||||||
tmpl, ok := s.templateCache[relativeName]
|
tmpl, ok := s.templateCache[relativeName]
|
||||||
if ok {
|
if ok {
|
||||||
s.mu.Unlock()
|
|
||||||
return tmpl
|
return tmpl
|
||||||
}
|
}
|
||||||
s.mu.Unlock()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteWriter executes a template and writes its result to the w writer.
|
// ExecuteWriter executes a template and writes its result to the w writer.
|
||||||
// layout here is useless.
|
// layout here is useless.
|
||||||
func (s *AmberEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
func (s *AmberEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
||||||
// reload the templates if reload configuration field is true
|
// re-parse the templates if reload is enabled.
|
||||||
if s.reload {
|
if s.reload {
|
||||||
|
// locks to fix #872, it's the simplest solution and the most correct,
|
||||||
|
// to execute writers with "wait list", one at a time.
|
||||||
|
s.rmu.Lock()
|
||||||
|
defer s.rmu.Unlock()
|
||||||
if err := s.Load(); err != nil {
|
if err := s.Load(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ type DjangoEngine struct {
|
||||||
namesFn func() []string // for embedded, in combination with directory & extension
|
namesFn func() []string // for embedded, in combination with directory & extension
|
||||||
reload bool
|
reload bool
|
||||||
//
|
//
|
||||||
rmu sync.RWMutex // locks for filters and globals
|
rmu sync.RWMutex // locks for filters, globals and `ExecuteWiter` when `reload` is true.
|
||||||
// filters for pongo2, map[name of the filter] the filter function . The filters are auto register
|
// filters for pongo2, map[name of the filter] the filter function . The filters are auto register
|
||||||
filters map[string]FilterFunction
|
filters map[string]FilterFunction
|
||||||
// globals share context fields between templates. https://github.com/flosch/pongo2/issues/35
|
// globals share context fields between templates. https://github.com/flosch/pongo2/issues/35
|
||||||
|
@ -147,6 +147,10 @@ func (s *DjangoEngine) Binary(assetFn func(name string) ([]byte, error), namesFn
|
||||||
// Reload if setted to true the templates are reloading on each render,
|
// Reload if setted to true the templates are reloading on each render,
|
||||||
// use it when you're in development and you're boring of restarting
|
// use it when you're in development and you're boring of restarting
|
||||||
// the whole app when you edit a template file.
|
// the whole app when you edit a template file.
|
||||||
|
//
|
||||||
|
// Note that if `true` is passed then only one `View -> ExecuteWriter` will be render each time,
|
||||||
|
// no concurrent access across clients, use it only on development status.
|
||||||
|
// It's good to be used side by side with the https://github.com/kataras/rizla reloader for go source files.
|
||||||
func (s *DjangoEngine) Reload(developmentMode bool) *DjangoEngine {
|
func (s *DjangoEngine) Reload(developmentMode bool) *DjangoEngine {
|
||||||
s.reload = developmentMode
|
s.reload = developmentMode
|
||||||
return s
|
return s
|
||||||
|
@ -373,8 +377,12 @@ func (s *DjangoEngine) fromCache(relativeName string) *pongo2.Template {
|
||||||
// ExecuteWriter executes a templates and write its results to the w writer
|
// ExecuteWriter executes a templates and write its results to the w writer
|
||||||
// layout here is useless.
|
// layout here is useless.
|
||||||
func (s *DjangoEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
func (s *DjangoEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
||||||
// reload the templates if reload configuration field is true
|
// re-parse the templates if reload is enabled.
|
||||||
if s.reload {
|
if s.reload {
|
||||||
|
// locks to fix #872, it's the simplest solution and the most correct,
|
||||||
|
// to execute writers with "wait list", one at a time.
|
||||||
|
s.rmu.Lock()
|
||||||
|
defer s.rmu.Unlock()
|
||||||
if err := s.Load(); err != nil {
|
if err := s.Load(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,8 @@ type HandlebarsEngine struct {
|
||||||
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
|
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
|
||||||
// parser configuration
|
// parser configuration
|
||||||
layout string
|
layout string
|
||||||
rmu sync.RWMutex // locks for helpers
|
rmu sync.RWMutex // locks for helpers and `ExecuteWiter` when `reload` is true.
|
||||||
helpers map[string]interface{}
|
helpers map[string]interface{}
|
||||||
mu sync.Mutex // locks for template files load
|
|
||||||
templateCache map[string]*raymond.Template
|
templateCache map[string]*raymond.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +65,10 @@ func (s *HandlebarsEngine) Binary(assetFn func(name string) ([]byte, error), nam
|
||||||
// Reload if setted to true the templates are reloading on each render,
|
// Reload if setted to true the templates are reloading on each render,
|
||||||
// use it when you're in development and you're boring of restarting
|
// use it when you're in development and you're boring of restarting
|
||||||
// the whole app when you edit a template file.
|
// the whole app when you edit a template file.
|
||||||
|
//
|
||||||
|
// Note that if `true` is passed then only one `View -> ExecuteWriter` will be render each time,
|
||||||
|
// no concurrent access across clients, use it only on development status.
|
||||||
|
// It's good to be used side by side with the https://github.com/kataras/rizla reloader for go source files.
|
||||||
func (s *HandlebarsEngine) Reload(developmentMode bool) *HandlebarsEngine {
|
func (s *HandlebarsEngine) Reload(developmentMode bool) *HandlebarsEngine {
|
||||||
s.reload = developmentMode
|
s.reload = developmentMode
|
||||||
return s
|
return s
|
||||||
|
@ -123,8 +126,7 @@ func (s *HandlebarsEngine) loadDirectory() error {
|
||||||
|
|
||||||
// the render works like {{ render "myfile.html" theContext.PartialContext}}
|
// the render works like {{ render "myfile.html" theContext.PartialContext}}
|
||||||
// instead of the html/template engine which works like {{ render "myfile.html"}} and accepts the parent binding, with handlebars we can't do that because of lack of runtime helpers (dublicate error)
|
// instead of the html/template engine which works like {{ render "myfile.html"}} and accepts the parent binding, with handlebars we can't do that because of lack of runtime helpers (dublicate error)
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
var templateErr error
|
var templateErr error
|
||||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
if info == nil || info.IsDir() {
|
if info == nil || info.IsDir() {
|
||||||
|
@ -181,9 +183,6 @@ func (s *HandlebarsEngine) loadAssets() error {
|
||||||
}
|
}
|
||||||
var templateErr error
|
var templateErr error
|
||||||
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
names := namesFn()
|
names := namesFn()
|
||||||
for _, path := range names {
|
for _, path := range names {
|
||||||
if !strings.HasPrefix(path, virtualDirectory) {
|
if !strings.HasPrefix(path, virtualDirectory) {
|
||||||
|
@ -219,15 +218,12 @@ func (s *HandlebarsEngine) loadAssets() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HandlebarsEngine) fromCache(relativeName string) *raymond.Template {
|
func (s *HandlebarsEngine) fromCache(relativeName string) *raymond.Template {
|
||||||
s.mu.Lock()
|
|
||||||
tmpl, ok := s.templateCache[relativeName]
|
tmpl, ok := s.templateCache[relativeName]
|
||||||
if ok {
|
if !ok {
|
||||||
s.mu.Unlock()
|
|
||||||
return tmpl
|
|
||||||
}
|
|
||||||
s.mu.Unlock()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return tmpl
|
||||||
|
}
|
||||||
|
|
||||||
func (s *HandlebarsEngine) executeTemplateBuf(name string, binding interface{}) (string, error) {
|
func (s *HandlebarsEngine) executeTemplateBuf(name string, binding interface{}) (string, error) {
|
||||||
if tmpl := s.fromCache(name); tmpl != nil {
|
if tmpl := s.fromCache(name); tmpl != nil {
|
||||||
|
@ -238,8 +234,12 @@ func (s *HandlebarsEngine) executeTemplateBuf(name string, binding interface{})
|
||||||
|
|
||||||
// ExecuteWriter executes a template and writes its result to the w writer.
|
// ExecuteWriter executes a template and writes its result to the w writer.
|
||||||
func (s *HandlebarsEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
func (s *HandlebarsEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
|
||||||
// reload the templates if reload configuration field is true
|
// re-parse the templates if reload is enabled.
|
||||||
if s.reload {
|
if s.reload {
|
||||||
|
// locks to fix #872, it's the simplest solution and the most correct,
|
||||||
|
// to execute writers with "wait list", one at a time.
|
||||||
|
s.rmu.Lock()
|
||||||
|
defer s.rmu.Unlock()
|
||||||
if err := s.Load(); err != nil {
|
if err := s.Load(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
36
view/html.go
36
view/html.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -20,7 +21,7 @@ type (
|
||||||
extension string
|
extension string
|
||||||
assetFn func(name string) ([]byte, error) // for embedded, in combination with directory & extension
|
assetFn func(name string) ([]byte, error) // for embedded, in combination with directory & extension
|
||||||
namesFn func() []string // for embedded, in combination with directory & extension
|
namesFn func() []string // for embedded, in combination with directory & extension
|
||||||
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
|
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded, each ExecuteWriter waits to be finished before writing to a new one.
|
||||||
// parser configuration
|
// parser configuration
|
||||||
options []string // text options
|
options []string // text options
|
||||||
left string
|
left string
|
||||||
|
@ -32,7 +33,6 @@ type (
|
||||||
|
|
||||||
//
|
//
|
||||||
middleware func(name string, contents string) (string, error)
|
middleware func(name string, contents string) (string, error)
|
||||||
mu sync.Mutex // locks for template files loader
|
|
||||||
Templates *template.Template
|
Templates *template.Template
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,10 @@ func (s *HTMLEngine) Binary(assetFn func(name string) ([]byte, error), namesFn f
|
||||||
// Reload if setted to true the templates are reloading on each render,
|
// Reload if setted to true the templates are reloading on each render,
|
||||||
// use it when you're in development and you're boring of restarting
|
// use it when you're in development and you're boring of restarting
|
||||||
// the whole app when you edit a template file.
|
// the whole app when you edit a template file.
|
||||||
|
//
|
||||||
|
// Note that if `true` is passed then only one `View -> ExecuteWriter` will be render each time,
|
||||||
|
// no concurrent access across clients, use it only on development status.
|
||||||
|
// It's good to be used side by side with the https://github.com/kataras/rizla reloader for go source files.
|
||||||
func (s *HTMLEngine) Reload(developmentMode bool) *HTMLEngine {
|
func (s *HTMLEngine) Reload(developmentMode bool) *HTMLEngine {
|
||||||
s.reload = developmentMode
|
s.reload = developmentMode
|
||||||
return s
|
return s
|
||||||
|
@ -118,9 +122,9 @@ func (s *HTMLEngine) Reload(developmentMode bool) *HTMLEngine {
|
||||||
// Execution stops immediately with an error.
|
// Execution stops immediately with an error.
|
||||||
//
|
//
|
||||||
func (s *HTMLEngine) Option(opt ...string) *HTMLEngine {
|
func (s *HTMLEngine) Option(opt ...string) *HTMLEngine {
|
||||||
s.mu.Lock()
|
s.rmu.Lock()
|
||||||
s.options = append(s.options, opt...)
|
s.options = append(s.options, opt...)
|
||||||
s.mu.Unlock()
|
s.rmu.Unlock()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +184,15 @@ func (s *HTMLEngine) AddFunc(funcName string, funcBody interface{}) {
|
||||||
//
|
//
|
||||||
// Returns an error if something bad happens, user is responsible to catch it.
|
// Returns an error if something bad happens, user is responsible to catch it.
|
||||||
func (s *HTMLEngine) Load() error {
|
func (s *HTMLEngine) Load() error {
|
||||||
|
// No need to make this with a complicated and "pro" way, just add lockers to the `ExecuteWriter`.
|
||||||
|
// if `Reload(true)` and add a note for non conc access on dev mode.
|
||||||
|
// atomic.StoreUint32(&s.isLoading, 1)
|
||||||
|
// s.rmu.Lock()
|
||||||
|
// defer func() {
|
||||||
|
// s.rmu.Unlock()
|
||||||
|
// atomic.StoreUint32(&s.isLoading, 0)
|
||||||
|
// }()
|
||||||
|
|
||||||
if s.assetFn != nil && s.namesFn != nil {
|
if s.assetFn != nil && s.namesFn != nil {
|
||||||
// NOT NECESSARY "fix" of https://github.com/kataras/iris/issues/784,
|
// NOT NECESSARY "fix" of https://github.com/kataras/iris/issues/784,
|
||||||
// IT'S BAD CODE WRITTEN WE KEEP HERE ONLY FOR A REMINDER
|
// IT'S BAD CODE WRITTEN WE KEEP HERE ONLY FOR A REMINDER
|
||||||
|
@ -256,10 +269,10 @@ func (s *HTMLEngine) loadDirectory() error {
|
||||||
templateErr = err
|
templateErr = err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
//s.mu.Lock()
|
||||||
// Add our funcmaps.
|
// Add our funcmaps.
|
||||||
_, err = tmpl.Funcs(emptyFuncs).Funcs(s.funcs).Parse(contents)
|
_, err = tmpl.Funcs(emptyFuncs).Funcs(s.funcs).Parse(contents)
|
||||||
s.mu.Unlock()
|
//s.mu.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
templateErr = err
|
templateErr = err
|
||||||
return err
|
return err
|
||||||
|
@ -406,11 +419,10 @@ func (s *HTMLEngine) layoutFuncsFor(name string, binding interface{}) {
|
||||||
return template.HTML(buf.String()), err
|
return template.HTML(buf.String()), err
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.rmu.RLock()
|
|
||||||
for k, v := range s.layoutFuncs {
|
for k, v := range s.layoutFuncs {
|
||||||
funcs[k] = v
|
funcs[k] = v
|
||||||
}
|
}
|
||||||
s.rmu.RUnlock()
|
|
||||||
if tpl := s.Templates.Lookup(name); tpl != nil {
|
if tpl := s.Templates.Lookup(name); tpl != nil {
|
||||||
tpl.Funcs(funcs)
|
tpl.Funcs(funcs)
|
||||||
}
|
}
|
||||||
|
@ -429,10 +441,16 @@ func (s *HTMLEngine) runtimeFuncsFor(name string, binding interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var zero = time.Time{}
|
||||||
|
|
||||||
// ExecuteWriter executes a template and writes its result to the w writer.
|
// ExecuteWriter executes a template and writes its result to the w writer.
|
||||||
func (s *HTMLEngine) ExecuteWriter(w io.Writer, name string, layout string, bindingData interface{}) error {
|
func (s *HTMLEngine) ExecuteWriter(w io.Writer, name string, layout string, bindingData interface{}) error {
|
||||||
// reload the templates if reload configuration field is true
|
// re-parse the templates if reload is enabled.
|
||||||
if s.reload {
|
if s.reload {
|
||||||
|
// locks to fix #872, it's the simplest solution and the most correct,
|
||||||
|
// to execute writers with "wait list", one at a time.
|
||||||
|
s.rmu.Lock()
|
||||||
|
defer s.rmu.Unlock()
|
||||||
if err := s.Load(); err != nil {
|
if err := s.Load(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user