Weber - is a MVC Web framework for Elixir.
- MVC web framework;
- Project generation;
- Json generation with exjson;
- Websocket support;
- HTML generators;
- i18n support;
- Sessions support;
- Get and install Elixir from master.
- Clone this repository.
- Execute
mix deps.get
in the weber directory. - Execute
mix compile
in the weber directory. - Execute
MIX_ENV=test mix do deps.get, test
- Create new project with:
mix weber.new /home/user/testWebApp
Now go to the /home/user/testWebApp
and execute there: mix deps.get && mix compile
. Then you can try to run your testWeberApplication with:
./start.sh
and go to the http://localhost:8080/
For more details see in examples
directory and Weber's API.
Dir/File | Description |
---|---|
./start.sh | Startup script |
./lib/controllers | Directory with web controllers |
./lib/helpers | Helper functions |
./lib/models | Directory for models (ecto) |
./lib/views | Directory with EEx views |
./lib/app.ex | Application startup settings |
./lib/config.ex | Configuration file. |
./lib/route.ex | File with routes declaration |
./public | Directory for static files (css, js ....) |
Routing declaration is in route.ex
files:
@route on("/", :Simpletodo.Main, :action)
|> on("/add/:note", :Simpletodo.Main, :add)
Also on
supports following syntax:
@route on("/", "Simpletodo.Main#action")
|> on("/add/:note", "Simpletodo.Main#add")
It is @route
attribute which value is chain of on
and otherwise
functions with 3 parametes:
- Route path, can be binding (starts with ':' symbol);
- Module name of controller;
- Function name from this controller.
Every Weber's controller is just an elixir module, like:
defmodule Simpletodo.Main do
import Simplemodel
def action("GET", []) do
{:render, [project: "simpleTodo"], []}
end
def add("POST", [body: body]) do
new(body)
{:json, [response: "ok"], [{"Content-Type", "application/json"}]}
end
end
Every controller's action passes 2 parameters:
- HTTP method
- List of URL bindings
Controller can return:
{:render, [project: "simpleTodo"], [{"HttpHeaderName", "HttpHeaderValheaderVal"}]}
- Render views with the same name as controller and sends it to response.{:render_inline, "foo <%= bar %>", [bar: "baz"]}, []}
- Render inline template.{:file, path, headers}
- Send file in response.{:json, [response: "ok"], [{"HttpHeaderName", "HttpHeaderValheaderVal"}]}
- Weber convert keyword to json and sends it to response.{:redirect, "/main"}
- Redirect to other resource.{:text, data, headers}
- Sends plain text.{:nothing, ["Cache-Control", "no-cache"]}
- Sends empty response with status200
and headers.
Sometimes it is necessary for the request parameters in the controller. For this point can be used Weber.Http.Params
API.
defmodule Simplechat.Main.Login do
import Weber.Http.Params
def render_login("GET", []) do
# get body request
body = get_body()
#
# Do something with param
#
{:render, [project: "SimpleChat"], []}
end
end
If you need to get parameters from query string, it is easy to do with param/1
API. For example you got request for: /user?name=0xAX
, you can get name
parameter's value with:
defmodule Simplechat.Main.Login do
import Weber.Http.Params
def render_login("GET", []) do
name = param(:name)
#
# Do something with param
#
{:render, [project: "SimpleChat", name: name], []}
end
end
You can find the full API at the wiki.
Html helpers helps to generate html templates from elixir:
defmodule Simpletodo.Helper.MyHelper
import Weber.Helper.Html
# Generates <p>test</p>
def do_something do
tag(:p, "test")
end
# Generates <p class="class_test">test</p>
def do_something do
tag(:p, "test", [class: "class_test"])
end
# Generates <img src="path/to/file">
def do_something do
tag(:img, [src: "path/to/file"])
end
end
Tags with blocks
defmodule Simpletodo.Helper.MyHelper
import Weber.Helper.Html
# Generates <div id="test"><p>test</p></div>
def do_something do
tag(:div, [id: "test"]) do
tag(:p, "test")
end
end
end
Include view helper helps to include other views inside another.
Import in your controller.
import Weber.Helper
Your view.
<p>Test</p>
<%= include_view "test.html", [value: "value"]%>
You can include your static resources like javascript
, css
, favicon
or image
files with resource helpers:
#
# Generates: <script type="text/javascript" src="/static/test.js"></script>
script("/static/test.js")
# If no value is passed for src it defaults to "/public/application.js"
script()
#
# Generates: <link href="/static/test.css" rel="stylesheet" media="screen">
#
style("/static/test.css")
# If no value is passed for href it defaults to "/public/application.css"
style()
#
# Generates: <link href="/public/img/favicon.ico" rel="shortcut icon" type="image/png">
favicon("/public/img/favicon.ico")
# If no value is passed for href it defaults to "/public/img/favicon.ico"
favicon()
#
# Generates: <img src="/public/img/example.jpg" alt="Image" class="some-class" height="100" width="100">"
image("/public/img/example.jpg", [alt: "Image", class: "some-class", height: 100, width: 100])
You can handle websocket connection and incoming/outcoming websocket message in your controllers.
First of all you need to designate websocket controller in your config.ex
file in webserver:
section, like:
ws:
[ws_port: 8800,
ws_mod: :Handler
]
After it you must implement 3 callbacks in your controller like this:
defmodule Simplechat.Main.Chat do
def websocket_init(pid) do
#
# new websocket connection init
#
end
def websocket_message(pid, message) do
#
# handle incoming message here
#
end
def websocket_terminate(pid) do
#
# connection terminated
#
end
end
See Contributing.md