diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index e257b466..27074c84 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,38 +1,23 @@
-If you wanna contribute please submit a PR to one of the [iris-contrib organisation's](https://github.com/iris-contrib) projects.
+## Code Of Conduct
-##### Note that I do not accept pull requests here and that I use the issue tracker for bug reports and proposals only. Please ask questions on the [https://kataras.rocket.chat/channel/iris][Chat] or [http://stackoverflow.com/](http://stackoverflow.com).
+The community should respect and follow our new [Code of Conduct](https://github.com/kataras/iris/blob/master/CODE-OF-CONDUCT.md).
## Before Submitting an Issue
-First, please do a search in [open issues](http://support.iris-go.com) to see if the issue or feature request has already been filed. If there is an issue add your comments to this issue.
+Navigate through [issues](https://github.com/kataras/issues) and check if it has been already filled by other person.
-The Iris project is distributed across multiple repositories, try to file the issue against the correct repository,
-- [Community iris-specific middleware](https://github.com/iris-contrib/middleware/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [App reloader and command line tool](https://github.com/kataras/rizla/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [View Engine](https://github.com/kataras/go-template/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [Sessions](https://github.com/kataras/go-sessions/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [About docs.iris-go.com](https://github.com/iris-contrib/gitbook/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [About examples](https://github.com/iris-contrib/examples/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [Iris main(core)](http://support.iris-go.com)
+Before post a new issue, please do an upgrade:
-Before post a new issue do an iris upgrade:
-
-- Delete `$GOPATH/src/gopkg.in/kataras`
-- Open shell and execute the command: `go get -u gopkg.in/kataras/iris.v6/iris`
+- Delete `$GOPATH/src/github.com/kataras`
+- Open shell and execute the command: `go get -u github.com/kataras/iris`
- Try to re-produce the issue
-- If the issue still exists, then post the issue with the necessary information.
+To be aware of the framework's changes and updates please **[star](https://github.com/kataras/iris/stargazers)** and **[watch](https://github.com/kataras/iris/watchers)** the repository.
-If the issue is after an upgrade, please read the [HISTORY.md](https://github.com/kataras/iris/blob/v6/HISTORY.md) for any breaking-changes and fixes.
-
-The author answers the same day, perhaps the same hour you post the issue.
-
-It is impossible to notify each user on every change, so to be aware of the framework's changes and be notify about updates
-please **star** or **watch** the repository.
-
-If your issue is a closed-personal question then please ask that question on [community chat][Chat].
+Do not discuss things that they're not relative to the framework, keep Github issues useful for newcomers. A Github issue should exists to solve or report a problem.
+> If you want to talk about something else that can't be inside Github issues please [chat](https://gitter.im/iris-go/Lobby) with us.
## Writing Good Bug Reports and Feature Requests
@@ -47,5 +32,3 @@ The more information you can provide, the more likely someone will be successful
* Version of Iris
* Errors in the Terminal/Console
* When you have glide/godep installed, can you reproduce the issue when starting Iris' station without these?
-
-[Chat]: https://kataras.rocket.chat/channel/iris
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 3a7b0f2c..421e4d59 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,6 +1,6 @@
Please answer these questions before submitting your issue. Thanks!
-- [x] I have read the [GopherBOOk](http://gopherbook.iris-go.com), [Examples](https://github.com/iris-contrib/examples), [Contributing File](https://github.com/kataras/iris/blob/v6/.github/CONTRIBUTING.md) and **I'm sure that this issue is not [posted](http://support.iris-go.com)** before.
+- [x] I have read the [_examples](https://github.com/kataras/iris/tree/master/_examples), [Contributing File](https://github.com/kataras/iris/blob/master/.github/CONTRIBUTING.md).
### What version of Go are you using, minimum 1.8 (`go version`)?
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 1a799390..8e9730b3 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,20 +1,6 @@
-This repository follows the official [golang](https://github.com/golang/go#contributing) guidelines for the contributions:
+I'd love to see more contributions!
-##### Note that I do not accept pull requests here and that I use the issue tracker proposals only. Please ask questions on the http://support.iris-go.com or [https://kataras.rocket.chat/channel/iris][chat].
-
-Iris' features are not directly adopted to Iris. A component's feature/change should be tested for some time before being part of the Iris which users install.
-
-Do PRs at the iris' components instead of the core.
-You can find many repositories to help Iris with your contribution. The [iris-contrib](https://github.com/iris-contrib) is open for any
-kind of PR, community is 100% responsible for the whole organisation.
-
-- [Community iris-specific middleware](https://github.com/iris-contrib/middleware/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [App reloader and command line tool](https://github.com/kataras/rizla/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [View Engine](https://github.com/kataras/go-template/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [Sessions](https://github.com/kataras/go-sessions/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [For docs.iris-go.com](https://github.com/iris-contrib/gitbook/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
-- [For examples](https://github.com/iris-contrib/examples/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue)
+If you are interested in contributing to the Iris project, please read and understand the [Code of Conduct](https://github.com/kataras/iris/blob/master/CODE-OF-CONDUCT.md) before submitting your [PR](https://github.com/kataras/iris/pulls).
- **Only one term to future authors**: A contributor should be responsible and answer to the future users' issues that are relative to her/his code. PR's authors must provide adequate support.
-**Users is the most important part, we, as software authors, have to respect them. I don't accept any form of contempt to them(users) by anyone.**
+Don't forget to, first, open an [issue](https://github.com/kataras/iris) to discuss what changes you're willing to push.
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index e2d21c23..28021e0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-.settings
-.project
+# my own configuration for vs code, my lovely editor, if someone of you want this, contact with me
.vscode
-specs
+# turn off these for now
.github
+specs
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 9015ecd4..84d1e298 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,10 @@
language: go
-
+os:
+ - linux
+ - osx
go:
- - go1.8
-
-go_import_path: gopkg.in/kataras/iris.v6
+ - go1.8
+ - tip
+go_import_path: github.com/kataras/iris
+before_install:
+ - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libgtk-3-dev libappindicator3-dev ; fi
\ No newline at end of file
diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md
new file mode 100644
index 00000000..829bdf6a
--- /dev/null
+++ b/CODE-OF-CONDUCT.md
@@ -0,0 +1,41 @@
+# Iris Open Source Code of Conduct
+
+This code of conduct outlines expectations for participation in kataras-managed open source communities, as well as steps for reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all. People violating this code of conduct may be banned from the community.
+
+Our open source communities strive to:
+
+* **Be friendly and patient**: Remember you might not be communicating in someone else's primary spoken or programming language, and others may not have your level of understanding.
+* **Be welcoming**: Our communities welcome and support people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
+* **Be respectful**: We are a world-wide community of professionals, and we conduct ourselves professionally. Disagreement is no excuse for poor behavior and poor manners. Disrespectful and unacceptable behavior includes, but is not limited to:
+ * Violent threats or language.
+ * Discriminatory or derogatory jokes and language.
+ * Posting sexually explicit or violent material.
+ * Posting, or threatening to post, people's personally identifying information ("doxing").
+ * Insults, especially those using discriminatory terms or slurs.
+ * Behavior that could be perceived as sexual attention.
+ * Advocating for or encouraging any of the above behaviors.
+* **Understand disagreements**: Disagreements, both social and technical, are useful learning opportunities. Seek to understand the other viewpoints and resolve differences constructively.
+* This code is not exhaustive or complete. It serves to capture our common understanding of a productive, collaborative environment. We expect the code to be followed in spirit as much as in the letter.
+
+## Scope
+
+This code of conduct applies to all repos and communities for kataras-managed open source projects regardless of whether or not the repo explicitly calls out its use of this code. The code also applies in public spaces when an individual is representing a project or its community. Examples include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+
+## Reporting Code of Conduct Issues
+
+We encourage all communities to resolve issues on their own whenever possible. This builds a broader and deeper understanding and ultimately a healthier interaction. In the event that an issue cannot be resolved locally, please feel free to report your concerns by contacting kataras@tutanota.com.
+
+In your report please include:
+
+* Your contact information.
+* Names (real, usernames or pseudonyms) of any individuals involved. If there are additional witnesses, please include them as well.
+* Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly available record (e.g. a mailing list archive or a public chat log), please include a link or attachment.
+* Any additional information that may be helpful.
+
+
+All reports will be reviewed by [kataras](https://github.com/kataras) and will result in a response that is deemed necessary and appropriate to the circumstances. Where additional perspectives are needed, I may seek insight from others with relevant expertise or experience. The confidentiality of the person reporting the incident will be kept at all times. Involved parties are never part of the review team.
+
+Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in **unacceptable behavior**, the review team may take any action they deem appropriate, **including a permanent ban from the community**.
+
+This code of conduct is based on the [template](http://todogroup.org/opencodeofconduct) established by the [TODO Group](http://todogroup.org/) and used by numerous other large communities (e.g., [Facebook](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct), [Yahoo](https://yahoo.github.io/codeofconduct), [Twitter](https://engineering.twitter.com/opensource/code-of-conduct), [GitHub](http://todogroup.org/opencodeofconduct/#opensource@github.com)) and the Scope section from the [Contributor Covenant version 1.4](http://contributor-covenant.org/version/1/4/).
\ No newline at end of file
diff --git a/DONATIONS.md b/DONATIONS.md
deleted file mode 100644
index 4a037e73..00000000
--- a/DONATIONS.md
+++ /dev/null
@@ -1,66 +0,0 @@
-The main purpose of donations to open source is to say "thank you" to the developer rather than actually advancing the project.
-
-
-Open source projects don’t need the money like those charities do—and so it’s usually phrased like: *Buy the developer a cup of coffee*.
-
-
-
-
-# Buy me a cup of coffee?
-
-Iris is free and open source but developing it has taken thousands of hours of my time and a large part of my sanity. If you feel this web framework useful to you, it would go a great way to ensuring that I can afford to take the time to continue to develop it.
-
-
-I spend all my time in the construction of Iris, therefore I have no income value.
-
-Feel free to send **any** amount through paypal
-
-[![](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kataras2006%40hotmail%2ecom&lc=GR&item_name=Iris%20web%20framework&item_number=iriswebframeworkdonationid2016¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)
-
-
-Some of the benefits are listed here:
-
-- Your github username, after your approval, is visible here as a "premium" community member.
-- Access to the 'donors' [private chat room](https://kataras.rocket.chat/group/donors) gives you real-time assistance by Iris' Author.
-
-## More about your donations
-
-[Juan Sebastián Suárez Valencia](https://github.com/Juanses) donated 20 EUR at September 11
-
-[Bob Lee](https://github.com/li3p) donated 20 EUR at September 16
-
-[Celso Luiz](https://github.com/celsosz) donated 50 EUR at September 29
-
-[Ankur Srivastava](https://github.com/ansrivas) donated 20 EUR at October 2
-
-[Damon Zhao](https://github.com/se77en) donated 20 EUR at October 21
-
-[exponity - consulting & digital transformation](https://github.com/exponity) donated 30 EUR at November 4
-
-[Thomas Fritz](https://github.com/thomasfr) donated 25 EUR at Jenuary 8 of 2017
-
-[Thanos V.](http://mykonosbiennale.com/) donated 20 EUR at Jenuary 16 of 2017
-
-[George Opritescu](https://github.com/International) donated 20 EUR at February 7 of 2017
-
-[Lex Tang](https://github.com/lexrus) donated 20 EUR at February 22 of 2017
-
-[Conrad Steenberg](https://github.com/hengestone) donated 25 EUR at March 23 of 2017
-
-*ANONYMOUS* donated 356 EUR, last anonymous donation at March 22 of 2017
-
-> The names, shown at the [legends](https://github.com/kataras/iris#legends-) list, are sorted by **date** and **NOT by the amount** of the donation.
-
-
-> *ANONYMOUS*: People who donate but don't want to be shown here. *ANONYMOUS* are listed as one group instead of an individual entry, in order to protect their exact date of their donation.
-
-# Thanks for your gratitude and finance help ♡
\ No newline at end of file
diff --git a/Gopkg.lock b/Gopkg.lock
new file mode 100644
index 00000000..b8bf13d5
--- /dev/null
+++ b/Gopkg.lock
@@ -0,0 +1,309 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+ branch = "master"
+ name = "github.com/BurntSushi/toml"
+ packages = ["."]
+ revision = "b26d9c308763d68093482582cea63d69be07a0f0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/Joker/jade"
+ packages = ["."]
+ revision = "35b3f5bdbcc920cd31f4870536dbc63be8530541"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/Unknwon/i18n"
+ packages = ["."]
+ revision = "8372b908b5876d26cfa46a85fc4851b981dad102"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/ajg/form"
+ packages = ["."]
+ revision = "523a5da1a92f01b01f840b61689c0340a0243532"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/aymerick/raymond"
+ packages = [".","ast","lexer","parser"]
+ revision = "72acac2207479d21dd45898c2a4264246c818148"
+
+[[projects]]
+ name = "github.com/davecgh/go-spew"
+ packages = ["spew"]
+ revision = "346938d642f2ec3594ed81d874461961cd0faa76"
+ version = "v1.1.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/eknkc/amber"
+ packages = [".","parser"]
+ revision = "f0d8fdb67f9f4a2c0d02fb6ce4830b8b6754de10"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/esemplastic/unis"
+ packages = [".","logger"]
+ revision = "6e30ed034e8cb31227b24057d030fdd0261bcfc6"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/fatih/structs"
+ packages = ["."]
+ revision = "74a29b9fac7397d933f47e33eba94d2d83a464a2"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/flosch/pongo2"
+ packages = ["."]
+ revision = "1d0f0d3af150c4a65dfd424d742f7374819e7d29"
+
+[[projects]]
+ name = "github.com/garyburd/redigo"
+ packages = ["internal","redis"]
+ revision = "433969511232c397de61b1442f9fd49ec06ae9ba"
+ version = "v1.1.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/gavv/monotime"
+ packages = ["."]
+ revision = "47d58efa69556a936a3c15eb2ed42706d968ab01"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/context"
+ packages = ["."]
+ revision = "624d99b1798d7c5375ea1d3ca4c5b04d58f7c775"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/errors"
+ packages = ["."]
+ revision = "99fa440517e8f3d1e4cd8d6dbed6b41f4c1ed3d6"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/filepersist"
+ packages = ["."]
+ revision = "c5f0cd24e7991579ba6f5f1bd20a1ad2c9f06cd4"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/golog"
+ packages = ["."]
+ revision = "cca714f7feb5df8e455f409b549d384441ac4578"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/hex"
+ packages = ["."]
+ revision = "083fba3033ad473db3dd31c9bb368473d37581a7"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/hidden"
+ packages = ["."]
+ revision = "d52a649ab33af200943bb599898dbdcfdbc94cb7"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/ops"
+ packages = ["."]
+ revision = "b70875f5d689a9438bca72aefd7142a2af889b18"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/stack"
+ packages = ["."]
+ revision = "02f928aad224fbccd50d66edd776fc9d1e9f2f2b"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/getlantern/systray"
+ packages = ["."]
+ revision = "0068f6ae40ea39bfd683043e8452024097fff0e4"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/google/go-querystring"
+ packages = ["query"]
+ revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
+
+[[projects]]
+ name = "github.com/gorilla/websocket"
+ packages = ["."]
+ revision = "3ab3a8b8831546bd18fd182c20687ca853b2bb13"
+ version = "v1.1.0"
+
+[[projects]]
+ name = "github.com/imdario/mergo"
+ packages = ["."]
+ revision = "3e95a51e0639b4cf372f2ccf74c86749d747fbdc"
+ version = "0.2.2"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/imkira/go-interpol"
+ packages = ["."]
+ revision = "5accad8134979a6ac504d456a6c7f1c53da237ca"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/iris-contrib/httpexpect"
+ packages = ["."]
+ revision = "ed44d3c477393b96a598a38730f128dffee33068"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/juju/errors"
+ packages = ["."]
+ revision = "8234c829496aaeae67c5c71235a2cbcc289e960a"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/klauspost/compress"
+ packages = ["flate","gzip"]
+ revision = "f3dce52e0576655d55fd69e74b63da96ad1108f3"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/klauspost/cpuid"
+ packages = ["."]
+ revision = "09cded8978dc9e80714c4d85b0322337b0a1e5e0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/microcosm-cc/bluemonday"
+ packages = ["."]
+ revision = "e79763773ab6222ca1d5a7cbd9d62d83c1f77081"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/monoculum/formam"
+ packages = ["."]
+ revision = "334e05a3c7f95d500715d7c0405937ac933b28cb"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/moul/http2curl"
+ packages = ["."]
+ revision = "4e24498b31dba4683efb9d35c1c8a91e2eda28c8"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/oxtoacart/bpool"
+ packages = ["."]
+ revision = "4e1c5567d7c2dd59fa4c7c83d34c2f3528b025d6"
+
+[[projects]]
+ name = "github.com/pmezard/go-difflib"
+ packages = ["difflib"]
+ revision = "792786c7400a136282c1664665ae0a8db921c6c2"
+ version = "v1.0.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/russross/blackfriday"
+ packages = ["."]
+ revision = "0ba0f2b6ed7c475a92e4df8641825cb7a11d1fa3"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/satori/go.uuid"
+ packages = ["."]
+ revision = "5bf94b69c6b68ee1b541973bb8e1144db23a194b"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/sergi/go-diff"
+ packages = ["diffmatchpatch"]
+ revision = "feef008d51ad2b3778f85d387ccf91735543008d"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/stretchr/testify"
+ packages = ["assert","require"]
+ revision = "f6abca593680b2315d2075e0f5e2a9751e3f431a"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/valyala/bytebufferpool"
+ packages = ["."]
+ revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/xeipuuv/gojsonpointer"
+ packages = ["."]
+ revision = "6fe8760cad3569743d51ddbb243b26f8456742dc"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/xeipuuv/gojsonreference"
+ packages = ["."]
+ revision = "e02fc20de94c78484cd5ffb007f8af96be030a45"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/xeipuuv/gojsonschema"
+ packages = ["."]
+ revision = "0c8571ac0ce161a5feb57375a9cdf148c98c0f70"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/yalp/jsonpath"
+ packages = ["."]
+ revision = "31a79c7593bb93eb10b163650d4a3e6ca190e4dc"
+
+[[projects]]
+ name = "github.com/yudai/gojsondiff"
+ packages = [".","formatter"]
+ revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6"
+ version = "1.0.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/yudai/golcs"
+ packages = ["."]
+ revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/crypto"
+ packages = ["acme","acme/autocert"]
+ revision = "e1a4589e7d3ea14a3352255d04b6f1a418845e5e"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/net"
+ packages = ["html","html/atom","idna","publicsuffix"]
+ revision = "e4fa1c5465ad6111f206fc92186b8c83d64adbe1"
+
+[[projects]]
+ branch = "master"
+ name = "golang.org/x/text"
+ packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
+ revision = "ccbd3f7822129ff389f8ca4858a9b9d4d910531c"
+
+[[projects]]
+ name = "gopkg.in/ini.v1"
+ packages = ["."]
+ revision = "d3de07a94d22b4a0972deb4b96d790c2c0ce8333"
+ version = "v1.28.0"
+
+[[projects]]
+ branch = "v2"
+ name = "gopkg.in/yaml.v2"
+ packages = ["."]
+ revision = "cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b"
+
+[solve-meta]
+ analyzer-name = "dep"
+ analyzer-version = 1
+ inputs-digest = "415eba3367a3b497ce9c74414ba802d5902d5b7fefc7dfc99cff6af102ec40fe"
+ solver-name = "gps-cdcl"
+ solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
new file mode 100644
index 00000000..81361cc8
--- /dev/null
+++ b/Gopkg.toml
@@ -0,0 +1,179 @@
+
+## Gopkg.toml example (these lines may be deleted)
+
+## "metadata" defines metadata about the project that could be used by other independent
+## systems. The metadata defined here will be ignored by dep.
+# [metadata]
+# key1 = "value that convey data to other systems"
+# system1-data = "value that is used by a system"
+# system2-data = "value that is used by another system"
+
+## "required" lists a set of packages (not projects) that must be included in
+## Gopkg.lock. This list is merged with the set of packages imported by the current
+## project. Use it when your project needs a package it doesn't explicitly import -
+## including "main" packages.
+# required = ["github.com/user/thing/cmd/thing"]
+
+## "ignored" lists a set of packages (not projects) that are ignored when
+## dep statically analyzes source code. Ignored packages can be in this project,
+## or in a dependency.
+# ignored = ["github.com/user/project/badpkg"]
+
+## Constraints are rules for how directly imported projects
+## may be incorporated into the depgraph. They are respected by
+## dep whether coming from the Gopkg.toml of the current project or a dependency.
+# [[constraint]]
+## Required: the root import path of the project being constrained.
+# name = "github.com/user/project"
+#
+## Recommended: the version constraint to enforce for the project.
+## Only one of "branch", "version" or "revision" can be specified.
+# version = "1.0.0"
+# branch = "master"
+# revision = "abc123"
+#
+## Optional: an alternate location (URL or import path) for the project's source.
+# source = "https://github.com/myfork/package.git"
+#
+## "metadata" defines metadata about the dependency or override that could be used
+## by other independent systems. The metadata defined here will be ignored by dep.
+# [metadata]
+# key1 = "value that convey data to other systems"
+# system1-data = "value that is used by a system"
+# system2-data = "value that is used by another system"
+
+## Overrides have the same structure as [[constraint]], but supersede all
+## [[constraint]] declarations from all projects. Only [[override]] from
+## the current project's are applied.
+##
+## Overrides are a sledgehammer. Use them only as a last resort.
+# [[override]]
+## Required: the root import path of the project being constrained.
+# name = "github.com/user/project"
+#
+## Optional: specifying a version constraint override will cause all other
+## constraints on this project to be ignored; only the overridden constraint
+## need be satisfied.
+## Again, only one of "branch", "version" or "revision" can be specified.
+# version = "1.0.0"
+# branch = "master"
+# revision = "abc123"
+#
+## Optional: specifying an alternate source location as an override will
+## enforce that the alternate location is used for that project, regardless of
+## what source location any dependent projects specify.
+# source = "https://github.com/myfork/package.git"
+
+
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/BurntSushi/toml"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/Joker/jade"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/Unknwon/i18n"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/aymerick/raymond"
+
+[[constraint]]
+ name = "github.com/davecgh/go-spew"
+ version = "1.1.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/eknkc/amber"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/esemplastic/unis"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/flosch/pongo2"
+
+[[constraint]]
+ name = "github.com/garyburd/redigo"
+ version = "1.1.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/gavv/monotime"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/getlantern/systray"
+
+[[constraint]]
+ name = "github.com/gorilla/websocket"
+ version = "1.1.0"
+
+[[constraint]]
+ name = "github.com/imdario/mergo"
+ version = "0.2.2"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/iris-contrib/httpexpect"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/klauspost/compress"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/microcosm-cc/bluemonday"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/monoculum/formam"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/moul/http2curl"
+
+[[constraint]]
+ name = "github.com/pmezard/go-difflib"
+ version = "1.0.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/russross/blackfriday"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/satori/go.uuid"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/valyala/bytebufferpool"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/xeipuuv/gojsonschema"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/yalp/jsonpath"
+
+[[constraint]]
+ name = "github.com/yudai/gojsondiff"
+ version = "1.0.0"
+
+[[constraint]]
+ branch = "master"
+ name = "golang.org/x/crypto"
+
+[[constraint]]
+ branch = "master"
+ name = "golang.org/x/text"
+
+[[constraint]]
+ branch = "v2"
+ name = "gopkg.in/yaml.v2"
diff --git a/HISTORY.md b/HISTORY.md
index a30b6f4d..51934559 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,1391 +1,122 @@
-# Changelog
+# FAQ
-**How to upgrade**: Open your command-line and execute this command: `go get -u gopkg.in/kataras/iris.v6`.
-
-## Looking for free support?
+### Looking for free support?
http://support.iris-go.com
+ https://kataras.rocket.chat/channel/iris
-## Sa, 03 June 2017
+### Looking for previous versions?
-New version 7 released.
+ https://github.com/kataras/iris#version
-Navigate to the [master](https://github.com/kataras/iris/tree/master) branch for more.
-This version, v6, will work "forever" by-design, it uses the vendor directory feature, so you get truly reproducible builds, as this method guards against upstream renames and delete.
+### Should I upgrade my Iris?
-Developers are not forced to upgrade to the version 7 if they don't really need it.
+Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready.
+> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
+
+**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`.
+For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework).
-## v5 -> v6
-
-Users already notified for some breaking-changes, this section will help you
-to adapt the new changes to your application, it contains an overview of the new features too.
-
-
-- **FIX**: Upgrade the [httpcache](https://github.com/geekypanda/httpcache) vendor. As requested [here](http://support.iris-go.com/d/44-upgrade-httpcache-module).
-
-
-- **View**: Provide an easier method on the community's question about "injecting" additional data outside of the route's main handler which calls the .Render, via middleware.
- - As discussed [above](http://support.iris-go.com/d/27-using-middleware-to-inject-properties-for-templates).
- - Click [here](https://github.com/kataras/iris/tree/v6/_examples/intermediate/view/context-view-data) for an example.
-
-_Update: 18 March 2017_
-
-- **Sessions**: Enchance the community's feature request about custom encode and decode methods for the cookie value(sessionid) as requested [here](http://support.iris-go.com/d/29-mark-cookie-for-session-as-secure).
-
-_Update: 12 March 2017_
-
-- Enhance Custom http errors with gzip and static files handler, as requested/reported [here](http://support.iris-go.com/d/17-fallback-handler-for-non-matched-routes).
-- Enhance per-party custom http errors (now it works on any wildcard path too).
-- Add a third parameter on `app.OnError(...)` for custom http errors with regexp validation, see [status_test.go](https://github.com/kataras/iris/blob/v6/status_test.go) for an example.
-- Add a `context.ParamIntWildcard(...)` to skip the first slash, useful for wildcarded paths' parameters.
-
-- Shutdown with `app.Shutdown(context.Context) error`, no need for any third-parties, with `EventPolicy.Interrupted` and Go's 1.8 Gracefully Shutdown feature you're ready to go!
-- HTTP/2 Go 1.8 `context.Push(target string, opts *http.PushOptions) error` is supported, example can be found [here](https://github.com/kataras/iris/blob/v6/adaptors/websocket/_examples/websocket_secure/main.go)
-
-- Router (two lines to add, new features)
-- Template engines (two lines to add, same features as before, except their easier configuration)
-- Basic middleware, that have been written by me, are transfared to the main repository[/middleware](https://github.com/kataras/iris/tree/v6/middleware) with a lot of improvements to the `recover middleware` (see the next)
-- `func(http.ResponseWriter, r *http.Request, next http.HandlerFunc)` signature is fully compatible using `iris.ToHandler` helper wrapper func, without any need of custom boilerplate code. So all net/http middleware out there are supported, no need to re-invert the world here, search to the internet and you'll find a suitable to your case.
-
-- Load Configuration from an external file, yaml and toml:
-
- - [yaml-based](http://www.yaml.org/) configuration file using the `iris.YAML` function: `app := iris.New(iris.YAML("myconfiguration.yaml"))`
- - [toml-based](https://github.com/toml-lang/toml) configuration file using the `iris.TOML` function: `app := iris.New(iris.TOML("myconfiguration.toml"))`
-
-
-- Add `.Regex` middleware which does path validation using the `regexp` package, i.e `.Regex("param", "[0-9]+$")`. Useful for routers that don't support regex route path validation out-of-the-box.
-
-- Websocket additions: `c.Context() *iris.Context`, `ws.GetConnectionsByRoom("room name") []websocket.Connection`, `c.OnLeave(func(roomName string){})`,
-```go
- // SetValue sets a key-value pair on the connection's mem store.
- c.SetValue(key string, value interface{})
- // GetValue gets a value by its key from the connection's mem store.
- c.GetValue(key string) interface{}
- // GetValueArrString gets a value as []string by its key from the connection's mem store.
- c.GetValueArrString(key string) []string
- // GetValueString gets a value as string by its key from the connection's mem store.
- c.GetValueString(key string) string
- // GetValueInt gets a value as integer by its key from the connection's mem store.
- c.GetValueInt(key string) int
-
-```
-[examples here](https://github.com/kataras/iris/blob/v6/adaptors/websocket/_examples).
-
-Fixes:
-
-- Websocket improvements and fix errors when using custom golang client
-- Sessions performance improvements
-- Fix cors by using `rs/cors` and add a new adaptor to be able to wrap the entire router
-- Fix and improve oauth/oauth2 plugin(now adaptor)
-- Improve and fix recover middleware
-- Fix typescript compiler and hot-reloader plugin(now adaptor)
-- Fix and improve the cloud-editor `alm/alm-tools` plugin(now adaptor)
-- Fix gorillamux serve static files (custom routers are supported with a workaround, not a complete solution as they are now)
-- Fix `iris run main.go` app reload while user saved the file from gogland
-- Fix [StaticEmbedded doesn't works on root "/"](https://github.com/kataras/iris/issues/633)
-
-Changes:
-
-- `context.TemplateString` replaced with `app.Render(w io.Writer, name string, bind interface{}, options ...map[string]interface{}) error)` which gives you more functionality.
-
-```go
-import "bytes"
-// ....
-app := iris.New()
-// ....
-
-buff := &bytes.Buffer{}
-app.Render(buff, "my_template.html", nil)
-// buff.String() is the template parser's result, use that string to send a rich-text e-mail based on a template.
-```
-
-```go
-// you can take the app(*Framework instance) via *Context.Framework() too:
-
-app.Get("/send_mail", func(ctx *iris.Context){
- buff := &bytes.Buffer{}
- ctx.Framework().Render(buff, "my_template.html", nil)
- // ...
-})
-
-```
-- `.Close() error` replaced with gracefully `.Shutdown(context.Context) error`
-- Remove all the package-level functions and variables for a default `*iris.Framework, iris.Default`
-- Remove `.API`, use `iris.Handle/.HandleFunc/.Get/.Post/.Put/.Delete/.Trace/.Options/.Use/.UseFunc/.UseGlobal/.Party/` instead
-- Remove `.Logger`, `.Config.IsDevelopment`, `.Config.LoggerOut`, `.Config.LoggerPrefix` you can adapt a logger which will log to each log message mode by `app.Adapt(iris.DevLogger())` or adapt a new one, it's just a `func(mode iris.LogMode, message string)`.
-- Remove `.Config.DisableTemplateEngines`, are disabled by-default, you have to `.Adapt` a view engine by yourself
-- Remove `context.RenderTemplateSource` you should make a new template file and use the `iris.Render` to specify an `io.Writer` like `bytes.Buffer`
-- Remove `plugins`, replaced with more pluggable echosystem that I designed from zero on this release, named `Policy` [Adaptors](https://github.com/kataras/iris/tree/v6/adaptors) (all plugins have been converted, fixed and improvement, except the iriscontrol).
-- `context.Log(string,...interface{})` -> `context.Log(iris.LogMode, string)`
-- Remove `.Config.DisableBanner`, now it's controlled by `app.Adapt(iris.LoggerPolicy(func(mode iris.LogMode, msg string)))`
-- Remove `.Config.Websocket` , replaced with the `kataras/iris/adaptors/websocket.Config` adaptor.
-
-- https://github.com/iris-contrib/plugin -> https://github.com/iris-contrib/adaptors
-
-- `import "github.com/iris-contrib/middleware/basicauth"` -> `import "gopkg.in/kataras/iris.v6/middleware/basicauth"`
-- `import "github.com/iris-contrib/middleware/i18n"` -> `import "gopkg.in/kataras/iris.v6/middleware/i18n"`
-- `import "github.com/iris-contrib/middleware/logger"` -> `import "gopkg.in/kataras/iris.v6/middleware/logger"`
-- `import "github.com/iris-contrib/middleware/recovery"` -> `import "gopkg.in/kataras/iris.v6/middleware/recover"`
-
-
-- `import "github.com/iris-contrib/plugin/typescript"` -> `import "gopkg.in/kataras/iris.v6/adaptors/typescript"`
-- `import "github.com/iris-contrib/plugin/editor"` -> `import "gopkg.in/kataras/iris.v6/adaptors/typescript/editor"`
-- `import "github.com/iris-contrib/plugin/cors"` -> `import "gopkg.in/kataras/iris.v6/adaptors/cors"`
-- `import "github.com/iris-contrib/plugin/gorillamux"` -> `import "gopkg.in/kataras/iris.v6/adaptors/gorillamux"`
-- `import github.com/iris-contrib/plugin/oauth"` -> `import "github.com/iris-contrib/adaptors/oauth"`
-
-
-- `import "github.com/kataras/go-template/html"` -> `import "gopkg.in/kataras/iris.v6/adaptors/view"`
-- `import "github.com/kataras/go-template/django"` -> `import "gopkg.in/kataras/iris.v6/adaptors/view"`
-- `import "github.com/kataras/go-template/pug"` -> `import "gopkg.in/kataras/iris.v6/adaptors/view"`
-- `import "github.com/kataras/go-template/handlebars"` -> `import "gopkg.in/kataras/iris.v6/adaptors/view"`
-- `import "github.com/kataras/go-template/amber"` -> `import "gopkg.in/kataras/iris.v6/adaptors/view"`
-
-**Read more below** for the lines you have to change. Package-level removal is critical, you will have build-time errors. Router(less) is MUST, otherwise your app will fatal with a detailed error message.
-
-> If I missed something please [chat](https://kataras.rocket.chat/channel/iris).
-
-
-### Router(less)
-
-**Iris server does not contain a default router anymore**, yes your eyes are ok.
-
-This decision came up because of your requests of using other routers than the iris' defaulted.
-At the past I gave you many workarounds, but they are just workarounds, not a complete solution.
-
-**Don't worry:**
-
-- you have to add only two lines, one is the `import path` and another is the `.Adapt`, after the `iris.New()`, so it can be tolerated.
-- you are able to use all iris' features as you used before, **the API for routing has not been changed**.
-
-Two routers available to use, today:
-
-
-- [httprouter](https://github.com/kataras/iris/tree/v6/adaptors/httprouter), the old defaulted. A router that can be adapted, it's a custom version of https://github.comjulienschmidt/httprouter which is edited to support iris' subdomains, reverse routing, custom http errors and a lot features, it should be a bit faster than the original too because of iris' Context. It uses `/mypath/:firstParameter/path/:secondParameter` and `/mypath/*wildcardParamName` .
-
-
-Example:
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter" // <---- NEW
-)
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger())
- app.Adapt(httprouter.New()) // <---- NEW
-
-
- app.OnError(iris.StatusNotFound, func(ctx *iris.Context){
- ctx.HTML(iris.StatusNotFound, "
custom http error page
")
- })
-
-
- app.Get("/healthcheck", h)
-
- gamesMiddleware := func(ctx *iris.Context) {
- println(ctx.Method() + ": " + ctx.Path())
- ctx.Next()
- }
-
- games:= app.Party("/games", gamesMiddleware)
- { // braces are optional of course, it's just a style of code
- games.Get("/:gameID/clans", h)
- games.Get("/:gameID/clans/clan/:publicID", h)
- games.Get("/:gameID/clans/search", h)
-
- games.Put("/:gameID/players/:publicID", h)
- games.Put("/:gameID/clans/clan/:publicID", h)
-
- games.Post("/:gameID/clans", h)
- games.Post("/:gameID/players", h)
- games.Post("/:gameID/clans/:publicID/leave", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/application", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/application/:action", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/invitation", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/invitation/:action", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/delete", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/promote", h)
- games.Post("/:gameID/clans/:clanPublicID/memberships/demote", h)
- }
-
- app.Get("/anything/*anythingparameter", func(ctx *iris.Context){
- s := ctx.Param("anythingparameter")
- ctx.Writef("The path after /anything is: %s",s)
- })
-
- app.Listen(":80")
-
- /*
- gameID = 1
- publicID = 2
- clanPublicID = 22
- action = 3
-
- GET
- http://localhost/healthcheck
- http://localhost/games/1/clans
- http://localhost/games/1/clans/clan/2
- http://localhost/games/1/clans/search
-
- PUT
- http://localhost/games/1/players/2
- http://localhost/games/1/clans/clan/2
-
- POST
- http://localhost/games/1/clans
- http://localhost/games/1/players
- http://localhost/games/1/clans/2/leave
- http://localhost/games/1/clans/22/memberships/application -> 494
- http://localhost/games/1/clans/22/memberships/application/3- > 404
- http://localhost/games/1/clans/22/memberships/invitation
- http://localhost/games/1/clans/22/memberships/invitation/3
- http://localhost/games/1/clans/2/memberships/delete
- http://localhost/games/1/clans/22/memberships/promote
- http://localhost/games/1/clans/22/memberships/demote
-
- */
-}
-
-func h(ctx *iris.Context) {
- ctx.HTML(iris.StatusOK, "Path"+ctx.Path())
-}
-
-```
-
-- [gorillamux](https://github.com/kataras/iris/tree/v6/adaptors/gorillamux), a router that can be adapted, it's the https://github.com/gorilla/mux which supports subdomains, custom http errors, reverse routing, pattern matching via regex and the rest of the iris' features.
-
-
-Example:
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/gorillamux" // <---- NEW
-)
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger())
- app.Adapt(gorillamux.New()) // <---- NEW
-
-
- app.OnError(iris.StatusNotFound, func(ctx *iris.Context){
- ctx.HTML(iris.StatusNotFound, " custom http error page
")
- })
-
-
- app.Get("/healthcheck", h)
-
- gamesMiddleware := func(ctx *iris.Context) {
- println(ctx.Method() + ": " + ctx.Path())
- ctx.Next()
- }
-
- games:= app.Party("/games", gamesMiddleware)
- { // braces are optional of course, it's just a style of code
- games.Get("/{gameID:[0-9]+}/clans", h)
- games.Get("/{gameID:[0-9]+}/clans/clan/{publicID:[0-9]+}", h)
- games.Get("/{gameID:[0-9]+}/clans/search", h)
-
- games.Put("/{gameID:[0-9]+}/players/{publicID:[0-9]+}", h)
- games.Put("/{gameID:[0-9]+}/clans/clan/{publicID:[0-9]+}", h)
-
- games.Post("/{gameID:[0-9]+}/clans", h)
- games.Post("/{gameID:[0-9]+}/players", h)
- games.Post("/{gameID:[0-9]+}/clans/{publicID:[0-9]+}/leave", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/application", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/application/:action", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/invitation", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/invitation/:action", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/delete", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/promote", h)
- games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/demote", h)
- }
-
- app.Get("/anything/{anythingparameter:.*}", func(ctx *iris.Context){
- s := ctx.Param("anythingparameter")
- ctx.Writef("The path after /anything is: %s",s)
- })
-
- app.Listen(":80")
-
- /*
- gameID = 1
- publicID = 2
- clanPublicID = 22
- action = 3
-
- GET
- http://localhost/healthcheck
- http://localhost/games/1/clans
- http://localhost/games/1/clans/clan/2
- http://localhost/games/1/clans/search
-
- PUT
- http://localhost/games/1/players/2
- http://localhost/games/1/clans/clan/2
-
- POST
- http://localhost/games/1/clans
- http://localhost/games/1/players
- http://localhost/games/1/clans/2/leave
- http://localhost/games/1/clans/22/memberships/application -> 494
- http://localhost/games/1/clans/22/memberships/application/3- > 404
- http://localhost/games/1/clans/22/memberships/invitation
- http://localhost/games/1/clans/22/memberships/invitation/3
- http://localhost/games/1/clans/2/memberships/delete
- http://localhost/games/1/clans/22/memberships/promote
- http://localhost/games/1/clans/22/memberships/demote
-
- */
-}
-
-func h(ctx *iris.Context) {
- ctx.HTML(iris.StatusOK, "Path"+ctx.Path())
-}
-
-```
-
-**No changes whatever router you use**, only the `path` is changed(otherwise it doesn't make sense to support more than one router).
-At the `gorillamux`'s path example we get pattern matching using regexp, at the other hand `httprouter` doesn't provides path validations
-but it provides parameter and wildcard parameters too, it's also a lot faster than gorillamux.
-
-Original Gorilla Mux made my life easier when I had to adapt the reverse routing and subdomains features, it has got these features by its own too, so it was easy.
-
-Original Httprouter doesn't supports subdomains, multiple paths on different methods, reverse routing, custom http errors, I had to implement
-all of them by myself and after adapt them using the policies, it was a bit painful but this is my job. Result: It runs blazy-fast!
-
-
-As we said, all iris' features works as before even if you are able to adapt any custom router. Template funcs that were relative-closed to reverse router, like `{{ url }} and {{ urlpath }}`, works as before too, no change for your app's side need.
-
-
-> I would love to see more routers (as more as they can provide different `path declaration` features) from the community, create an adaptor for an iris' router and I will share your repository to the rest of the users!
-
-
-Adaptors are located [there](https://github.com/kataras/iris/tree/v6/adaptors).
-
-### View engine (5 template engine adaptors)
-
-At the past, If no template engine was used then iris selected the [html standard](https://github.com/kataras/go-template/tree/master/html).
-
-**Now, iris doesn't defaults any template engine** (also the `.Config.DisableTemplateEngines` has been removed, it has no use anymore).
-
-So, again you have to do two changes, the `import path` and the `.Adapt`.
-
-**Template files are no need to change, the template engines does the same exactly things as before**
-
-
-All of these **five template engines** have common features with common API, like Layout, Template Funcs, Party-specific layout, partial rendering and more.
- - **the standard html**, based on [go-template/html](https://github.com/kataras/go-template/tree/master/html), its template parser is the [html/template](https://golang.org/pkg/html/template/).
-
- - **django**, based on [go-template/django](https://github.com/kataras/go-template/tree/master/django), its template parser is the [pongo2](https://github.com/flosch/pongo2)
-
- - **pug**, based on [go-template/pug](https://github.com/kataras/go-template/tree/master/pug), its template parser is the [jade](https://github.com/Joker/jade)
-
- - **handlebars**, based on [go-template/handlebars](https://github.com/kataras/go-template/tree/master/handlebars), its template parser is the [raymond](https://github.com/aymerick/raymond)
-
- - **amber**, based on [go-template/amber](https://github.com/kataras/go-template/tree/master/amber), its template parser is the [amber](https://github.com/eknkc/amber).
-
-Each of the template engines has different options, view adaptors are located [here](https://github.com/kataras/iris/tree/v6/adaptors/view).
-
-
-Example:
-
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/gorillamux" // <--- NEW (previous section)
- "gopkg.in/kataras/iris.v6/adaptors/view" // <--- NEW it contains all the template engines
-)
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger())
- app.Adapt(gorillamux.New()) // <--- NEW (previous section)
-
- // - standard html | view.HTML(...)
- // - django | view.Django(...)
- // - pug(jade) | view.Pug(...)
- // - handlebars | view.Handlebars(...)
- // - amber | view.Amber(...)
- app.Adapt(view.HTML("./templates", ".html").Reload(true)) // <---- NEW (set .Reload to true when you're in dev mode.)
-
- // default template funcs:
- //
- // - {{ url "mynamedroute" "pathParameter_ifneeded"} }
- // - {{ urlpath "mynamedroute" "pathParameter_ifneeded" }}
- // - {{ render "header.html" }}
- // - {{ render_r "header.html" }} // partial relative path to current page
- // - {{ yield }}
- // - {{ current }}
- //
- // to adapt custom funcs, use:
- app.Adapt(iris.TemplateFuncsPolicy{"myfunc": func(s string) string {
- return "hi "+s
- }}) // usage inside template: {{ hi "kataras"}}
-
- app.Get("/hi", func(ctx *iris.Context) {
- ctx.MustRender(
- "hi.html", // the file name of the template relative to the './templates'
- iris.Map{"Name": "Iris"}, // the .Name inside the ./templates/hi.html
- iris.Map{"gzip": false}, // enable gzip for big files
- )
-
- })
-
- // http://127.0.0.1:8080/hi
- app.Listen(":8080")
-}
-
-
-```
-
-`.UseTemplate` have been removed and replaced with the `.Adapt` which is using `iris.RenderPolicy` and `iris.TemplateFuncsPolicy`
-to adapt the behavior of the custom template engines.
-
-**BEFORE**
-```go
-import "github.com/kataras/go-template/django"
-// ...
-app := iris.New()
-app.UseTemplate(django.New()).Directory("./templates", ".html")/*.Binary(...)*/)
-```
-
-**AFTER**
-```go
-import ""gopkg.in/kataras/iris.v6/adaptors/view"
-// ...
-app := iris.New()
-app.Adapt(view.Django("./templates",".htmll")/*.Binary(...)*/)
-```
-
-The rest remains the same. Don't forget the real changes were `only import path and .Adapt(imported)`, at general when you see an 'adaptor' these two declarations should happen to your code.
-
-
-
-### Package-level functions and variables for `iris.Default` have been removed.
-
-The form of variable use for an Iris *Framework remains as it was:
-```go
-app := iris.New()
-app.$FUNCTION/$VARIABLE
-```
-
-
-> When I refer to `iris.$FUNCTION/$VARIABLE` it means `iris.Handle/.HandleFunc/.Get/.Post/.Put/.Delete/.Trace/.Options/.Use/.UseFunc/.UseGlobal/.Party/.Set/.Config`
-and the rest of the package-level functions referred to the `iris.Default` variable.
-
-**BEFORE**
-
-```go
-iris.Config.FireMethodNotAllowed = true
-iris.Set(OptionDisableBodyConsumptionOnUnmarshal(true))
-```
-
-```go
-iris.Get("/", func(ctx *iris.Context){
-
-})
-
-iris.ListenLETSENCRYPT(":8080")
-```
-
-**AFTER**
-
-
-```go
-app := iris.New()
-app.Config.FireMethodNotAllowed = true
-// or iris.Default.Config.FireMethodNotAllowed = true and so on
-app.Set(OptionDisableBodyConsumptionOnUnmarshal(true))
-// same as
-// app := iris.New(iris.Configuration{FireMethodNotAllowed:true, DisableBodyConsumptionOnUnmarshal:true})
-```
-
-```go
-app := iris.New()
-app.Get("/", func(ctx *iris.Context){
-
-})
-
-app.ListenLETSENCRYPT(":8080")
-```
-
-For those who had splitted the application in different packages they could do just that `iris.$FUNCTION/$VARIABLE` without the need
-of import a singleton package which would initialize a new `App := iris.New()`.
-
-`Iris.Default` remains, so you can refer to that if you don't want to initialize a new `App := iris.New()` by your own.
-
-**BEFORE**
-
-```go
-package controllers
-import "github.com/kataras/iris"
-func init(){
- iris.Get("/", func(ctx *iris.Context){
-
- })
-}
-```
-
-```go
-package main
-
-import (
- "github.com/kataras/iris"
- _ "github.com/mypackage/controllers"
-)
-
-func main(){
- iris.Listen(":8080")
-}
-```
-
-
-**AFTER**
-
-```go
-package controllers
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-func init(){
- iris.Default.Adapt(httprouter.New())
- iris.Default.Get("/", func(ctx *iris.Context){
-
- })
-}
-```
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- _ "github.com/mypackage/controllers"
-)
-
-func main(){
- iris.Default.Listen(":8080")
-}
-```
-
-You got the point, let's continue to the next conversion.
-
-### Remove the slow .API | iris.API(...) / app := iris.New(); app.API(...)
-
-
-The deprecated `.API` has been removed entirely, it should be removed after v5(look on the v5 history tag).
-
-At first I created that func in order to give newcovers a chance to be able to quick start a new `controller-like`
-with one function, but that function was using generics at runtime and it was very slow compared to the
-`iris.Handle/.HandleFunc/.Get/.Post/.Put/.Delete/.Trace/.Options/.Use/.UseFunc/.UseGlobal/.Party`.
-
-Also some users they used only `.API`, they didn't bother to 'learn' about the standard rest api functions
-and their power(including per-route middleware, cors, recover and so on). So we had many unrelational questions about the `.API` func.
-
-
-**BEFORE**
-
-```go
-package main
-
-import (
- "github.com/kataras/iris"
-)
-
-type UserAPI struct {
- *iris.Context
-}
-
-// GET /users
-func (u UserAPI) Get() {
- u.Writef("Get from /users")
- // u.JSON(iris.StatusOK,myDb.AllUsers())
-}
-
-// GET /users/:param1 which its value passed to the id argument
-func (u UserAPI) GetBy(id string) { // id equals to u.Param("param1")
- u.Writef("Get from /users/%s", id)
- // u.JSON(iris.StatusOK, myDb.GetUserById(id))
-
-}
-
-// POST /users
-func (u UserAPI) Post() {
- name := u.FormValue("name")
- // myDb.InsertUser(...)
- println(string(name))
- println("Post from /users")
-}
-
-// PUT /users/:param1
-func (u UserAPI) PutBy(id string) {
- name := u.FormValue("name") // you can still use the whole Context's features!
- // myDb.UpdateUser(...)
- println(string(name))
- println("Put from /users/" + id)
-}
-
-// DELETE /users/:param1
-func (u UserAPI) DeleteBy(id string) {
- // myDb.DeleteUser(id)
- println("Delete from /" + id)
-}
-
-func main() {
-
- iris.API("/users", UserAPI{})
- iris.Listen(":8080")
-}
-
-```
-
-
-**AFTER**
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/gorillamux"
-)
-
-func GetAllUsersHandler(ctx *iris.Context) {
- ctx.Writef("Get from /users")
- // ctx.JSON(iris.StatusOK,myDb.AllUsers())
-}
-
-func GetUserByIdHandler(ctx *iris.Context) {
- ctx.Writef("Get from /users/%s",
- ctx.Param("id")) // or id, err := ctx.ParamInt("id")
- // ctx.JSON(iris.StatusOK, myDb.GetUserById(id))
-}
-
-func InsertUserHandler(ctx *iris.Context){
- name := ctx.FormValue("name")
- // myDb.InsertUser(...)
- println(string(name))
- println("Post from /users")
-}
-
-func UpdateUserHandler(ctx *iris.Context) {
- name := ctx.FormValue("name")
- // myDb.UpdateUser(...)
- println(string(name))
- println("Put from /users/" + ctx.Param("id"))
-}
-
-func DeleteUserById(id string) {
- // myDb.DeleteUser(id)
- println("Delete from /" + ctx.param("id"))
-}
-
-func main() {
- app := iris.New()
- app.Adapt(gorillamux.New())
-
- // create a new router targeted for "/users" path prefix
- // you can learn more about Parties on the examples and book too
- // they can share middleware, template layout and more.
- userRoutes := app.Party("users")
-
- // GET http://localhost:8080/users/ and /users
- userRoutes.Get("/", GetAllUsersHandler)
-
- // GET http://localhost:8080/users/:id
- userRoutes.Get("/:id", GetUserByIdHandler)
- // POST http://localhost:8080/users
- userRoutes.Post("/", InsertUserHandler)
-
- // PUT http://localhost:8080/users/:id
- userRoutes.Put("/:id", UpdateUserHandler)
-
- // DELETE http://localhost:8080/users/:id
- userRoutes.Delete("/:id", DeleteUserById)
-
- app.Listen(":8080")
-}
-
-```
-
-### Old Plugins and the new `.Adapt` Policies
-
-A lot of changes to old -so-called Plugins and many features have been adopted to this new ecosystem.
-
-
-First of all plugins renamed to `policies with adaptors which, adaptors, adapts the policies to the framework`
-(it is not just a simple rename of the word, it's a new concept).
-
-
-Policies are declared inside Framework, they are implemented outside of the Framework and they are adapted to Framework by a user call.
-
-Policy adaptors are just like a plugins but they have to implement a specific action/behavior to a specific policy type(or more than one at the time).
-
-The old plugins are fired 'when something happens do that' (ex: PreBuild,PostBuild,PreListen and so on) this behavior is the new `EventPolicy`
-which has **4 main flow events** with their callbacks been wrapped, so you can use more than EventPolicy (most of the policies works this way).
-
-```go
-type (
- // EventListener is the signature for type of func(*Framework),
- // which is used to register events inside an EventPolicy.
- //
- // Keep note that, inside the policy this is a wrapper
- // in order to register more than one listener without the need of slice.
- EventListener func(*Framework)
-
- // EventPolicy contains the available Framework's flow event callbacks.
- // Available events:
- // - Boot
- // - Build
- // - Interrupted
- // - Recovery
- EventPolicy struct {
- // Boot with a listener type of EventListener.
- // Fires when '.Boot' is called (by .Serve functions or manually),
- // before the Build of the components and the Listen,
- // after VHost and VSCheme configuration has been setted.
- Boot EventListener
- // Before Listen, after Boot
- Build EventListener
- // Interrupted with a listener type of EventListener.
- // Fires after the terminal is interrupted manually by Ctrl/Cmd + C
- // which should be used to release external resources.
- // Iris will close and os.Exit at the end of custom interrupted events.
- // If you want to prevent the default behavior just block on the custom Interrupted event.
- Interrupted EventListener
- // Recovery with a listener type of func(*Framework,error).
- // Fires when an unexpected error(panic) is happening at runtime,
- // while the server's net.Listener accepting requests
- // or when a '.Must' call contains a filled error.
- // Used to release external resources and '.Close' the server.
- // Only one type of this callback is allowed.
- //
- // If not empty then the Framework will skip its internal
- // server's '.Close' and panic to its '.Logger' and execute that callback instaed.
- // Differences from Interrupted:
- // 1. Fires on unexpected errors
- // 2. Only one listener is allowed.
- Recovery func(*Framework, error)
- }
-)
-```
-
-**A quick overview on how they can be adapted** to an iris *Framework (iris.New()'s result).
-Let's adapt `EventPolicy`:
-
-```go
-app := iris.New()
-
-evts := iris.EventPolicy{
- // we ommit the *Framework's variable name because we have already the 'app'
- // if we were on different file with no access to the 'app' then the varialbe name will be useful.
- Boot: func(*Framework){
- app.Log("Here you can change any field and configuration for iris before being used
- also you can adapt more policies that should be used to the next step which is the Build and Listen,
- only the app.Config.VHost and app.Config.VScheme have been setted here, but you can change them too\n")
- },
- Build: func(*Framework){
- app.Log("Here all configuration and all app' fields and features have been builded, here you are ready to call
- anything (you shouldn't change fields and configuration here)\n")
- },
-}
-// Adapt the EventPolicy 'evts' to the Framework
-app.Adapt(evts)
-
-// let's register one more
-app.Adapt(iris.EventPolicy{
- Boot: func(*Framework){
- app.Log("the second log message from .Boot!\n")
-}})
-
-// you can also adapt multiple and different(or same) types of policies in the same call
-// using: app.Adapt(iris.EventPolicy{...}, iris.LoggerPolicy(...), iris.RouterWrapperPolicy(...))
-
-// starts the server, executes the Boot -> Build...
-app.Adapt(httprouter.New()) // read below for this line
-app.Listen(":8080")
-```
-
-
-
-This pattern allows us to be very pluggable and add features that the *Framework itself doesn't knows,
-it knows only the main policies which implement but their features are our(as users) business.
-
-
-We have 8 policies, so far, and some of them have 'subpolicies' (the RouterReversionPolicy for example).
-
-- LoggerPolicy
-- EventPolicy
- - Boot
- - Build
- - Interrupted
- - Recover
-- RouterReversionPolicy
- - StaticPath
- - WildcardPath
- - Param
- - URLPath
-- RouterBuilderPolicy
-- RouterWrapperPolicy
-- RenderPolicy
-- TemplateFuncsPolicy
-- SessionsPolicy
-
-
-**Details** of these can be found at [policy.go](https://github.com/kataras/iris/blob/v6/policy.go).
-
-The **Community**'s adaptors are [here](https://github.com/iris-contrib/adaptors).
-
-**Iris' Built'n Adaptors** for these policies can be found at [/adaptors folder](https://github.com/kataras/iris/tree/v6/adaptors).
-
-The folder contains:
-
-- cors, a cors (router) wrapper based on `rs/cors`.
-It's a `RouterWrapperPolicy`
-
-- gorillamux, a router that can be adapted, it's the `gorilla/mux` which supports subdomains, custom http errors, reverse routing, pattern matching.
-It's a compination of`EventPolicy`, `RouterReversionPolicy with StaticPath, WildcardPath, URLPath, RouteContextLinker` and the `RouterBuilderPolicy`.
-
-- httprouter, a router that can be adapted, it's a custom version of `julienschmidt/httprouter` which is edited to support iris' subdomains, reverse routing, custom http errors and a lot features, it should be a bit faster than the original too.
-It's a compination of`EventPolicy`, `RouterReversionPolicy with StaticPath, WildcardPath, URLPath, RouteContextLinker` and the `RouterBuilderPolicy`.
-
-
-- typescript and cloud editor, contains the typescript compiler with hot reload feature and a typescript cloud editor ([alm-tools](https://github.com/alm-tools/alm)), it's an `EventPolicy`
-
-- view, contains 5 template engines based on the `kataras/go-template`.
-All of these have common features with common API, like Layout, Template Funcs, Party-specific layout, partial rendering and more.
-It's a `RenderPolicy` with a compinaton of `EventPolicy` and use of `TemplateFuncsPolicy`.
- - the standard html
- - pug(jade)
- - django(pongo2)
- - handlebars
- - amber.
-
-
-
-
-
-#### Note
-Go v1.8 introduced a new plugin system with `.so` files, users should not be confused with old iris' plugins and new adaptors.
-It is not ready for all operating systems(yet) when it will be ready, Iris will take leverage of this Golang's feature.
-
-
-### http.Handler and third-party middleware
-
-We were compatible before this version but if a third-party middleware had the form of:
-`func(http.ResponseWriter, *http.Request, http.HandlerFunc)`you were responsible of make a wrapper
-which would return an `iris.Handler/HandlerFunc`.
-
-Now you're able to pass an `func(http.ResponseWriter, *http.Request, http.HandlerFunc)` third-party net/http middleware(Chain-of-responsibility pattern) using the `iris.ToHandler` wrapper func without any other custom boilerplate.
-
-Example:
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/gorillamux"
- "github.com/rs/cors"
-)
-
-// myCors returns a new cors middleware
-// with the provided options.
-myCors := func(opts cors.Options) iris.HandlerFunc {
- handlerWithNext := cors.New(opts).ServeHTTP
- return iris.ToHandler(handlerWithNext)
-}
-
-func main(){
- app := iris.New()
- app.Adapt(httprouter.New())
-
- app.Post("/user", myCors(cors.Options{}), func(ctx *iris.Context){
- // ....
- })
-
- app.Listen(":8080")
-}
-
-```
-
-- Irrelative info but this is the best place to put it: `iris/app.AcquireCtx/.ReleaseCtx` replaced to: `app.Context.Acquire/.Release/.Run`.
-
-
-
-### iris cmd
-
-- FIX: [iris run main.go](https://github.com/kataras/iris/tree/v6/iris#run) not reloading when file changes maden by some of the IDEs,
-because they do override the operating system's fs signals. The majority of
-editors worked before but I couldn't let some developers without support.
-
-
-### Sessions
-
-
-Sessions manager is also an Adaptor now, `iris.SessionsPolicy`.
-So far we used the `kataras/go-sessions`, you could always use other session manager ofcourse but you would lose the `context.Session()`
-and its returning value, the `iris.Session` now.
-
-`SessionsPolicy` gives the developers the opportunity to adapt any,
-compatible with a particular simple interface(Start and Destroy methods), third-party sessions managers.
-
-- The API for sessions inside context is the same, no matter what session manager you wanna to adapt.
-- The API for sessions inside context didn't changed, it's the same as you knew it.
-
-- Iris, of course, has built'n `SessionsPolicy` adaptor(the kataras/go-sessions: edited to remove fasthttp dependencies).
- - Sessions manager works even faster now and a bug fixed for some browsers.
-
-- Functions like, adding a database or store(i.e: `UseDatabase`) depends on the session manager of your choice,
-Iris doesn't requires these things
-to adapt a package as a session manager. So `iris.UseDatabase` has been removed and depends on the `mySessions.UseDatabase` you 'll see below.
-
-- `iris.DestroySessionByID and iris.DestroyAllSessions` have been also removed, depends on the session manager of your choice, `mySessions.DestroyByID and mySessions.DestroyAll` should do the job now.
-
-
-> Don't worry about forgetting to adapt any feature that you use inside Iris, Iris will print you a how-to-fix message at iris.DevMode log level.
-
-
-**[Examples folder](https://github.com/kataras/iris/tree/v6/adaptors/sessions/_examples)**
-
-
-
-```go
-package main
-
-import (
- "time"
-
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/sessions"
-)
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger()) // enable all (error) logs
- app.Adapt(httprouter.New()) // select the httprouter as the servemux
-
- mySessions := sessions.New(sessions.Config{
- // Cookie string, the session's client cookie name, for example: "mysessionid"
- //
- // Defaults to "irissessionid"
- Cookie: "mysessionid",
- // base64 urlencoding,
- // if you have strange name cookie name enable this
- DecodeCookie: false,
- // it's time.Duration, from the time cookie is created, how long it can be alive?
- // 0 means no expire.
- // -1 means expire when browser closes
- // or set a value, like 2 hours:
- Expires: time.Hour * 2,
- // the length of the sessionid's cookie's value
- CookieLength: 32,
- // if you want to invalid cookies on different subdomains
- // of the same host, then enable it
- DisableSubdomainPersistence: false,
- })
-
- // OPTIONALLY:
- // import "gopkg.in/kataras/iris.v6/adaptors/sessions/sessiondb/redis"
- // or import "github.com/kataras/go-sessions/sessiondb/$any_available_community_database"
- // mySessions.UseDatabase(redis.New(...))
-
- app.Adapt(mySessions) // Adapt the session manager we just created.
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
- })
- app.Get("/set", func(ctx *iris.Context) {
-
- //set session values
- ctx.Session().Set("name", "iris")
-
- //test if setted here
- ctx.Writef("All ok session setted to: %s", ctx.Session().GetString("name"))
- })
-
- app.Get("/get", func(ctx *iris.Context) {
- // get a specific key, as string, if no found returns just an empty string
- name := ctx.Session().GetString("name")
-
- ctx.Writef("The name on the /set was: %s", name)
- })
-
- app.Get("/delete", func(ctx *iris.Context) {
- // delete a specific key
- ctx.Session().Delete("name")
- })
-
- app.Get("/clear", func(ctx *iris.Context) {
- // removes all entries
- ctx.Session().Clear()
- })
-
- app.Get("/destroy", func(ctx *iris.Context) {
-
- //destroy, removes the entire session and cookie
- ctx.SessionDestroy()
- msg := "You have to refresh the page to completely remove the session (browsers works this way, it's not iris-specific.)"
-
- ctx.Writef(msg)
- ctx.Log(iris.DevMode, msg)
- }) // Note about destroy:
- //
- // You can destroy a session outside of a handler too, using the:
- // mySessions.DestroyByID
- // mySessions.DestroyAll
-
- app.Listen(":8080")
-}
-
-```
-
-### Websockets
-
-There are many internal improvements to the websocket server, it
-operates slighty faster to.
-
-
-Websocket is an Adaptor too and you can edit more configuration fields than before.
-No Write and Read timeout by default, you have to set the fields if you want to enable timeout.
-
-Below you'll see the before and the after, keep note that the static and templates didn't changed, so I am not putting the whole
-html and javascript sources here, you can run the full examples from [here](https://github.com/kataras/iris/tree/v6/adaptors/websocket/_examples).
-
-**BEFORE:***
-
-```go
-
-package main
-
-import (
- "fmt" // optional
-
- "github.com/kataras/iris"
-)
-
-type clientPage struct {
- Title string
- Host string
-}
-
-func main() {
- iris.StaticWeb("/js", "./static/js")
-
- iris.Get("/", func(ctx *iris.Context) {
- ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
- })
-
- // the path which the websocket client should listen/registered to ->
- iris.Config.Websocket.Endpoint = "/my_endpoint"
- // by-default all origins are accepted, you can change this behavior by setting:
- // iris.Config.Websocket.CheckOrigin
-
- var myChatRoom = "room1"
- iris.Websocket.OnConnection(func(c iris.WebsocketConnection) {
- // Request returns the (upgraded) *http.Request of this connection
- // avoid using it, you normally don't need it,
- // websocket has everything you need to authenticate the user BUT if it's necessary
- // then you use it to receive user information, for example: from headers.
-
- // httpRequest := c.Request()
- // fmt.Printf("Headers for the connection with ID: %s\n\n", c.ID())
- // for k, v := range httpRequest.Header {
- // fmt.Printf("%s = '%s'\n", k, strings.Join(v, ", "))
- // }
-
- // join to a room (optional)
- c.Join(myChatRoom)
-
- c.On("chat", func(message string) {
- if message == "leave" {
- c.Leave(myChatRoom)
- c.To(myChatRoom).Emit("chat", "Client with ID: "+c.ID()+" left from the room and cannot send or receive message to/from this room.")
- c.Emit("chat", "You have left from the room: "+myChatRoom+" you cannot send or receive any messages from others inside that room.")
- return
- }
- // to all except this connection ->
- // c.To(iris.Broadcast).Emit("chat", "Message from: "+c.ID()+"-> "+message)
- // to all connected clients: c.To(iris.All)
-
- // to the client itself ->
- //c.Emit("chat", "Message from myself: "+message)
-
- //send the message to the whole room,
- //all connections are inside this room will receive this message
- c.To(myChatRoom).Emit("chat", "From: "+c.ID()+": "+message)
- })
-
- // or create a new leave event
- // c.On("leave", func() {
- // c.Leave(myChatRoom)
- // })
-
- c.OnDisconnect(func() {
- fmt.Printf("Connection with ID: %s has been disconnected!\n", c.ID())
-
- })
- })
-
- iris.Listen(":8080")
-}
-
-
-
-```
-
-
-**AFTER**
-```go
-package main
-
-import (
- "fmt" // optional
-
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/view"
- "gopkg.in/kataras/iris.v6/adaptors/websocket"
-)
-
-type clientPage struct {
- Title string
- Host string
-}
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger()) // enable all (error) logs
- app.Adapt(httprouter.New()) // select the httprouter as the servemux
- app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
-
- ws := websocket.New(websocket.Config{
- // the path which the websocket client should listen/registered to,
- Endpoint: "/my_endpoint",
- // the client-side javascript static file path
- // which will be served by Iris.
- // default is /iris-ws.js
- // if you change that you have to change the bottom of templates/client.html
- // script tag:
- ClientSourcePath: "/iris-ws.js",
- //
- // Set the timeouts, 0 means no timeout
- // websocket has more configuration, go to ../../config.go for more:
- // WriteTimeout: 0,
- // ReadTimeout: 0,
- // by-default all origins are accepted, you can change this behavior by setting:
- // CheckOrigin: (r *http.Request ) bool {},
- //
- //
- // IDGenerator used to create (and later on, set)
- // an ID for each incoming websocket connections (clients).
- // The request is an argument which you can use to generate the ID (from headers for example).
- // If empty then the ID is generated by DefaultIDGenerator: randomString(64):
- // IDGenerator func(ctx *iris.Context) string {},
- })
-
- app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
-
- app.StaticWeb("/js", "./static/js") // serve our custom javascript code
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
- })
-
- var myChatRoom = "room1"
-
- ws.OnConnection(func(c websocket.Connection) {
- // Context returns the (upgraded) *iris.Context of this connection
- // avoid using it, you normally don't need it,
- // websocket has everything you need to authenticate the user BUT if it's necessary
- // then you use it to receive user information, for example: from headers.
-
- // ctx := c.Context()
-
- // join to a room (optional)
- c.Join(myChatRoom)
-
- c.On("chat", func(message string) {
- if message == "leave" {
- c.Leave(myChatRoom)
- c.To(myChatRoom).Emit("chat", "Client with ID: "+c.ID()+" left from the room and cannot send or receive message to/from this room.")
- c.Emit("chat", "You have left from the room: "+myChatRoom+" you cannot send or receive any messages from others inside that room.")
- return
- }
- // to all except this connection ->
- // c.To(websocket.Broadcast).Emit("chat", "Message from: "+c.ID()+"-> "+message)
- // to all connected clients: c.To(websocket.All)
-
- // to the client itself ->
- //c.Emit("chat", "Message from myself: "+message)
-
- //send the message to the whole room,
- //all connections are inside this room will receive this message
- c.To(myChatRoom).Emit("chat", "From: "+c.ID()+": "+message)
- })
-
- // or create a new leave event
- // c.On("leave", func() {
- // c.Leave(myChatRoom)
- // })
-
- c.OnDisconnect(func() {
- fmt.Printf("Connection with ID: %s has been disconnected!\n", c.ID())
- })
- })
-
- app.Listen(":8080")
-}
-
-```
-
-
-
-
-If the iris' websocket feature does not cover your app's needs, you can simply use any other
-library for websockets that you used to use, like the Golang's compatible to `socket.io`, simple example:
-
-```go
-package main
-
-import (
- "log"
-
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "github.com/googollee/go-socket.io"
-)
-
-func main() {
- app := iris.New()
- app.Adapt(httprouter.New())
- server, err := socketio.NewServer(nil)
- if err != nil {
- log.Fatal(err)
- }
- server.On("connection", func(so socketio.Socket) {
- log.Println("on connection")
- so.Join("chat")
- so.On("chat message", func(msg string) {
- log.Println("emit:", so.Emit("chat message", msg))
- so.BroadcastTo("chat", "chat message", msg)
- })
- so.On("disconnection", func() {
- log.Println("on disconnect")
- })
- })
- server.On("error", func(so socketio.Socket, err error) {
- log.Println("error:", err)
- })
-
- app.Any("/socket.io", iris.ToHandler(server))
-
- app.Listen(":5000")
-}
-```
-
-### Typescript compiler and cloud-based editor
-
-The Typescript compiler adaptor(old 'plugin') has been fixed (it had an issue on new typescript versions).
-Example can be bound [here](https://github.com/kataras/iris/tree/v6/adaptors/typescript/_example).
-
-The Cloud-based editor adaptor(old 'plugin') also fixed and improved to show debug messages to your iris' LoggerPolicy.
-Example can be bound [here](https://github.com/kataras/iris/tree/v6/adaptors/typescript/editor/_example).
-
-Their import paths also changed as the rest of the old plugins from: https://github.com/iris-contrib/plugin to https://github.com/kataras/adaptors and https://github.com/iris-contrib/adaptors
-I had them on iris-contrib because I thought that community would help but it didn't, no problem, they are at the same codebase now
-which making things easier to debug for me.
-
-
-### Oauth/OAuth2
-Fix the oauth/oauth2 adaptor (old 'plugin') .
-Example can be found [here](https://github.com/iris-contrib/adaptors/tree/master/oauth/_example).
-
-
-### CORS Middleware and the new Wrapper
-
-Lets speak about history of cors middleware, almost all the issues users reported to the iris-contrib/middleware repository
-were relative to the CORS middleware, some users done it work some others don't... it was strange. Keep note that this was one of the two middleware that I didn't
-wrote by myself, it was a PR by a member who wrote that middleware and after didn't answer on users' issues.
-
-Forget about it I removed it entirely and replaced with the `rs/cors`: we now use the https://github.com/rs/cors in two forms:
-
-First, you can use the original middlare that you can install by `go get -u github.com/rs/cors`
-(You had already see its example on the net/http handlers and iris.ToHandler section)
-
-Can be registered globally or per-route but the `MethodsAllowed option doesn't works`.
-
-Example:
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/gorillamux"
- "github.com/rs/cors"
-)
-
-func main(){
- app := iris.New()
- app.Adapt(httprouter.New()) // see below for that
- corsMiddleware := iris.ToHandler(cors.Default().ServeHTTP)
- app.Post("/user", corsMiddleware, func(ctx *iris.Context){
- // ....
- })
-
- app.Listen(":8080")
-}
-```
-
-Secondly, probably the one which you will choose to use, is the `cors` Router Wrapper Adaptor.
-It's already installed when you install iris because it's located at `kataras/iris/adaptors/cors`.
-
-This will wrap the entirely router so the whole of your app will be passing by the rules you setted up on its `cors.Options`.
-
-Again, it's functionality comes from the well-tested `rs/cors`, all known Options are working as expected.
-
-Example:
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/cors"
-)
-
-func main(){
- app := iris.New()
- app.Adapt(httprouter.New()) // see below for that
- app.Adapt(cors.New(cors.Options{})) // or cors.Default()
-
- app.Post("/user", func(ctx *iris.Context){
- // ....
- })
-
- app.Listen(":8080")
-}
-
-```
-
-### FAQ
-You know that you can always share your opinion and ask anything iris-relative with the rest of us, [here](https://kataras.rocket.chat/channel/iris).
+
+### About our new home page
+ http://iris-go.com
+
+Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome!
+
+[Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him.
+
+
+The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please!
+
+# Sa, 03 June 2017
+
+After 2+ months of hard work and collaborations, Iris [version 7](https://github.com/kataras/iris) was published earlier today.
+
+If you're new to Iris you don't have to read all these, just navigate to the [updated examples](https://github.com/kataras/iris/tree/master/_examples) and you should be fine:)
+
+Note that this section will not
+cover the internal changes, the difference is so big that anybody can see them with a glimpse, even the code structure itself.
+
+
+## Changes from [v6](https://github.com/kataras/iris/tree/v6)
+
+Vendoring /w update
+
+The previous vendor action for v6 was done by-hand, now I'm using the [go dep](https://github.com/golang/dep) tool, I had to do
+some small steps:
+
+- remove files like testdata to reduce the folder size
+- rollback some of the "golang/x/net/ipv4" and "ipv6" source files because they are downloaded to their latest versions
+by go dep, but they had lines with the `typealias` feature, which is not ready by current golang version (it will be on August)
+- fix "cannot use internal package" at golang/x/net/ipv4 and ipv6 packages
+ - rename the interal folder to was-internal, everywhere and fix its references.
+- fix "main redeclared in this block"
+ - remove the examples folder from everywhere.
+
+The go dep tool does what is says, as expected, don't be afraid of it now.
+I am totally recommending this tool for package authors, even if it's in its alpha state.
+I remember when Iris was in its alpha state and it had 4k stars on its first weeks/or month and that helped me a lot to fix reported bugs by users and make the framework even better, so give love to go dep from today!
+
+General
+- All `Listen` methods replaced with a single `Run` method, see [here](https://github.com/kataras/iris/tree/master/_examples/beginner/listening)
+- Configuration, easier to modify the defaults, see [here](https://github.com/kataras/iris/tree/master/_examples/beginner/cofiguration)
+- `HandlerFunc` removed, just `Handler` of `func(context.Context)` where context.Context derives from `import "github.com/kataras/iris/context"` (on August this import path will be optional)
+ - Simplify API, i.e instead of all these, `Handle,HandleFunc,Use,UseFunc,Done,DoneFunc,UseGlobal,UseGlobalFunc` use `Handle,Use,Done,UseGlobal`.
+- Response time decreased even more (9-35%, depends on the application)
+- The `Adaptors` idea replaced with a more structural design pattern, but you have to apply these changes:
+ - `app.Adapt(view.HTML/Pug/Amber/Django/Handlebars...)` -> `app.AttachView(view.HTML/Pug/Amber/Django/Handlebars...)`
+ - `app.Adapt(sessions.New(...))` -> `app.AttachSessionManager(sessions.New(...))`
+ - `app.Adapt(iris.LoggerPolicy(...))` -> `app.AttachLogger(io.Writer)`
+ - `app.Adapt(iris.RenderPolicy(...))` -> removed and replaced with the ability to replace the whole context with a custom one or override some methods of it, see below.
+
+Routing
+- Remove of multiple routers, now we have the fresh Iris router which is based on top of the julien's [httprouter](https://github.com/julienschmidt/httprouter)
+- Subdomains routing algorithm has been improved.
+- Iris router is using a custom interpreter with parser and path evaluator to achieve the best expressiveness, with zero performance loss, you ever seen so far, i.e:
+ - `app.Get("/", "/users/{userid:int min(1)}", handler)`,
+ - `{username:string}` or just `{username}`
+ - `{asset:path}`,
+ - `{firstname:alphabetical}`,
+ - `{requestfile:file}` ,
+ - `{mylowercaseParam regexp([a-z]+)}`.
+ - The previous syntax of `:param` and `*param` syntax still working as expected. Previous rules for paths confliction remain as they were.
+ - Also, path parameter names should be only alphabetical now, numbers and symbols are not allowed (for your own good, I have seen a lot the last year...).
+
+Click [here](https://github.com/kataras/iris/tree/master/_examples/beginner/routing) for details.
+> It was my first attempt/experience on the interpreters field, so be good with it :)
+
+Context
+- `iris.Context pointer` replaced with `context.Context interface` as we already mention
+ - in order to be able to use a custom context and/or catch lifetime like `BeginRequest` and `EndRequest` from context itself, see below
+- `context.JSON, context.JSONP, context.XML, context.Markdown, context.HTML` work faster
+- `context.Render("filename.ext", bindingViewData{}, options) ` -> `context.View("filename.ext")`
+ - `View` renders only templates, it will not try to search if you have a restful renderer adapted, because, now, you can do it via method overloading using a custom Context.
+ - Able to set `context.ViewData` and `context.ViewLayout` via middleware when executing a template.
+- `context.SetStatusCode(statusCode)` -> `context.StatusCode(statusCode)`
+ - which is equivalent with the old `EmitError` too:
+ - if status code >=400 given can automatically fire a custom http error handler if response wasn't written already.
+ - `context.GetStatusCode` -> `context.GetStatusCode()`.
+ - `app.OnError` -> `app.OnErrorCode`
+ - Errors per party are removed by-default, you can just use one global error handler with logic like "if path starts with 'prefix' fire this error handler, else...".
+- Easy way to change Iris' default `Context` with a custom one, see [here](https://github.com/kataras/iris/tree/master/_examples/intermediate/custom-context)
+- `context.ResponseWriter().SetBeforeFlush(...)` works for Flush and HTTP/2 Push, respectfully
+- Several improvements under the `Request transactions`
+- Remember that you had to set a status code on each of the render-relative methods? Now it's not required, it just renders
+with the status code that user gave with `context.StatusCode` or with `200 OK`, i.e:
+ -`context.JSON(iris.StatusOK, myJSON{})` -> `context.JSON(myJSON{})`.
+ - Each one of the context's render methods has optional per-call settings,
+ - **the new API is even more easier to read, understand and use.**
+
+Server
+- Several enhancements for the typescript transpiler, view engine, websocket server and sessions manager
+- Able to set custom underline *http.Server(s) with new Host (aka Server Supervisor) feature
+ - `Done` and `Err` channels to catch shutdown or any errors on custom hosts,
+ - Schedule custom tasks(with cancelation) when server is running, see [here](https://github.com/kataras/iris/tree/master/_examples/intermediate/graceful-shutdown)
+ - Taskbar Tray icon (disabled by default)
+ - Linux users have to download manually some dependencies if `app.WithTrayIcon` is passed on `app.Run`'s as second argument, the logger will print how.
+- Interrupt handler task for gracefully shutdown (when `CTRL/CMD+C`) are enabled by-default, you can disable its via configuration: `app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler)`
+
+Future plans
+- Future Go1.9's [ServeTLS](https://go-review.googlesource.com/c/38114/2/src/net/http/server.go) is ready when 1.9 released
+- Future Go1.9's typealias feature is ready when 1.9 released, i.e `context.Context` -> `iris.Context` just one import path instead of todays' two.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 2935ad5d..05050318 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,58 @@
-The MIT License (MIT)
+Copyright (c) 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
-Copyright (c) 2016-2017 Gerasimos Maropoulos
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Gerasimos Maropoulos nor the name of his
+username, kataras, may be used to endorse or promote products derived from
+this software without specific prior written permission.
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+
+The Go Programming Language is redistributed with the following disclaimer:
+
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/README.md b/README.md
index aca86cf9..b0bb9021 100644
--- a/README.md
+++ b/README.md
@@ -1,55 +1,173 @@
-# Iris
+# ![Logo created by @santoshanand](logo_white_35_24.png) Iris
+A fast, cross-platform and efficient web framework with robust set of well-designed features, written entirely in Go.
+
+[![Build status](https://api.travis-ci.org/kataras/iris.svg?branch=master&style=flat-square)](https://travis-ci.org/kataras/iris)
+[![Report card](https://img.shields.io/badge/report%20card%20-a%2B-F44336.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris)
+[![Support forum](https://img.shields.io/badge/support-page-ec2eb4.svg?style=flat-square)](http://support.iris-go.com)
+[![Examples](https://img.shields.io/badge/howto-examples-3362c2.svg?style=flat-square)](https://github.com/kataras/iris/tree/master/_examples#table-of-contents)
+[![Godocs](https://img.shields.io/badge/docs-%20reference-5272B4.svg?style=flat-square)](https://godoc.org/github.com/kataras/iris)
+[![Chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris)
+[![Buy me a cup of coffee](https://img.shields.io/badge/support-%20open--source-F4A460.svg?logo=data:image%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAwIDEwMDAiPjxwYXRoIGZpbGw9InJnYigyMjAsMjIwLDIyMCkiIGQ9Ik04ODYuNiwzMDUuM2MtNDUuNywyMDMuMS0xODcsMzEwLjMtNDA5LjYsMzEwLjNoLTc0LjFsLTUxLjUsMzI2LjloLTYybC0zLjIsMjEuMWMtMi4xLDE0LDguNiwyNi40LDIyLjYsMjYuNGgxNTguNWMxOC44LDAsMzQuNy0xMy42LDM3LjctMzIuMmwxLjUtOGwyOS45LTE4OS4zbDEuOS0xMC4zYzIuOS0xOC42LDE4LjktMzIuMiwzNy43LTMyLjJoMjMuNWMxNTMuNSwwLDI3My43LTYyLjQsMzA4LjktMjQyLjdDOTIxLjYsNDA2LjgsOTE2LjcsMzQ4LjYsODg2LjYsMzA1LjN6Ii8%2BPHBhdGggZmlsbD0icmdiKDIyMCwyMjAsMjIwKSIgZD0iTTc5MS45LDgzLjlDNzQ2LjUsMzIuMiw2NjQuNCwxMCw1NTkuNSwxMEgyNTVjLTIxLjQsMC0zOS44LDE1LjUtNDMuMSwzNi44TDg1LDg1MWMtMi41LDE1LjksOS44LDMwLjIsMjUuOCwzMC4ySDI5OWw0Ny4zLTI5OS42bC0xLjUsOS40YzMuMi0yMS4zLDIxLjQtMzYuOCw0Mi45LTM2LjhINDc3YzE3NS41LDAsMzEzLTcxLjIsMzUzLjItMjc3LjVjMS4yLTYuMSwyLjMtMTIuMSwzLjEtMTcuOEM4NDUuMSwxODIuOCw4MzMuMiwxMzAuOCw3OTEuOSw4My45TDc5MS45LDgzLjl6Ii8%2BPC9zdmc%2B)](https://github.com/kataras/iris#buy-me-a-cup-of-coffee)
+
-Iris is an efficient and well-designed, cross-platform, web framework with robust set of features.
Build your own high-performance web applications and APIs powered by unlimited potentials and portability.
-
-
-
-
-
-
+
-What you say about Iris ✌
+Build your own web applications and portable APIs with the highest performance and countless potentials.
+
+If you're coming from [Node.js](https://nodejs.org) world, this is the [expressjs](https://github.com/expressjs/express)++ equivalent for the [Go Programming Language](https://golang.org).
+
+Installation
-----------
-
-
-
-
-
-
-
+The only requirement is the [Go Programming Language](https://golang.org/dl/), at least version 1.8
-
+```sh
+$ go get -u github.com/kataras/iris
+```
-
-
-
+> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
+For further installation support, please navigate [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework).
-
-
-
+```go
+package main
-
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/view"
+)
+// User is just a bindable object structure.
+type User struct {
+ Username string `json:"username"`
+ Firstname string `json:"firstname"`
+ Lastname string `json:"lastname"`
+ City string `json:"city"`
+ Age int `json:"age"`
+}
-
-
-
+func main() {
+ app := iris.New()
+
+ // Define templates using the std html/template engine.
+ // Parse and load all files inside "./views" folder with ".html" file extension.
+ // Reload the templates on each request (development mode).
+ app.AttachView(view.HTML("./views", ".html").Reload(true))
+
+ // Regster custom handler for specific http errors.
+ app.OnErrorCode(iris.StatusInternalServerError, func(ctx context.Context) {
+ // .Values are used to communicate between handlers, middleware.
+ errMessage := ctx.Values().GetString("error")
+ if errMessage != "" {
+ ctx.Writef("Internal server error: %s", errMessage)
+ return
+ }
+
+ ctx.Writef("(Unexpected) internal server error")
+ })
+
+ app.Use(func(ctx context.Context) {
+ ctx.Application().Log("Begin request for path: %s", ctx.Path())
+ ctx.Next()
+ })
+
+ // app.Done(func(ctx context.Context) {})
+
+ // Method POST: http://localhost:8080/decode
+ app.Post("/decode", func(ctx context.Context) {
+ var user User
+ ctx.ReadJSON(&user)
+ ctx.Writef("%s %s is %d years old and comes from %s", user.Firstname, user.Lastname, user.Age, user.City)
+ })
+
+ // Method GET: http://localhost:8080/encode
+ app.Get("/encode", func(ctx context.Context) {
+ doe := User{
+ Username: "Johndoe",
+ Firstname: "John",
+ Lastname: "Doe",
+ City: "Neither FBI knows!!!",
+ Age: 25,
+ }
+
+ ctx.JSON(doe)
+ })
+
+ // Method GET: http://localhost:8080/profile/anytypeofstring
+ app.Get("/profile/{username:string}", profileByUsername)
+
+ usersRoutes := app.Party("/users", logThisMiddleware)
+ {
+ // Method GET: http://localhost:8080/users/42
+ usersRoutes.Get("/{id:int min(1)}", getUserByID)
+ // Method POST: http://localhost:8080/users/create
+ usersRoutes.Post("/create", createUser)
+ }
+
+ // Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080.
+ app.Run(iris.Addr(":8080"), iris.WithCharset("UTF-8"))
+}
-
-
-
-
+func logThisMiddleware(ctx context.Context) {
+ ctx.Application().Log("Path: %s | IP: %s", ctx.Path(), ctx.RemoteAddr())
+
+ // .Next is required to move forward to the chain of handlers,
+ // if missing then it stops the execution at this handler.
+ ctx.Next()
+}
-If you're coming from Node.js world, this is the expressjs equivalent for the Go Programming Language.
+func profileByUsername(ctx context.Context) {
+ // .Params are used to get dynamic path parameters.
+ username := ctx.Params().Get("username")
+ ctx.ViewData("Username", username)
+ // renders "./views/users/profile.html"
+ // with {{ .Username }} equals to the username dynamic path parameter.
+ ctx.View("users/profile.html")
+}
-
+func getUserByID(ctx context.Context) {
+ userID := ctx.Params().Get("id") // Or convert directly using: .Values().GetInt/GetInt64 etc...
+ // your own db fetch here instead of user :=...
+ user := User{Username: "username" + userID}
+
+ ctx.XML(user)
+}
-Legends [♡](https://github.com/kataras/iris#support)
------------
+func createUser(ctx context.Context) {
+ var user User
+ err := ctx.ReadForm(&user)
+ if err != nil {
+ ctx.Values().Set("error", "creating user, read and parse form failed. "+err.Error())
+ ctx.StatusCode(iris.StatusInternalServerError)
+ return
+ }
+ // renders "./views/users/create_verification.html"
+ // with {{ . }} equals to the User object, i.e {{ .Username }} , {{ .Firstname}} etc...
+ ctx.ViewData("", user)
+ ctx.View("users/create_verification.html")
+}
+```
+
+### Reload on source code changes
+
+```sh
+$ go get -u github.com/kataras/rizla
+$ cd $GOPATH/src/mywebapp
+$ rizla main.go
+```
+
+> Psst: Wanna go to [_examples](https://github.com/kataras/iris/tree/master/_examples) to see more code-snippets?
+
+
+Legends
+
+I'm sorry for taking this personally but I really need to thanks each one of them because they stood up [♡](https://github.com/kataras/iris#support) for me when others trying to "bullying" my personality in order to deflame Iris.
+
+All of us should read and repsect the official [golang](https://golang.org/conduct) and [iris](CODE-OF-CONDUCT.md) community **Code of Conduct**. This type of commitment and communication is the way of making Go great.
+
+
[Juan Sebastián Suárez Valencia](https://github.com/Juanses) donated 20 EUR at September 11 of 2016
@@ -73,18 +191,47 @@ Legends [♡](https://github.com/kataras/iris#support)
[Conrad Steenberg](https://github.com/hengestone) donated 25 EUR at March 23 of 2017
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Feature Overview
-----------
- Focus on high performance
+- Build RESTful APIs with our expressionist path syntax, i.e `{userid:int min(1)}`, `{asset:path}`, `{lowercase: regexp([a-z]+)}`
- Automatically install and serve certificates from https://letsencrypt.org
- Robust routing and middleware ecosystem
-- Build RESTful APIs
-- Choose your favorite routes' path syntax between [httprouter](https://github.com/kataras/iris/blob/v6/_examples/beginner/routes-using-httprouter/main.go) and [gorillamux](https://github.com/kataras/iris/blob/v6/_examples/beginner/routes-using-gorillamux/main.go)
- Request-Scoped Transactions
- Group API's and subdomains with wildcard support
- Body binding for JSON, XML, Forms, can be extended to use your own custom binders
@@ -94,7 +241,7 @@ Feature Overview
- Graceful shutdown
- Limit request body
- Localization i18N
-- Serve static files
+- Serve static and embedded files
- Cache
- Log requests
- Customizable format and output for the logger
@@ -122,239 +269,30 @@ Feature Overview
- And many others...
-Table of Contents
+Documentation
-----------
-
+
+Small but practical [examples](https://github.com/kataras/iris/tree/master/_examples#table-of-contents) --they cover each feature.
-* [Level: Beginner](_examples/beginner)
- * [Hello World](_examples/beginner/hello-world/main.go)
- * [Routes (using httprouter)](_examples/beginner/routes-using-httprouter/main.go)
- * [Routes (using gorillamux)](_examples/beginner/routes-using-gorillamux/main.go)
- * [Internal Application File Logger](_examples/beginner/file-logger/main.go)
- * [Write JSON](_examples/beginner/write-json/main.go)
- * [Read JSON](_examples/beginner/read-json/main.go)
- * [Read Form](_examples/beginner/read-form/main.go)
- * [Favicon](_examples/beginner/favicon/main.go)
- * [File Server](_examples/beginner/file-server/main.go)
- * [Send Files](_examples/beginner/send-files/main.go)
- * [Stream Writer](_examples/beginner/stream-writer/main.go)
- * [Listen UNIX Socket](_examples/beginner/listen-unix/main.go)
- * [Listen TLS](_examples/beginner/listen-tls/main.go)
- * [Listen Letsencrypt (Automatic Certifications)](_examples/beginner/listen-letsencrypt/main.go)
-* [Level: Intermediate](_examples/intermediate)
- * [Send An E-mail](_examples/intermediate/e-mail/main.go)
- * [Upload/Read Files](_examples/intermediate/upload-files/main.go)
- * [Request Logger](_examples/intermediate/request-logger/main.go)
- * [Profiling (pprof)](_examples/intermediate/pprof/main.go)
- * [Basic Authentication](_examples/intermediate/basicauth/main.go)
- * [HTTP Access Control](_examples/intermediate/cors/main.go)
- * [Cache Markdown](_examples/intermediate/cache-markdown/main.go)
- * [Localization and Internationalization](_examples/intermediate/i18n/main.go)
- * [Recovery](_examples/intermediate/recover/main.go)
- * [Graceful Shutdown](_examples/intermediate/graceful-shutdown/main.go)
- * [Custom TCP Listener](_examples/intermediate/custom-listener/main.go)
- * [Custom HTTP Server](_examples/intermediate/custom-httpserver/main.go)
- * [View Engine](_examples/intermediate/view)
- * [Overview](_examples/intermediate/view/overview/main.go)
- * [Template HTML: Part Zero](_examples/intermediate/view/template_html_0/main.go)
- * [Template HTML: Part One](_examples/intermediate/view/template_html_1/main.go)
- * [Template HTML: Part Two](_examples/intermediate/view/template_html_2/main.go)
- * [Template HTML: Part Three](_examples/intermediate/view/template_html_3/main.go)
- * [Template HTML: Part Four](_examples/intermediate/view/template_html_4/main.go)
- * [Inject Data Between Handlers](_examples/intermediate/view/context-view-data/main.go)
- * [Embedding Templates Into Executable](_examples/intermediate/view/embedding-templates-into-app)
- * [Custom Renderer](_examples/intermediate/view/custom-renderer/main.go)
- * [Password Hashing](_examples/intermediate/password-hashing/main.go)
- * [Sessions](_examples/intermediate/sessions)
- * [Overview](_examples/intermediate/sessions/overview/main.go)
- * [Encoding & Decoding the Session ID: Secure Cookie](_examples/intermediate/sessions/securecookie/main.go)
- * [Standalone](_examples/intermediate/sessions/standalone/main.go)
- * [With A Back-End Database](_examples/intermediate/sessions/database/main.go)
- * [Flash Messages](_examples/intermediate/flash-messages/main.go)
- * [Websockets](_examples/intermediate/websockets)
- * [Ridiculous Simple](_examples/intermediate/websockets/ridiculous-simple/main.go)
- * [Overview](_examples/intermediate/websockets/overview/main.go)
- * [Connection List](_examples/intermediate/websockets/connectionlist/main.go)
- * [Native Messages](_examples/intermediate/websockets/naive-messages/main.go)
- * [Secure](_examples/intermediate/websockets/secure/main.go)
- * [Custom Go Client](_examples/intermediate/websockets/custom-go-client/main.go)
-* [Level: Advanced](_examples/advanced)
- * [Transactions](_examples/advanced/transactions/main.go)
- * [HTTP Testing](_examples/advanced/httptest/main_test.go)
- * [Watch & Compile Typescript source files](_examples/advanced/typescript/main.go)
- * [Cloud Editor](_examples/advanced/cloud-editor/main.go)
- * [Online Visitors](_examples/advanced/online-visitors/main.go)
- * [URL Shortener using BoltDB](_examples/advanced/url-shortener/main.go)
- * [Subdomains](_examples/advanced/subdomains)
- * [Single](_examples/advanced/subdomains/single/main.go)
- * [Multi](_examples/advanced/subdomains/multi/main.go)
- * [Wildcard](_examples/advanced/subdomains/wildcard/main.go)
-
-Installation
------------
-
-The only requirement is the [Go Programming Language](https://golang.org/dl/), at least 1.8
-
-```sh
-$ go get gopkg.in/kataras/iris.v6
-```
-
-Overview
------------
-
-```go
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/cors"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/view"
-)
-
-func main() {
- // Receives optional iris.Configuration{}, see ./configuration.go
- // for more.
- app := iris.New()
-
- // Order doesn't matter,
- // You can split it to different .Adapt calls.
- // See ./adaptors folder for more.
- app.Adapt(
- // adapt a logger which prints all errors to the os.Stdout
- iris.DevLogger(),
- // adapt the adaptors/httprouter or adaptors/gorillamux
- httprouter.New(),
- // 5 template engines are supported out-of-the-box:
- //
- // - standard html/template
- // - amber
- // - django
- // - handlebars
- // - pug(jade)
- //
- // Use the html standard engine for all files inside "./views" folder with extension ".html"
- view.HTML("./views", ".html"),
- // Cors wrapper to the entire application, allow all origins.
- cors.New(cors.Options{AllowedOrigins: []string{"*"}}))
-
- // http://localhost:6300
- // Method: "GET"
- // Render ./views/index.html
- app.Get("/", func(ctx *iris.Context) {
- ctx.Render("index.html", iris.Map{"Title": "Page Title"}, iris.RenderOptions{"gzip": true})
- })
-
- // Group routes, optionally: share middleware, template layout and custom http errors.
- userAPI := app.Party("/users", userAPIMiddleware).
- Layout("layouts/userLayout.html")
- {
- // Fire userNotFoundHandler when Not Found
- // inside http://localhost:6300/users/*anything
- userAPI.OnError(404, userNotFoundHandler)
-
- // http://localhost:6300/users
- // Method: "GET"
- userAPI.Get("/", getAllHandler)
-
- // http://localhost:6300/users/42
- // Method: "GET"
- userAPI.Get("/:id", getByIDHandler)
-
- // http://localhost:6300/users
- // Method: "POST"
- userAPI.Post("/", saveUserHandler)
- }
-
- // Start the server at 127.0.0.1:6300
- app.Listen(":6300")
-}
-
-func userAPIMiddleware(ctx *iris.Context) {
- // your code here...
- println("Request: " + ctx.Path())
- ctx.Next() // go to the next handler(s)
-}
-
-func userNotFoundHandler(ctx *iris.Context) {
- // your code here...
- ctx.HTML(iris.StatusNotFound, " User page not found
")
-}
-
-func getAllHandler(ctx *iris.Context) {
- // your code here...
-}
-
-func getByIDHandler(ctx *iris.Context) {
- // take the :id from the path, parse to integer
- // and set it to the new userID local variable.
- userID, _ := ctx.ParamInt("id")
-
- // userRepo, imaginary database service <- your only job.
- user := userRepo.GetByID(userID)
-
- // send back a response to the client,
- // .JSON: content type as application/json; charset="utf-8"
- // iris.StatusOK: with 200 http status code.
- //
- // send user as it is or make use of any json valid golang type,
- // like the iris.Map{"username" : user.Username}.
- ctx.JSON(iris.StatusOK, user)
-}
-
-func saveUserHandler(ctx *iris.Context) {
- // your code here...
-}
-```
-
-### Reload on source code changes
-
-```sh
-$ go get -u github.com/kataras/rizla
-$ cd $GOPATH/src/mywebapp
-$ rizla main.go
-```
-
-### Reload templates on each incoming request
-
-```go
-app.Adapt(view.HTML("./views", ".html").Reload(true))
-```
-
-
-FAQ & Documentation
------------
-
-
-
-1. [Getting Started with Go+Iris](http://gopherbook.iris-go.com)
-
-2. Official small but practical [examples](https://github.com/kataras/iris/tree/v6/_examples#table-of-contents)
-
-3. Navigate through [community examples](https://github.com/iris-contrib/examples) too
-
-4. [Creating A URL Shortener Service Using Go, Iris, and Bolt](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7)
-
-5. [Godocs](https://godoc.org/gopkg.in/kataras/iris.v6) for deep documentation
-
-6. [HISTORY.md](https://github.com//kataras/iris/tree/v6/HISTORY.md) is your best friend, version migrations are released there
-
-
-I'll be glad to talk with you about **your awesome feature requests**,
-open a new [discussion](http://support.iris-go.com), you will be heard!
+Wanna create your own fast URL Shortener Service Using Iris? --click [here](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7) to learn how.
+[Godocs](https://godoc.org/github.com/kataras/iris) --for deep understanding.
Support
------------
-- :star: [the project](https://github.com/kataras/iris/stargazers), will help you to follow the upcoming features
-- [Donate](https://github.com/kataras/iris#buy-me-a-cup-of-coffee), will help me to continue
-- [Post](http://support.iris-go.com) a feature request or report a bug, will help all of us to build a better web, together
-- :earth_americas: post [an article](https://dzone.com/articles/a-url-shortener-service-using-go-iris-and-bolt-ger) or [tweet](https://twitter.com/gelnior/status/769100480706379776) and share it with your neighbor
+- [Post](http://support.iris-go.com) a feature request or report a bug, will help to make the framework even better.
+- :star: and watch [the project](https://github.com/kataras/iris/stargazers), will notify you about updates.
+- :earth_americas: publish [an article](https://medium.com/) or share a [tweet](https://twitter.com/) about Iris.
+- Donations, will help me to continue.
+I'll be glad to talk with you about **your awesome feature requests**,
+open a new [discussion](http://support.iris-go.com), you will be heard!
+
+Thanks in advance!
Buy me a cup of coffee?
------------
@@ -364,21 +302,40 @@ Iris is free and open source but developing it has taken thousands of hours of m
I spend all my time in the construction of Iris, therefore I have no income value.
-Feel free to send **any** amount through paypal
+Feel free to send **any** amount through paypal:
[![](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=kataras2006%40hotmail%2ecom&lc=GR&item_name=Iris%20web%20framework&item_number=iriswebframeworkdonationid2016¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)
> Please check your e-mail after your donation.
-
Thanks for your gratitude and finance help ♡
+
+
+
Third Party Middleware
------------
-Iris has its own middleware form of `func(ctx *iris.Context)` but it's also compatible with all `net/http` middleware forms using [iris.ToHandler](https://github.com/iris-contrib/middleware/blob/master/cors/cors.go#L33), i.e Negroni's middleware form of `func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)`.
+Iris has its own middleware form of `func(ctx context.Context)` but it's also compatible with all `net/http` middleware forms. See [here](https://github.com/kataras/iris/blob/master/_examples/beginner/convert-handlers/negroni-like/main.go).
-Here is a small list of Iris compatible middleware, I'm sure you can find more:
+I'm sure that each of you have, already, found his own favorite list but here's a small list of third-party handlers:
| Middleware | Author | Description |
| -----------|--------|-------------|
@@ -406,32 +363,16 @@ Feel free to put up a [PR](https://github.com/iris-contrib/middleware) your midd
Testing
------------
-The `httptest` package is a simple Iris helper for the httpexpect, a new library for End-to-end HTTP and REST API testing for Go.
+The `httptest` package is your way for end-to-end HTTP testing, it uses the httpexpect library created by our friend, [gavv](https://github.com/gavv).
-You can find tests by navigating to the source code,
-i.e:
-
-- [context_test.go](https://github.com/kataras/iris/blob/v6/context_test.go)
-- [handler_test.go](https://github.com/kataras/iris/blob/v6/handler_test.go)
-- [policy_gorillamux_test.go](https://github.com/kataras/iris/blob/v6/policy_gorillamux_test.go)
-- [policy_httprouter_test.go](https://github.com/kataras/iris/blob/v6/policy_httprouter_test.go)
-- [policy_nativerouter_test.go](https://github.com/kataras/iris/blob/v6/policy_nativerouter_test.go)
-- [policy_routerwrapper_test.go](https://github.com/kataras/iris/blob/v6/policy_routerwrapper_test.go)
-- [policy_sessions_test.go](https://github.com/kataras/iris/blob/v6/policy_sessions_test.go)
-- [response_writer_test.go](https://github.com/kataras/iris/blob/v6/response_writer_test.go)
-- [route_test.go](https://github.com/kataras/iris/blob/v6/route_test.go)
-- [status_test.go](https://github.com/kataras/iris/blob/v6/status_test.go)
-- [transaction_test.go](https://github.com/kataras/iris/blob/v6/transaction_test.go)
-- [serializer_test.go](https://github.com/kataras/iris/blob/v6/serializer_test.go)
-
-A simple test is located to [./_examples/advanced/httptest/main_test.go](https://github.com/kataras/iris/blob/v6/_examples/advanced/httptest/main_test.go)
+A simple test is located to [./_examples/intermediate/httptest/main_test.go](https://github.com/kataras/iris/blob/master/_examples/intermediate/httptest/main_test.go)
Philosophy
------------
-The Iris philosophy is to provide robust tooling for HTTP, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs. Keep note that, today, iris is faster than nginx itself.
+The Iris philosophy is to provide robust tooling for HTTP, making it a great solution for single page applications, web sites, hybrids, or public HTTP APIs. Keep note that, today, iris is faster than apache+nginx itself.
-Iris does not force you to use any specific ORM or template engine. Iris is routerless which means you can adapt any router you like, [httprouter](https://github.com/kataras/iris/blob/v6/_examples/beginner/routes-using-httprouter/main.go) is the fastest, [gorillamux](https://github.com/kataras/iris/blob/v6/_examples/beginner/routes-using-gorillamux/main.go) has more features. With support for the most used template engines (5), you can quickly craft the perfect application.
+Iris does not force you to use any specific ORM or template engine. With support for the most popular template engines, you can quickly craft your perfect application.
People
@@ -441,7 +382,6 @@ The author of Iris is [@kataras](https://github.com/kataras).
However the real Success of Iris belongs to you with your bug reports and feature requests that made this Framework so Unique.
-
Contact
------------
@@ -451,18 +391,39 @@ Besides the fact that we have a [community chat][Chat] for questions or reports
- [Facebook](https://facebook.com/kataras.gopher)
- [Linkedin](https://www.linkedin.com/in/gerasimos-maropoulos)
-
-Codename: ["√Νεxτ"](https://github.com/kataras/iris/blob/v6/HISTORY.md)
+Version
------------
+Current: v7
+
+Each new release is pushed to the master. It stays there until the next version. When a next version is released then the previous version goes to its own branch with `gopkg.in` as its import path (and its own vendor folder), in order to keep it working "for-ever".
+
+Community members can request additional features or report a bug fix for a specific iris version.
+
+
+### Should I upgrade my Iris?
+
+Developers are not forced to use the latest Iris version, they can use any version in production, they can update at any time they want.
+
+Testers should upgrade immediately, if you're willing to use Iris in production you can wait a little more longer, transaction should be as safe as possible.
+
+### Where can I find older versions?
+
+Each Iris version is independent. Only bug fixes, Router's API and experience are kept.
+
+Previous versions can be found at [releases page](https://github.com/kataras/iris/releases).
+
License
------------
Unless otherwise noted, the source files are distributed
-under the MIT License found in the [LICENSE file](LICENSE).
+under the BSD-3-Clause License found in the [LICENSE file](LICENSE).
-Note that some optional components that you may use with Iris requires
+Note that some third-party packages that you use with Iris may requires
different license agreements.
-
[Chat]: https://kataras.rocket.chat/channel/iris
+
+
+
+
diff --git a/_examples/README.md b/_examples/README.md
index 88310246..6aca38bd 100644
--- a/_examples/README.md
+++ b/_examples/README.md
@@ -1,18 +1,34 @@
# Examples
-This folder provides easy to understand code snippets on how to get started with web development with the Go programming language using the [Iris](https://github.com/kataras/iris) web framework.
+This folder provides easy to understand code snippets on how to get started with web development with the Go programming language using the [Iris](https://github.com/kataras/iris) web framework.
-It doesn't contains "best ways" neither explains all its features. It's just a simple, practical cookbook for young Go developers!
+It doesn't contains "best ways" neither explains all its features. It's just a simple, practical cookbook for young Gophers!
-## Table of Contents
-
-
+## Table of contents
* [Level: Beginner](beginner)
- * [Hello World](beginner/hello-world/main.go)
- * [Routes (using httprouter)](beginner/routes-using-httprouter/main.go)
- * [Routes (using gorillamux)](beginner/routes-using-gorillamux/main.go)
+ * [Overview](beginner/overview/main.go)
+ * [Listening](beginner/listening)
+ * [Common, with address](beginner/listening/listen-addr/main.go)
+ * [UNIX socket file](beginner/listening/listen-unix/main.go)
+ * [TLS](beginner/listening/listen-tls)
+ * [Letsencrypt (Automatic Certifications)](beginner/listening/listen-letsencrypt/main.go)
+ * [Custom TCP Listener](beginner/listening/custom-listener/main.go)
+ * [Configuration](beginner/configuration)
+ * [Basic way](beginner/configuration/basic/main.go)
+ * [Functional way](beginner/configuration/functional/main.go)
+ * [Import from YAML file](beginner/configuration/from-yaml-file/main.go)
+ * [Import from TOML file](beginner/configuration/from-toml-file/main.go)
+ * [Routing](beginner/routing)
+ * [Overview](beginner/routing/main.go)
+ * [Basic](beginner/routing/basic/main.go)
+ * [Dynamic Path](beginner/routing/dynamic-path/main.go)
+ * [Reverse routing](beginner/routing/reverse/main.go)
+ * [Transform any third-party handler to iris-compatible handler](beginner/convert-handlers)
+ * [From func(http.ResponseWriter, *http.Request, http.HandlerFunc)](beginner/convert-handlers/negroni-like/main.go)
+ * [From http.Handler or http.HandlerFunc](beginner/convert-handlers/nethttp/main.go)
* [Internal Application File Logger](beginner/file-logger/main.go)
+ * [Custom HTTP Errors](beginner/http-errors/main.go)
* [Write JSON](beginner/write-json/main.go)
* [Read JSON](beginner/read-json/main.go)
* [Read Form](beginner/read-form/main.go)
@@ -20,38 +36,46 @@ It doesn't contains "best ways" neither explains all its features. It's just a s
* [File Server](beginner/file-server/main.go)
* [Send Files](beginner/send-files/main.go)
* [Stream Writer](beginner/stream-writer/main.go)
- * [Listen UNIX Socket](beginner/listen-unix/main.go)
- * [Listen TLS](beginner/listen-tls/main.go)
- * [Listen Letsencrypt (Automatic Certifications)](beginner/listen-letsencrypt/main.go)
+ * [Send An E-mail](beginner/e-mail/main.go)
+ * [Upload/Read Files](beginner/upload-files/main.go)
+ * [Recovery](beginner/recover/main.go)
+ * [Profiling (pprof)](beginner/pprof/main.go)
+ * [Request Logger](beginner/request-logger/main.go)
+ * [Basic Authentication](beginner/basicauth/main.go)
* [Level: Intermediate](intermediate)
- * [Send An E-mail](intermediate/e-mail/main.go)
- * [Upload/Read Files](intermediate/upload-files/main.go)
- * [Request Logger](intermediate/request-logger/main.go)
- * [Profiling (pprof)](intermediate/pprof/main.go)
- * [Basic Authentication](intermediate/basicauth/main.go)
+ * [Transactions](intermediate/transactions/main.go)
+ * [HTTP Testing](intermediate/httptest/main_test.go)
+ * [Watch & Compile Typescript source files](intermediate/typescript/main.go)
+ * [Cloud Editor](intermediate/cloud-editor/main.go)
+ * [Serve Embedded Files](intermediate/serve-embedded-files/main.go)
* [HTTP Access Control](intermediate/cors/main.go)
* [Cache Markdown](intermediate/cache-markdown/main.go)
* [Localization and Internationalization](intermediate/i18n/main.go)
- * [Recovery](intermediate/recover/main.go)
- * [Graceful Shutdown](intermediate/graceful-shutdown/main.go)
- * [Custom TCP Listener](intermediate/custom-listener/main.go)
- * [Custom HTTP Server](intermediate/custom-httpserver/main.go)
+ * [Graceful Shutdown](intermediate/graceful-shutdown)
+ * [Basic and simple](intermediate/graceful-shutdown/basic/main.go)
+ * [Custom Host](intermediate/graceful-shutdown/custom-host/main.go)
+ * [Custom HTTP Server](intermediate/custom-httpserver)
+ * [Iris way](intermediate/custom-httpserver/iris-way/main.go)
+ * [Standar way](intermediate/custom-httpserver/std-way/main.go)
+ * [More than one server](intermediate/custom-httpserver/multi/main.go)
+ * [Custom Context](intermediate/custom-context)
+ * [Method Overriding](intermediate/custom-context/method-overriding/main.go)
+ * [Route State](intermediate/route-state/main.go)
* [View Engine](intermediate/view)
* [Overview](intermediate/view/overview/main.go)
- * [Template HTML: Part Zero](intermediate/view/template_html_0/main.go)
- * [Template HTML: Part One](intermediate/view/template_html_1/main.go)
- * [Template HTML: Part Two](intermediate/view/template_html_2/main.go)
- * [Template HTML: Part Three](intermediate/view/template_html_3/main.go)
- * [Template HTML: Part Four](intermediate/view/template_html_4/main.go)
+ * [Hi](intermediate/view/template_html_0/main.go)
+ * [Showcase one simple Layout](intermediate/view/template_html_1/main.go)
+ * [Layouts `yield` and `render` tmpl funcs](intermediate/view/template_html_2/main.go)
+ * [Showcase of the `urlpath` tmpl func](intermediate/view/template_html_3/main.go)
+ * [Showcase of the `url` tmpl func](intermediate/view/template_html_4/main.go)
* [Inject Data Between Handlers](intermediate/view/context-view-data/main.go)
- * [Embedding Templates Into Executable](intermediate/view/embedding-templates-into-app)
- * [Custom Renderer](intermediate/view/custom-renderer/main.go)
- * [Password Hashing](intermediate/password-hashing/main.go)
+ * [Embedding Templates Into App Executable File](intermediate/view/embedding-templates-into-app)
* [Sessions](intermediate/sessions)
* [Overview](intermediate/sessions/overview/main.go)
* [Encoding & Decoding the Session ID: Secure Cookie](intermediate/sessions/securecookie/main.go)
* [Standalone](intermediate/sessions/standalone/main.go)
* [With A Back-End Database](intermediate/sessions/database/main.go)
+ * [Password Hashing](intermediate/sessions/password-hashing/main.go)
* [Flash Messages](intermediate/flash-messages/main.go)
* [Websockets](intermediate/websockets)
* [Ridiculous Simple](intermediate/websockets/ridiculous-simple/main.go)
@@ -60,20 +84,14 @@ It doesn't contains "best ways" neither explains all its features. It's just a s
* [Native Messages](intermediate/websockets/naive-messages/main.go)
* [Secure](intermediate/websockets/secure/main.go)
* [Custom Go Client](intermediate/websockets/custom-go-client/main.go)
+ * [Subdomains](intermediate/subdomains)
+ * [Single](intermediate/subdomains/single/main.go)
+ * [Multi](intermediate/subdomains/multi/main.go)
+ * [Wildcard](intermediate/subdomains/wildcard/main.go)
* [Level: Advanced](advanced)
- * [Transactions](advanced/transactions/main.go)
- * [HTTP Testing](advanced/httptest/main_test.go)
- * [Watch & Compile Typescript source files](advanced/typescript/main.go)
- * [Cloud Editor](advanced/cloud-editor/main.go)
* [Online Visitors](advanced/online-visitors/main.go)
* [URL Shortener using BoltDB](advanced/url-shortener/main.go)
- * [Subdomains](advanced/subdomains)
- * [Single](advanced/subdomains/single/main.go)
- * [Multi](advanced/subdomains/multi/main.go)
- * [Wildcard](advanced/subdomains/wildcard/main.go)
+> Do not forget to [star or watch the project](https://github.com/kataras/iris/stargazers) in order to stay updated with the latest tech trends, it takes some seconds for the sake of go!
-
-> Don't forget to take a quick look or add your own [examples in the community's repository](https://github.com/iris-contrib/examples)!
-
-> Developers should read the official [documentation](https://godoc.org/gopkg.in/kataras/iris.v6), in depth, for better understanding.
+> Developers should read the official [documentation](https://godoc.org/github.com/kataras/iris) in depth, for deep understanding.
diff --git a/_examples/advanced/httptest/main.go b/_examples/advanced/httptest/main.go
deleted file mode 100644
index 7302b800..00000000
--- a/_examples/advanced/httptest/main.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/sessions"
-)
-
-func newApp() *iris.Framework {
- app := iris.New()
- app.Adapt(httprouter.New())
- app.Adapt(sessions.New(sessions.Config{Cookie: "mysessionid"}))
-
- app.Get("/hello", func(ctx *iris.Context) {
- sess := ctx.Session()
- if !sess.HasFlash() /* or sess.GetFlash("name") == "", same thing here */ {
- ctx.HTML(iris.StatusUnauthorized, " Unauthorized Page!
")
- return
- }
-
- ctx.JSON(iris.StatusOK, iris.Map{
- "Message": "Hello",
- "From": sess.GetFlash("name"),
- })
- })
-
- app.Post("/login", func(ctx *iris.Context) {
- sess := ctx.Session()
- if !sess.HasFlash() {
- sess.SetFlash("name", ctx.FormValue("name"))
- }
- // let's no redirect, just set the flash message, nothing more.
- })
-
- return app
-}
-
-func main() {
- app := newApp()
- app.Listen(":8080")
-}
diff --git a/_examples/advanced/online-visitors/main.go b/_examples/advanced/online-visitors/main.go
index 786c5c35..8206a0c7 100644
--- a/_examples/advanced/online-visitors/main.go
+++ b/_examples/advanced/online-visitors/main.go
@@ -3,30 +3,27 @@ package main
import (
"sync/atomic"
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/view"
- "gopkg.in/kataras/iris.v6/adaptors/websocket"
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+
+ "github.com/kataras/iris/view"
+ "github.com/kataras/iris/websocket"
)
var (
- app *iris.Framework
+ app *iris.Application
ws websocket.Server
)
func init() {
// init the server instance
app = iris.New()
- // adapt a logger in dev mode
- app.Adapt(iris.DevLogger())
- // adapt router
- app.Adapt(httprouter.New())
- // adapt templaes
- app.Adapt(view.HTML("./templates", ".html").Reload(true))
- // adapt websocket
+ // load templaes
+ app.AttachView(view.HTML("./templates", ".html").Reload(true))
+ // attach websocket server
ws = websocket.New(websocket.Config{Endpoint: "/my_endpoint"})
ws.OnConnection(HandleWebsocketConnection)
- app.Adapt(ws)
+ ws.Attach(app)
}
type page struct {
@@ -36,21 +33,23 @@ type page struct {
func main() {
app.StaticWeb("/js", "./static/assets/js")
- h := func(ctx *iris.Context) {
- ctx.Render("index.html", page{PageID: "index page"})
+ h := func(ctx context.Context) {
+ ctx.ViewData("", page{PageID: "index page"})
+ ctx.View("index.html")
}
- h2 := func(ctx *iris.Context) {
- ctx.Render("other.html", page{PageID: "other page"})
+ h2 := func(ctx context.Context) {
+ ctx.ViewData("", page{PageID: "other page"})
+ ctx.View("other.html")
}
// Open some browser tabs/or windows
// and navigate to
- // http://localhost:8080/ and http://localhost:8080/other
+ // http://localhost:8080/ and http://localhost:8080/other multiple times.
// Each page has its own online-visitors counter.
app.Get("/", h)
app.Get("/other", h2)
- app.Listen(":8080")
+ app.Run(iris.Addr(":8080"))
}
type pageView struct {
diff --git a/_examples/advanced/subdomains/multi/main.go b/_examples/advanced/subdomains/multi/main.go
deleted file mode 100644
index 8a7bcbd8..00000000
--- a/_examples/advanced/subdomains/multi/main.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-func main() {
- app := iris.New()
- app.Adapt(iris.DevLogger())
- // subdomains works with all available routers, like other features too.
- app.Adapt(httprouter.New())
-
- /*
- * Setup static files
- */
-
- app.StaticWeb("/assets", "./public/assets")
- app.StaticWeb("/upload_resources", "./public/upload_resources")
-
- dashboard := app.Party("dashboard.")
- {
- dashboard.Get("/", func(ctx *iris.Context) {
- ctx.Writef("HEY FROM dashboard")
- })
- }
- system := app.Party("system.")
- {
- system.Get("/", func(ctx *iris.Context) {
- ctx.Writef("HEY FROM system")
- })
- }
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Writef("HEY FROM frontend /")
- })
- /* test this on firefox, because the domain is not real (because of .local), on firefox this will fail, but you can test it with other domain */
- app.Listen("domain.local:80") // for beginners: look ../hosts file
-}
diff --git a/_examples/advanced/url-shortener/main.go b/_examples/advanced/url-shortener/main.go
index c8fba621..7a0205e7 100644
--- a/_examples/advanced/url-shortener/main.go
+++ b/_examples/advanced/url-shortener/main.go
@@ -13,21 +13,11 @@ import (
"time"
"github.com/boltdb/bolt"
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/view"
-)
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
-// a custom Iris event policy, which will run when server interruped (i.e control+C)
-// receives a func() error, most of packages are compatible with that on their Close/Shutdown/Cancel funcs.
-func releaser(r func() error) iris.EventPolicy {
- return iris.EventPolicy{
- Interrupted: func(app *iris.Framework) {
- if err := r(); err != nil {
- app.Log(iris.ProdMode, "error while releasing resources: "+err.Error())
- }
- }}
-}
+ "github.com/kataras/iris/view"
+)
func main() {
app := iris.New()
@@ -36,83 +26,77 @@ func main() {
db := NewDB("shortener.db")
factory := NewFactory(DefaultGenerator, db)
- app.Adapt(
- // print all kind of errors and logs at os.Stdout
- iris.DevLogger(),
- // use the httprouter, you can use adpaotrs/gorillamux if you want
- httprouter.New(),
- // serve the "./templates" directory's "*.html" files with the HTML std view engine.
- view.HTML("./templates", ".html").Reload(true),
- // `db.Close` is a `func() error` so it can be a `releaser` too.
- // Wrap the db.Close with the releaser in order to be released when app exits or control+C
- // You probably never saw that before, clever pattern which I am able to use only with Iris :)
- releaser(db.Close),
- )
-
+ // serve the "./templates" directory's "*.html" files with the HTML std view engine.
+ tmpl := view.HTML("./templates", ".html").Reload(true)
// template funcs
//
// look ./templates/index.html#L16
- app.Adapt(iris.TemplateFuncsPolicy{"isPositive": func(n int) bool {
+ tmpl.AddFunc("isPositive", func(n int) bool {
if n > 0 {
return true
}
return false
- }})
+ })
+
+ app.AttachView(tmpl)
// Serve static files (css)
app.StaticWeb("/static", "./resources")
- app.Get("/", func(ctx *iris.Context) {
- ctx.MustRender("index.html", iris.Map{"url_count": db.Len()})
+ app.Get("/", func(ctx context.Context) {
+ ctx.ViewData("url_count", db.Len())
+ ctx.View("index.html")
})
// find and execute a short url by its key
// used on http://localhost:8080/u/dsaoj41u321dsa
- execShortURL := func(ctx *iris.Context, key string) {
+ execShortURL := func(ctx context.Context, key string) {
if key == "" {
- ctx.EmitError(iris.StatusBadRequest)
+ ctx.StatusCode(iris.StatusBadRequest)
return
}
value := db.Get(key)
if value == "" {
- ctx.SetStatusCode(iris.StatusNotFound)
+ ctx.StatusCode(iris.StatusNotFound)
ctx.Writef("Short URL for key: '%s' not found", key)
return
}
ctx.Redirect(value, iris.StatusTemporaryRedirect)
}
- app.Get("/u/:shortkey", func(ctx *iris.Context) {
- execShortURL(ctx, ctx.Param("shortkey"))
+ app.Get("/u/:shortkey", func(ctx context.Context) {
+ execShortURL(ctx, ctx.Params().Get("shortkey"))
})
- app.Post("/shorten", func(ctx *iris.Context) {
- data := make(map[string]interface{}, 0)
+ app.Post("/shorten", func(ctx context.Context) {
formValue := ctx.FormValue("url")
if formValue == "" {
- data["form_result"] = "You need to a enter a URL."
+ ctx.ViewData("form_result", "You need to a enter a URL")
} else {
key, err := factory.Gen(formValue)
if err != nil {
- data["form_result"] = "Invalid URL."
+ ctx.ViewData("form_result", "Invalid URL")
} else {
if err = db.Set(key, formValue); err != nil {
- data["form_result"] = "Internal error while saving the url"
- app.Log(iris.DevMode, "while saving url: "+err.Error())
+ ctx.ViewData("form_result", "Internal error while saving the URL")
+ app.Log("while saving URL: " + err.Error())
} else {
- ctx.SetStatusCode(iris.StatusOK)
- shortenURL := "http://" + app.Config.VHost + "/u/" + key
- data["form_result"] = template.HTML("" + shortenURL + "
")
+ ctx.StatusCode(iris.StatusOK)
+ shortenURL := "http://" + app.ConfigurationReadOnly().GetVHost() + "/u/" + key
+ ctx.ViewData("form_result",
+ template.HTML(""+shortenURL+"
"))
}
}
}
- data["url_count"] = db.Len()
- ctx.Render("index.html", data)
+ ctx.ViewData("url_count", db.Len())
+ ctx.View("index.html")
})
- app.Listen("localhost:8080")
+ app.Run(iris.Addr(":8080"))
+
+ db.Close()
}
// +------------------------------------------------------------+
diff --git a/_examples/intermediate/basicauth/main.go b/_examples/beginner/basicauth/main.go
similarity index 50%
rename from _examples/intermediate/basicauth/main.go
rename to _examples/beginner/basicauth/main.go
index 99e46352..b7e37a26 100644
--- a/_examples/intermediate/basicauth/main.go
+++ b/_examples/beginner/basicauth/main.go
@@ -3,55 +3,56 @@ package main
import (
"time"
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/middleware/basicauth"
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/middleware/basicauth"
)
func main() {
app := iris.New()
- app.Adapt(iris.DevLogger()) // adapt a simple internal logger to print any errors
- app.Adapt(httprouter.New()) // adapt a router, you can use gorillamux too
authConfig := basicauth.Config{
Users: map[string]string{"myusername": "mypassword", "mySecondusername": "mySecondpassword"},
Realm: "Authorization Required", // defaults to "Authorization Required"
- ContextKey: "mycustomkey", // defaults to "user"
+ ContextKey: "user", // defaults to "user"
Expires: time.Duration(30) * time.Minute,
}
authentication := basicauth.New(authConfig)
- app.Get("/", func(ctx *iris.Context) { ctx.Redirect("/admin") })
- // to global app.Use(authentication) (or app.UseGlobal before the .Listen)
+
+ // to global app.Use(authentication) (or app.UseGlobal before the .Run)
// to routes
/*
- app.Get("/mysecret", authentication, func(ctx *iris.Context) {
- username := ctx.GetString("mycustomkey") // the Contextkey from the authConfig
+ app.Get("/mysecret", authentication, func(ctx context.Context) {
+ username := ctx.Values().GetString("user") // the Contextkey from the authConfig
ctx.Writef("Hello authenticated user: %s ", username)
})
*/
+ app.Get("/", func(ctx context.Context) { ctx.Redirect("/admin") })
+
// to party
needAuth := app.Party("/admin", authentication)
{
//http://localhost:8080/admin
- needAuth.Get("/", func(ctx *iris.Context) {
- username := ctx.GetString("mycustomkey") // the Contextkey from the authConfig
+ needAuth.Get("/", func(ctx context.Context) {
+ username := ctx.Values().GetString("mycustomkey") // the Contextkey from the authConfig
ctx.Writef("Hello authenticated user: %s from: %s ", username, ctx.Path())
})
// http://localhost:8080/admin/profile
- needAuth.Get("/profile", func(ctx *iris.Context) {
- username := ctx.GetString("mycustomkey") // the Contextkey from the authConfig
+ needAuth.Get("/profile", func(ctx context.Context) {
+ username := ctx.Values().GetString("mycustomkey") // the Contextkey from the authConfig
ctx.Writef("Hello authenticated user: %s from: %s ", username, ctx.Path())
})
+
// http://localhost:8080/admin/settings
- needAuth.Get("/settings", func(ctx *iris.Context) {
- username := authConfig.User(ctx) // shortcut for ctx.GetString("mycustomkey")
+ needAuth.Get("/settings", func(ctx context.Context) {
+ username := authConfig.User(ctx) // shortcut for ctx.Values().GetString("mycustomkey")
ctx.Writef("Hello authenticated user: %s from: %s ", username, ctx.Path())
})
}
// open http://localhost:8080/admin
- app.Listen(":8080")
+ app.Run(iris.Addr(":8080"))
}
diff --git a/_examples/beginner/configuration/basic/main.go b/_examples/beginner/configuration/basic/main.go
new file mode 100644
index 00000000..af24c0bd
--- /dev/null
+++ b/_examples/beginner/configuration/basic/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+)
+
+func main() {
+ app := iris.New()
+
+ // [...]
+
+ // Good when you want to modify the whole configuration.
+ app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.Configuration{ // default configuration:
+ DisableBanner: false,
+ DisableTray: false,
+ DisableInterruptHandler: false,
+ DisablePathCorrection: false,
+ EnablePathEscape: false,
+ FireMethodNotAllowed: false,
+ DisableBodyConsumptionOnUnmarshal: false,
+ DisableAutoFireStatusCode: false,
+ TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT",
+ Charset: "UTF-8",
+ }))
+
+ // or before run:
+ // app.Configure(iris.WithConfiguration(...))
+ // app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/configuration/from-toml-file/configs/iris.tml b/_examples/beginner/configuration/from-toml-file/configs/iris.tml
new file mode 100644
index 00000000..3c2d6f34
--- /dev/null
+++ b/_examples/beginner/configuration/from-toml-file/configs/iris.tml
@@ -0,0 +1,10 @@
+DisableTray: true
+DisablePathCorrection = false
+EnablePathEscape = false
+FireMethodNotAllowed = true
+DisableBodyConsumptionOnUnmarshal = false
+TimeFormat = "Mon, 01 Jan 2006 15:04:05 GMT"
+Charset = "UTF-8"
+
+[Other]
+ MyServerName = "Iris"
diff --git a/_examples/beginner/configuration/from-toml-file/main.go b/_examples/beginner/configuration/from-toml-file/main.go
new file mode 100644
index 00000000..c5b22d2c
--- /dev/null
+++ b/_examples/beginner/configuration/from-toml-file/main.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+)
+
+func main() {
+ app := iris.New()
+
+ // [...]
+
+ // Good when you have two configurations, one for development and a different one for production use.
+ app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.TOML("./configs/iris.tml")))
+
+ // or before run:
+ // app.Configure(iris.WithConfiguration(iris.TOML("./configs/iris.tml")))
+ // app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/configuration/from-yaml-file/configs/iris.yml b/_examples/beginner/configuration/from-yaml-file/configs/iris.yml
new file mode 100644
index 00000000..e402d414
--- /dev/null
+++ b/_examples/beginner/configuration/from-yaml-file/configs/iris.yml
@@ -0,0 +1,7 @@
+DisableTray: true
+DisablePathCorrection: false
+EnablePathEscape: false
+FireMethodNotAllowed: true
+DisableBodyConsumptionOnUnmarshal: true
+TimeFormat: Mon, 01 Jan 2006 15:04:05 GMT
+Charset: UTF-8
\ No newline at end of file
diff --git a/_examples/beginner/configuration/from-yaml-file/main.go b/_examples/beginner/configuration/from-yaml-file/main.go
new file mode 100644
index 00000000..930ca8e6
--- /dev/null
+++ b/_examples/beginner/configuration/from-yaml-file/main.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+)
+
+func main() {
+ app := iris.New()
+
+ // [...]
+
+ // Good when you have two configurations, one for development and a different one for production use.
+ app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.YAML("./configs/iris.yml")))
+
+ // or before run:
+ // app.Configure(iris.WithConfiguration(iris.YAML("./configs/iris.yml")))
+ // app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/configuration/functional/main.go b/_examples/beginner/configuration/functional/main.go
new file mode 100644
index 00000000..e0d2bb3b
--- /dev/null
+++ b/_examples/beginner/configuration/functional/main.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+)
+
+func main() {
+ app := iris.New()
+
+ // [...]
+
+ // Good when you want to change some of the configuration's field.
+ // I use that method :)
+ app.Run(iris.Addr(":8080"), iris.WithoutBanner, iris.WithTray, iris.WithCharset("UTF-8"))
+
+ // or before run:
+ // app.Configure(iris.WithoutBanner, iris.WithTray, iris.WithCharset("UTF-8"))
+ // app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/convert-handlers/negroni-like/main.go b/_examples/beginner/convert-handlers/negroni-like/main.go
new file mode 100644
index 00000000..c4a1f973
--- /dev/null
+++ b/_examples/beginner/convert-handlers/negroni-like/main.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/core/handlerconv"
+)
+
+func main() {
+ app := iris.New()
+ irisMiddleware := handlerconv.FromStdWithNext(negronilikeTestMiddleware)
+ app.Use(irisMiddleware)
+
+ // Method GET: http://localhost:8080/
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML(" Home
")
+ // this will print an error,
+ // this route's handler will never be executed because the middleware's criteria not passed.
+ })
+
+ // Method GET: http://localhost:8080/ok
+ app.Get("/ok", func(ctx context.Context) {
+ ctx.Writef("Hello world!")
+ // this will print "OK. Hello world!".
+ })
+
+ // http://localhost:8080
+ // http://localhost:8080/ok
+ app.Run(iris.Addr(":8080"))
+}
+
+func negronilikeTestMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
+ if r.URL.Path == "/ok" && r.Method == "GET" {
+ w.Write([]byte("OK. "))
+ next(w, r) // go to the next route's handler
+ return
+ }
+ // else print an error and do not forward to the route's handler.
+ w.WriteHeader(iris.StatusBadRequest)
+ w.Write([]byte("Bad request"))
+}
diff --git a/_examples/beginner/convert-handlers/nethttp/main.go b/_examples/beginner/convert-handlers/nethttp/main.go
new file mode 100644
index 00000000..995d67b5
--- /dev/null
+++ b/_examples/beginner/convert-handlers/nethttp/main.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/core/handlerconv"
+)
+
+func main() {
+ app := iris.New()
+ irisMiddleware := handlerconv.FromStd(nativeTestMiddleware)
+ app.Use(irisMiddleware)
+
+ // Method GET: http://localhost:8080/
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML("Home")
+ })
+
+ // Method GET: http://localhost:8080/ok
+ app.Get("/ok", func(ctx context.Context) {
+ ctx.HTML("Hello world!")
+ })
+
+ // http://localhost:8080
+ // http://localhost:8080/ok
+ app.Run(iris.Addr(":8080"))
+}
+
+func nativeTestMiddleware(w http.ResponseWriter, r *http.Request) {
+ println("Request path: " + r.URL.Path)
+}
diff --git a/_examples/intermediate/e-mail/main.go b/_examples/beginner/e-mail/main.go
similarity index 55%
rename from _examples/intermediate/e-mail/main.go
rename to _examples/beginner/e-mail/main.go
index f17cf0fa..9ee65ec0 100644
--- a/_examples/intermediate/e-mail/main.go
+++ b/_examples/beginner/e-mail/main.go
@@ -4,20 +4,16 @@ import (
"bytes"
"github.com/kataras/go-mailer"
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/view"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
+
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/view"
)
func main() {
app := iris.New()
- // output startup banner and error logs on os.Stdout
- app.Adapt(iris.DevLogger())
- // set the router, you can choose gorillamux too
- app.Adapt(httprouter.New())
- // set a root for our templates
- app.Adapt(view.HTML("./templates", ".html"))
+ app.AttachView(view.HTML("./templates", ".html"))
// change these to your own settings
cfg := mailer.Config{
@@ -38,31 +34,40 @@ func main() {
//mailService.Send("iris e-mail test subject", "outside of context before server's listen!", to...)
//inside handler
- app.Get("/send", func(ctx *iris.Context) {
+ app.Get("/send", func(ctx context.Context) {
content := `Hello From Iris web framework
This is the rich message body `
err := mailService.Send("iris e-mail just t3st subject", content, to...)
if err != nil {
- ctx.HTML(200, " Problem while sending the e-mail: "+err.Error())
+ ctx.HTML(" Problem while sending the e-mail: " + err.Error())
} else {
- ctx.HTML(200, " SUCCESS
")
+ ctx.HTML(" SUCCESS
")
}
})
// send a body by template
- app.Get("/send/template", func(ctx *iris.Context) {
- // we will not use ctx.Render
+ app.Get("/send/template", func(ctx context.Context) {
+ // we will not use ctx.View
// because we don't want to render to the client
// we need the templates' parsed result as raw bytes
// so we make use of the bytes.Buffer which is an io.Writer
- // which being expected on app.Render parameter first.
+ // which being expected on app.View parameter first.
//
- // the rest of the parameters are the same and the behavior is the same as ctx.Render,
+ // the rest of the parameters are the same and the behavior is the same as ctx.View,
// except the 'where to render'
buff := &bytes.Buffer{}
- app.Render(buff, "body.html", iris.Map{
+ // View executes and writes the result of a template file to the writer.
+ //
+ // First parameter is the writer to write the parsed template.
+ // Second parameter is the relative, to templates directory, template filename, including extension.
+ // Third parameter is the layout, can be empty string.
+ // Forth parameter is the bindable data to the template, can be nil.
+ //
+ // Use context.View to render templates to the client instead.
+ // Returns an error on failure, otherwise nil.
+ app.View(buff, "body.html", "", context.Map{
"Message": " his is the rich message body sent by a template!!",
"Footer": "The footer of this e-mail!",
})
@@ -71,10 +76,12 @@ func main() {
err := mailService.Send("iris e-mail just t3st subject", content, to...)
if err != nil {
- ctx.HTML(iris.StatusOK, " Problem while sending the e-mail: "+err.Error())
+ ctx.StatusCode(iris.StatusBadRequest)
+ ctx.HTML(" Sent failed with error: " + err.Error())
} else {
- ctx.HTML(iris.StatusOK, " SUCCESS
")
+ ctx.HTML(" SUCCESS
")
}
})
- app.Listen(":8080")
+
+ app.Run(iris.Addr(":8080"))
}
diff --git a/_examples/intermediate/e-mail/templates/mail_body.html b/_examples/beginner/e-mail/templates/mail_body.html
similarity index 100%
rename from _examples/intermediate/e-mail/templates/mail_body.html
rename to _examples/beginner/e-mail/templates/mail_body.html
diff --git a/_examples/beginner/favicon/main.go b/_examples/beginner/favicon/main.go
index 14341a12..0525aa87 100644
--- a/_examples/beginner/favicon/main.go
+++ b/_examples/beginner/favicon/main.go
@@ -1,23 +1,25 @@
package main
import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
)
func main() {
app := iris.New()
- app.Adapt(httprouter.New())
- // This will serve the ./static/favicons/iris_favicon_32_32.ico to: localhost:8080/favicon.ico
- app.Favicon("./static/favicons/iris_favicon_32_32.ico")
- // app.Favicon("./static/favicons/iris_favicon_32_32.ico", "/favicon_32_32.ico")
- // This will serve the ./static/favicons/iris_favicon_32_32.ico to: localhost:8080/favicon_32_32.ico
+ // This will serve the ./static/favicons/iris_favicon_48_48.ico to: localhost:8080/favicon.ico
+ app.Favicon("./static/favicons/iris_favicon_48_48.ico")
- app.Get("/", func(ctx *iris.Context) {
- ctx.HTML(iris.StatusOK, `You should see the favicon now at the side of your browser,
- if not, please refresh or clear the browser's cache.`)
- })
+ // app.Favicon("./static/favicons/iris_favicon_48_48.ico", "/favicon_48_48.ico")
+ // This will serve the ./static/favicons/iris_favicon_48_48.ico to: localhost:8080/favicon_48_48.ico
- app.Listen(":8080")
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML(` press here to see the favicon.ico.
+ At some browsers like chrome, it should be visible at the top-left side of the browser's window,
+ because some browsers make requests to the /favicon.ico automatically,
+ so Iris serves your favicon in that path too (you can change it).`)
+ }) // if favicon doesn't show to you, try to clear your browser's cache.
+
+ app.Run(iris.Addr(":8080"))
}
diff --git a/_examples/beginner/favicon/static/favicons/iris_favicon_32_32.ico b/_examples/beginner/favicon/static/favicons/iris_favicon_32_32.ico
deleted file mode 100644
index 4dd556e1..00000000
Binary files a/_examples/beginner/favicon/static/favicons/iris_favicon_32_32.ico and /dev/null differ
diff --git a/_examples/beginner/favicon/static/favicons/iris_favicon_48_48.ico b/_examples/beginner/favicon/static/favicons/iris_favicon_48_48.ico
new file mode 100644
index 00000000..c370da51
Binary files /dev/null and b/_examples/beginner/favicon/static/favicons/iris_favicon_48_48.ico differ
diff --git a/_examples/beginner/file-logger/main.go b/_examples/beginner/file-logger/main.go
index 0150fa43..738e9ded 100644
--- a/_examples/beginner/file-logger/main.go
+++ b/_examples/beginner/file-logger/main.go
@@ -1,63 +1,49 @@
package main
import (
- "log"
"os"
+ "time"
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
)
-var myLogFile *os.File
+// get a filename based on the date, file logs works that way the most times
+// but these are just a sugar, you can directly attach a new file logger with .AttachLogger(io.Writer)
+func todayFilename() string {
+ today := time.Now().Format("Jan 02 2006")
+ return today + ".txt"
+}
-func init() {
- // open an output file
- f, err := os.Create("logs.txt")
+func newLogFile() *os.File {
+ filename := todayFilename()
+ // open an output file, this will append to the today's file if server restarted.
+ f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
- myLogFile = f
-}
-func myFileLogger() iris.LoggerPolicy {
-
- // you can use a *File or an io.Writer,
- // we want to log with timestamps so we use the log.New.
- myLogger := log.New(myLogFile, "", log.LstdFlags)
-
- // the logger is just a func,
- // will be used in runtime
- return func(mode iris.LogMode, message string) {
- // optionally, check for production or development log message mode
- // two modes: iris.ProdMode and iris.DevMode
- if mode == iris.ProdMode {
- // log only production-mode log messages
- myLogger.Println(message)
- }
- }
+ return f
}
func main() {
- // close the log file on exit application
- // when panic or iris exited by interupt event or manually by Shutdown.
- defer func() {
- if err := myLogFile.Close(); err != nil {
- panic(err)
- }
- }()
+ f := newLogFile()
+ defer f.Close()
app := iris.New()
- app.Adapt(myFileLogger())
- app.Adapt(httprouter.New())
-
- app.Get("/", func(ctx *iris.Context) {
- // for the sake of simplicity, in order see the logs at the ./logs.txt:
- app.Log(iris.ProdMode, "You have requested: http://localhost/8080"+ctx.Path())
+ // attach the file as logger, remember, iris' app logger is just an io.Writer.
+ app.AttachLogger(f)
+ app.Get("/", func(ctx context.Context) {
+ // for the sake of simplicity, in order see the logs at the ./_today_.txt
+ ctx.Application().Log("Request: %s\r\n", ctx.Path())
ctx.Writef("hello")
})
- // open http://localhost:8080
- // and watch the ./logs.txt file
- app.Listen(":8080")
+ // navigate to http://localhost:8080
+ // and open the ./logs.txt file
+ if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner); err != nil {
+ app.Log("Shutdown with error: %v", err)
+
+ }
}
diff --git a/_examples/beginner/file-server/assets/css/styles.css b/_examples/beginner/file-server/assets/css/main.css
similarity index 100%
rename from _examples/beginner/file-server/assets/css/styles.css
rename to _examples/beginner/file-server/assets/css/main.css
diff --git a/_examples/beginner/file-server/main.go b/_examples/beginner/file-server/main.go
index 08d51648..bc7b8f1f 100644
--- a/_examples/beginner/file-server/main.go
+++ b/_examples/beginner/file-server/main.go
@@ -1,16 +1,16 @@
package main
import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
+ "github.com/kataras/iris"
)
func main() {
app := iris.New()
- app.Adapt(httprouter.New())
+
// first parameter is the request path
// second is the operating system directory
app.StaticWeb("/static", "./assets")
- app.Listen(":8080")
+ // http://localhost:8080/static/css/main.css
+ app.Run(iris.Addr(":8080"))
}
diff --git a/_examples/beginner/hello-world/main.go b/_examples/beginner/hello-world/main.go
deleted file mode 100644
index 8ab1af6e..00000000
--- a/_examples/beginner/hello-world/main.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-func main() {
- app := iris.New()
- // Adapt the "httprouter", faster,
- // but it has limits on named path parameters' validation,
- // you can adapt "gorillamux" if you need regexp path validation!
- app.Adapt(httprouter.New())
-
- app.HandleFunc("GET", "/", func(ctx *iris.Context) {
- ctx.Writef("hello world\n")
- })
-
- app.Listen(":8080")
-}
diff --git a/_examples/beginner/http-errors/main.go b/_examples/beginner/http-errors/main.go
new file mode 100644
index 00000000..8647c34c
--- /dev/null
+++ b/_examples/beginner/http-errors/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+)
+
+func main() {
+ app := iris.New()
+
+ app.OnErrorCode(iris.StatusInternalServerError, func(ctx context.Context) {
+ ctx.HTML("Message: " + ctx.Values().GetString("message") + "")
+ })
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML(`Click here to fire the 500 status code`)
+ })
+
+ app.Get("/my500", func(ctx context.Context) {
+ ctx.Values().Set("message", "this is the error message")
+ ctx.StatusCode(500)
+ })
+
+ app.Get("/u/{firstname:alphabetical}", func(ctx context.Context) {
+ ctx.Writef("Hello %s", ctx.Values().GetString("firstname"))
+ })
+
+ app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/listen-letsencrypt/main.go b/_examples/beginner/listen-letsencrypt/main.go
deleted file mode 100644
index 782af887..00000000
--- a/_examples/beginner/listen-letsencrypt/main.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Package main provide one-line integration with letsencrypt.org
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-func main() {
- app := iris.New()
- // output startup banner and error logs on os.Stdout
- app.Adapt(iris.DevLogger())
- // set the router, you can choose gorillamux too
- app.Adapt(httprouter.New())
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Writef("Hello from SECURE SERVER!")
- })
-
- app.Get("/test2", func(ctx *iris.Context) {
- ctx.Writef("Welcome to secure server from /test2!")
- })
-
- app.Get("/redirect", func(ctx *iris.Context) {
- ctx.Redirect("/test2")
- })
-
- // This will provide you automatic certification & key from letsencrypt.org's servers
- // it also starts a second 'http://' server which will redirect all 'http://$PATH' requests to 'https://$PATH'
-
- // NOTE: may not work on local addresses like this,
- // use it on a real domain, because
- // it uses the "golang.org/x/crypto/acme/autocert" package.
- app.ListenLETSENCRYPT("localhost:443")
-}
diff --git a/_examples/beginner/listen-tls/main.go b/_examples/beginner/listen-tls/main.go
deleted file mode 100644
index fb460164..00000000
--- a/_examples/beginner/listen-tls/main.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-const host = "127.0.0.1:443"
-
-func main() {
- app := iris.New()
- // output startup banner and error logs on os.Stdout
- app.Adapt(iris.DevLogger())
- // set the router, you can choose gorillamux too
- app.Adapt(httprouter.New())
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Writef("Hello from the SECURE server")
- })
-
- app.Get("/mypath", func(ctx *iris.Context) {
- ctx.Writef("Hello from the SECURE server on path /mypath")
- })
-
- // start a secondary server (HTTP) on port 80, this is a non-blocking func
- // redirects all http to the main server which is tls/ssl on port :443
-
- iris.Proxy(":80", "https://"+host)
- // start the MAIN server (HTTPS) on port 443, this is a blocking func
- app.ListenTLS(host, "mycert.cert", "mykey.key")
-
- // now if you navigate to http://127.0.0.1/mypath it will
- // send you back to https://127.0.0.1:443/mypath (https://127.0.0.1/mypath)
- //
- // go to the listen-letsencrypt example to view how you can integrate your server
- // to get automatic certification and key from the letsencrypt.org 's servers.
-}
diff --git a/_examples/beginner/listen-unix/main.go b/_examples/beginner/listen-unix/main.go
deleted file mode 100644
index 68632b7c..00000000
--- a/_examples/beginner/listen-unix/main.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package main
-
-import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
-)
-
-const host = "127.0.0.1:443"
-
-func main() {
- app := iris.New()
- // output startup banner and error logs on os.Stdout
- app.Adapt(iris.DevLogger())
- // set the router, you can choose gorillamux too
- app.Adapt(httprouter.New())
-
- app.Get("/", func(ctx *iris.Context) {
- ctx.Writef("Hello from the server")
- })
-
- app.ListenUNIX("/tmp/srv.sock", 0666)
-}
diff --git a/_examples/beginner/listening/custom-listener/main.go b/_examples/beginner/listening/custom-listener/main.go
new file mode 100644
index 00000000..a8a77a27
--- /dev/null
+++ b/_examples/beginner/listening/custom-listener/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "net"
+
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+)
+
+func main() {
+ app := iris.New()
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.Writef("Hello from the server")
+ })
+
+ app.Get("/mypath", func(ctx context.Context) {
+ ctx.Writef("Hello from %s", ctx.Path())
+ })
+
+ // create any custom tcp listener, unix sock file or tls tcp listener.
+ l, err := net.Listen("tcp4", ":8080")
+ if err != nil {
+ panic(err)
+ }
+
+ // use of the custom listener
+ app.Run(iris.Listener(l))
+}
diff --git a/_examples/beginner/listening/listen-addr/main.go b/_examples/beginner/listening/listen-addr/main.go
new file mode 100644
index 00000000..1d5b8ce0
--- /dev/null
+++ b/_examples/beginner/listening/listen-addr/main.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+)
+
+func main() {
+ app := iris.New()
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML("Index /
")
+ })
+
+ if err := app.Run(iris.Addr(":8080")); err != nil {
+ panic(err)
+ }
+
+}
diff --git a/_examples/beginner/listening/listen-letsencrypt/main.go b/_examples/beginner/listening/listen-letsencrypt/main.go
new file mode 100644
index 00000000..9e6ecd91
--- /dev/null
+++ b/_examples/beginner/listening/listen-letsencrypt/main.go
@@ -0,0 +1,31 @@
+// Package main provide one-line integration with letsencrypt.org
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+)
+
+func main() {
+ app := iris.New()
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.Writef("Hello from SECURE SERVER!")
+ })
+
+ app.Get("/test2", func(ctx context.Context) {
+ ctx.Writef("Welcome to secure server from /test2!")
+ })
+
+ app.Get("/redirect", func(ctx context.Context) {
+ ctx.Redirect("/test2")
+ })
+
+ // If http to https auto-redirect is one of your needs
+ // please look the code inside iris_deprecateed.go.ListenLETSENCRYPT to do it manually.
+
+ // NOTE: This may not work on local addresses like this,
+ // use it on a real domain, because
+ // it uses the "golang.org/x/crypto/acme/autocert" package.
+ app.Run(iris.AutoTLS("localhost:443"))
+}
diff --git a/_examples/beginner/listening/listen-tls/main.go b/_examples/beginner/listening/listen-tls/main.go
new file mode 100644
index 00000000..74e5ffa1
--- /dev/null
+++ b/_examples/beginner/listening/listen-tls/main.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+)
+
+func main() {
+ app := iris.New()
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.Writef("Hello from the SECURE server")
+ })
+
+ app.Get("/mypath", func(ctx context.Context) {
+ ctx.Writef("Hello from the SECURE server on path /mypath")
+ })
+
+ // start the server (HTTPS) on port 443, this is a blocking func
+ app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key"))
+}
diff --git a/_examples/beginner/listen-tls/mycert.cert b/_examples/beginner/listening/listen-tls/mycert.cert
similarity index 100%
rename from _examples/beginner/listen-tls/mycert.cert
rename to _examples/beginner/listening/listen-tls/mycert.cert
diff --git a/_examples/beginner/listen-tls/mykey.key b/_examples/beginner/listening/listen-tls/mykey.key
similarity index 100%
rename from _examples/beginner/listen-tls/mykey.key
rename to _examples/beginner/listening/listen-tls/mykey.key
diff --git a/_examples/beginner/listening/listen-unix/main.go b/_examples/beginner/listening/listen-unix/main.go
new file mode 100644
index 00000000..b699b136
--- /dev/null
+++ b/_examples/beginner/listening/listen-unix/main.go
@@ -0,0 +1,17 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/core/nettools"
+)
+
+func main() {
+ app := iris.New()
+
+ l, err := nettools.UNIX("/tmpl/srv.sock", 0666) // see its code to see how you can manually create a new file listener, it's easy.
+ if err != nil {
+ panic(err)
+ }
+
+ app.Run(iris.Listener(l))
+}
diff --git a/_examples/beginner/overview/main.go b/_examples/beginner/overview/main.go
new file mode 100644
index 00000000..aca8f688
--- /dev/null
+++ b/_examples/beginner/overview/main.go
@@ -0,0 +1,117 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/view"
+)
+
+// User is just a bindable object structure.
+type User struct {
+ Username string `json:"username"`
+ Firstname string `json:"firstname"`
+ Lastname string `json:"lastname"`
+ City string `json:"city"`
+ Age int `json:"age"`
+}
+
+func main() {
+ app := iris.New()
+
+ // Define templates using the std html/template engine.
+ // Parse and load all files inside "./views" folder with ".html" file extension.
+ // Reload the templates on each request (development mode).
+ app.AttachView(view.HTML("./views", ".html").Reload(true))
+
+ // Regster custom handler for specific http errors.
+ app.OnErrorCode(iris.StatusInternalServerError, func(ctx context.Context) {
+ // .Values are used to communicate between handlers, middleware.
+ errMessage := ctx.Values().GetString("error")
+ if errMessage != "" {
+ ctx.Writef("Internal server error: %s", errMessage)
+ return
+ }
+
+ ctx.Writef("(Unexpected) internal server error")
+ })
+
+ app.Use(func(ctx context.Context) {
+ ctx.Application().Log("Begin request for path: %s", ctx.Path())
+ ctx.Next()
+ })
+
+ // app.Done(func(ctx context.Context) {]})
+
+ // Method POST: http://localhost:8080/decode
+ app.Post("/decode", func(ctx context.Context) {
+ var user User
+ ctx.ReadJSON(&user)
+ ctx.Writef("%s %s is %d years old and comes from %s", user.Firstname, user.Lastname, user.Age, user.City)
+ })
+
+ // Method GET: http://localhost:8080/encode
+ app.Get("/encode", func(ctx context.Context) {
+ doe := User{
+ Username: "Johndoe",
+ Firstname: "John",
+ Lastname: "Doe",
+ City: "Neither FBI knows!!!",
+ Age: 25,
+ }
+
+ ctx.JSON(doe)
+ })
+
+ // Method GET: http://localhost:8080/profile/anytypeofstring
+ app.Get("/profile/{username:string}", profileByUsername)
+
+ usersRoutes := app.Party("/users", logThisMiddleware)
+ {
+ // Method GET: http://localhost:8080/users/42
+ usersRoutes.Get("/{id:int min(1)}", getUserByID)
+ // Method POST: http://localhost:8080/users/create
+ usersRoutes.Post("/create", createUser)
+ }
+
+ // Listen for incoming HTTP/1.x & HTTP/2 clients on localhost port 8080.
+ app.Run(iris.Addr(":8080"), iris.WithCharset("UTF-8"))
+}
+
+func logThisMiddleware(ctx context.Context) {
+ ctx.Application().Log("Path: %s | IP: %s", ctx.Path(), ctx.RemoteAddr())
+
+ // .Next is required to move forward to the chain of handlers,
+ // if missing then it stops the execution at this handler.
+ ctx.Next()
+}
+
+func profileByUsername(ctx context.Context) {
+ // .Params are used to get dynamic path parameters.
+ username := ctx.Params().Get("username")
+ ctx.ViewData("Username", username)
+ // renders "./views/users/profile.html"
+ // with {{ .Username }} equals to the username dynamic path parameter.
+ ctx.View("users/profile.html")
+}
+
+func getUserByID(ctx context.Context) {
+ userID := ctx.Params().Get("id") // Or convert directly using: .Values().GetInt/GetInt64 etc...
+ // your own db fetch here instead of user :=...
+ user := User{Username: "username" + userID}
+
+ ctx.XML(user)
+}
+
+func createUser(ctx context.Context) {
+ var user User
+ err := ctx.ReadForm(&user)
+ if err != nil {
+ ctx.Values().Set("error", "creating user, read and parse form failed. "+err.Error())
+ ctx.StatusCode(iris.StatusInternalServerError)
+ return
+ }
+ // renders "./views/users/create_verification.html"
+ // with {{ . }} equals to the User object, i.e {{ .Username }} , {{ .Firstname}} etc...
+ ctx.ViewData("", user)
+ ctx.View("users/create_verification.html")
+}
diff --git a/_examples/beginner/overview/views/users/create_verification.html b/_examples/beginner/overview/views/users/create_verification.html
new file mode 100644
index 00000000..a1981380
--- /dev/null
+++ b/_examples/beginner/overview/views/users/create_verification.html
@@ -0,0 +1,22 @@
+
+ Create verification
+
+ Create Verification
+
+
+ Username |
+ Firstname |
+ Lastname |
+ City |
+ Age |
+
+
+ {{ .Username }} |
+ {{ .Firstname }} |
+ {{ .Lastname }} |
+ {{ .City }} |
+ {{ .Age }} |
+
+
+
+
diff --git a/_examples/beginner/overview/views/users/profile.html b/_examples/beginner/overview/views/users/profile.html
new file mode 100644
index 00000000..7b3ceebc
--- /dev/null
+++ b/_examples/beginner/overview/views/users/profile.html
@@ -0,0 +1,7 @@
+
+ Profile page
+
+ Profile
+ {{ .Username }}
+
+
diff --git a/_examples/beginner/pprof/main.go b/_examples/beginner/pprof/main.go
new file mode 100644
index 00000000..bf688f87
--- /dev/null
+++ b/_examples/beginner/pprof/main.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+
+ "github.com/kataras/iris/middleware/pprof"
+)
+
+func main() {
+ app := iris.New()
+
+ app.Get("/", func(ctx context.Context) {
+ ctx.HTML(" Please click here")
+ })
+
+ app.Any("/debug/pprof/{action:path}", pprof.New())
+ // ___________
+ app.Run(iris.Addr(":8080"))
+}
diff --git a/_examples/beginner/read-form/main.go b/_examples/beginner/read-form/main.go
index f659e195..7a571728 100644
--- a/_examples/beginner/read-form/main.go
+++ b/_examples/beginner/read-form/main.go
@@ -2,9 +2,9 @@
package main
import (
- "gopkg.in/kataras/iris.v6"
- "gopkg.in/kataras/iris.v6/adaptors/httprouter"
- "gopkg.in/kataras/iris.v6/adaptors/view"
+ "github.com/kataras/iris"
+ "github.com/kataras/iris/context"
+ "github.com/kataras/iris/view"
)
type Visitor struct {
@@ -15,28 +15,27 @@ type Visitor struct {
func main() {
app := iris.New()
- // output startup banner and error logs on os.Stdout
- app.Adapt(iris.DevLogger())
- // set the router, you can choose gorillamux too
- app.Adapt(httprouter.New())
- // set the view html template engine
- app.Adapt(view.HTML("./templates", ".html"))
- app.Get("/", func(ctx *iris.Context) {
- if err := ctx.Render("form.html", nil); err != nil {
- ctx.Log(iris.DevMode, err.Error())
+ // set the view html template engine
+ app.AttachView(view.HTML("./templates", ".html").Reload(true))
+
+ app.Get("/", func(ctx context.Context) {
+ if err := ctx.View("form.html"); err != nil {
+ ctx.StatusCode(iris.StatusInternalServerError)
+ ctx.WriteString(err.Error())
}
})
- app.Post("/form_action", func(ctx *iris.Context) {
+ app.Post("/form_action", func(ctx context.Context) {
visitor := Visitor{}
err := ctx.ReadForm(&visitor)
if err != nil {
- ctx.Log(iris.DevMode, "Error when reading form: "+err.Error())
+ ctx.StatusCode(iris.StatusInternalServerError)
+ ctx.WriteString(err.Error())
}
ctx.Writef("Visitor: %#v", visitor)
})
- app.Listen(":8080")
+ app.Run(iris.Addr(":8080"))
}
diff --git a/_examples/beginner/read-form/templates/form.html b/_examples/beginner/read-form/templates/form.html
index af68b075..7f85b962 100644
--- a/_examples/beginner/read-form/templates/form.html
+++ b/_examples/beginner/read-form/templates/form.html
@@ -4,13 +4,16 @@