Elixir v1.0.4 ships with two new important options for new projects. For projects generated prior to Elixir 1.0.4, add these options to your project
entries in mix.exs
:
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod
A new phoenix.digest
task is now inluded which digests and compress static files and can be used during deploy. It also integrates with the static_path
helper to render the proper asset paths from the manifest.
A new configuration called cache_static_manifest
was added which should be set to "priv/static/manifest.json" in production which will preload the manifest file generated by the mix task in order to point to the digested files when generating static paths, ie:
# config/prod.exs
config :my_app, MyApp.Endpoint,
...
cache_static_manifest: "priv/static/manifest.json"
Usage:
mix phoenix.digest
mix phoenix.digest priv/static -o /www/public
The first argument is the path where the static files are located. The
-o
option indicates the path that will be used to save the digested and
compressed files.
If no path is given, it will use priv/static
as the input and output path.
The output folder will contain:
- the original file
- a compressed file with gzip
- a file containing the original file name and its digest
- a compressed file containing the file name and its digest
- a manifest file
Example of generated files:
- application.js.erb
- application.js.erb.gz
- application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb
- application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb.gz
- manifest.json
Live reload has been updated to reload css changes without refreshing the browser. We also fixed a few bugs for windows users. Simply run mix deps.update phoenix_live_reload
or bump the version in your mix.exs
:
...
{:phoenix_live_reload, "~> 0.3.3"},
Phoenix includes new test helpers for easily testing your endpoints, routers, controllers. See the test docs for example usage.
Code that used to require multiple assertions and manually wiring up the %Conn{}
structs can now simply call into the endpoint stack. Phoenix generates tests files for these features for new projects. Existing projects can get up to speed by the following steps:
-
$ mkdir test/support
-
Save the following listing as
test/support/conn_case.ex
and replaceMyApp
with your app module. Note: the Ecto bits of this step can be excluded if not using Ecto.
defmodule MyApp.ConnCase do
@moduledoc """
This module defines the test case to be used by
tests that require setting up a connection.
Such tests rely on `Phoenix.ConnTest` and also
imports other functionality to make it easier
to build and query models.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
inside a transaction which is reset at the beginning
of the test unless the test case is marked as async.
"""
use ExUnit.CaseTemplate
using do
quote do
# Import conveniences for testing with connections
use Phoenix.ConnTest
# Alias the data repository and import query/model functions
alias MyApp.Repo
import Ecto.Model
import Ecto.Query, only: [from: 2]
# Import URL helpers from the router
import MyApp.Router.Helpers
# The default endpoint for testing
@endpoint MyApp.Endpoint
end
end
setup tags do
unless tags[:async] do
Ecto.Adapters.SQL.restart_test_transaction(MyApp.Repo, [])
end
:ok
end
end
- Save the following listing as
test/support/model_case.ex
and replaceMyApp
with your app module. Note: this step can be skipped/modified if not using Ecto.
defmodule MyApp.ModelCase do
@moduledoc """
This module defines the test case to be used by
model tests.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
inside a transaction which is reset at the beginning
of the test unless the test case is marked as async.
"""
use ExUnit.CaseTemplate
using do
quote do
# Alias the data repository and import query/model functions
alias MyApp.Repo
import Ecto.Model
import Ecto.Query, only: [from: 2]
end
end
setup tags do
unless tags[:async] do
Ecto.Adapters.SQL.restart_test_transaction(MyApp.Repo, [])
end
:ok
end
end
terminate/2
in your channels is now always called when the channel server shuts down. Leaving the channel or closing the client will now trigger terminate on the channel, regardless of traping exits, with reasons {:shutdown, :left}
and {:shutdown, :closed}
respectively.
New functions render_many/4
and render_one/4
have been added to make it easier to render collection and optional data. See the docs for example usage
render_existing/3
has been added to allow dynamic rendering of templates that may or may not exist. From the docs:
Consider the case where the application layout allows views to dynamically render a section of script tags in the head of the document. Some views may wish to inject certain scripts, while others will not.
<head>
<%= render_existing view_module(@conn), "scripts.html", assigns %>
</head>
Then the module for the @inner
view can decide to provide scripts with
either a precompiled template, or by implementing the function directly, ie:
def render("scripts.html", _assigns) do
"<script src=\"...\">"
end
In some cases, you might need render based on the template from the controller.
For these cases, Phoenix.Controller.controller_template/1
can pair with
render_existing/3
for per-template based content, ie:
<head>
<%= render_existing view_module(@conn), "scripts." <> controller_template(@conn), assigns %>
</head>
def render("scripts.show.html", _assigns) do
"<script src=\"...\">"
end
def render("scripts.index.html", _assigns) do
"<script src=\"...\">"
end