### Next steps when skipping dependency installation Source: https://phoenix.hexdocs.pm/up_and_running.md Shows the output when the user answers n to installing dependencies, prompting to cd into the project and run mix deps.get, then configure the database and start the server. ```console Fetch and install dependencies? [Yn] n We are almost there! The following steps are missing: $ cd hello $ mix deps.get Then configure your database in config/dev.exs and run: $ mix ecto.create Start your Phoenix app with: $ mix phx.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phx.server ``` -------------------------------- ### Install dependencies and next steps after mix phx.new Source: https://phoenix.hexdocs.pm/up_and_running.md Shows the output when the user answers Y to install dependencies, including running mix deps.get, mix assets.setup, and mix deps.compile, followed by the steps to configure the database, create it, and start the server. ```console Fetch and install dependencies? [Yn] Y * running mix deps.get * running mix assets.setup * running mix deps.compile We are almost there! The following steps are missing: $ cd hello Then configure your database in config/dev.exs and run: $ mix ecto.create Start your Phoenix app with: $ mix phx.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phx.server ``` -------------------------------- ### Phoenix.Endpoint.server?/2 example Source: https://phoenix.hexdocs.pm/Phoenix.Endpoint.html Shows how to check if an endpoint's web server is configured to start. Returns true when the server is configured. ```elixir iex> Phoenix.Endpoint.server?(:my_app, MyAppWeb.Endpoint) true ``` -------------------------------- ### PostControllerTest setup and index test Source: https://phoenix.hexdocs.pm/testing_controllers.html Example of the generated controller test file, showing the use of ConnCase, fixtures, module attributes, and a describe block for the index action. ```elixir defmodule HelloWeb.PostControllerTest do use HelloWeb.ConnCase import Hello.BlogFixtures @create_attrs %{body: "some body", title: "some title"} @update_attrs %{body: "some updated body", title: "some updated title"} @invalid_attrs %{body: nil, title: nil} describe "index" do test "lists all posts", %{conn: conn} do conn = get(conn, ~p"/posts") assert html_response(conn, 200) =~ "Listing Posts" end end ... ``` -------------------------------- ### Start Phoenix server with mix phx.server Source: https://phoenix.hexdocs.pm/json_and_apis.html Starts the Phoenix server for local development. ```shell $ mix phx.server ``` -------------------------------- ### put_view example Source: https://phoenix.hexdocs.pm/Phoenix.Controller.md Example call to put_view/2 with a keyword list mapping formats to view modules. ```elixir iex> put_view(conn, html: AppHTML, json: AppJSON) ``` -------------------------------- ### Router with API routes (lib/hello_web/router.ex) Source: https://phoenix.hexdocs.pm/json_and_apis.html Defines a Phoenix router with an API pipeline that accepts JSON and three routes: GET /, GET /:name, and POST /. This is the minimal setup for the examples. ```elixir defmodule HelloWeb.Router do use HelloWeb, :router pipeline :api do plug :accepts, ["json"] end scope "/api", HelloWeb do pipe_through :api get "/", HelloController, :show get "/:name", HelloController, :show post "/", HelloController, :show end end ``` -------------------------------- ### Curl requests for minimal example Source: https://phoenix.hexdocs.pm/json_and_apis.html Three curl commands that demonstrate how the minimal setup handles GET with path parameter, GET with query parameter, and POST with JSON body, all returning "Hello world!". ```bash $ curl http://localhost:4000/api/world $ curl http://localhost:4000/api?name=world $ curl -iX POST http://localhost:4000/api \ -H 'Content-Type: application/json' \ -d '{"name": "world"}' ``` -------------------------------- ### Example: bypass_through with router and GET request Source: https://phoenix.hexdocs.pm/Phoenix.ConnTest.html Example showing how to use bypass_through/2 with a router and a GET request to test an authentication plug in isolation. ```elixir conn = conn |> bypass_through(MyAppWeb.Router) |> get("/some_url") |> MyApp.RequireAuthentication.call([]) assert conn.halted ``` -------------------------------- ### mix phx.new hello_world example Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.New.md Creates a new Phoenix project named hello_world. Equivalent to specifying --module HelloWorld. ```shell $ mix phx.new hello_world ``` ```shell $ mix phx.new hello_world --module HelloWorld ``` -------------------------------- ### scope/3 example with host option Source: https://phoenix.hexdocs.pm/Phoenix.Router.html Example of defining a scope with path and host options, containing a GET route. ```elixir scope "/v1", host: "api." do get "/pages/:id", PageController, :show end ``` -------------------------------- ### Example: mix phx.new.ecto hello_ecto Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.New.Ecto.html Creates a new Ecto project named hello_ecto. This is equivalent to specifying --module HelloEcto. ```shell $ mix phx.new.ecto hello_ecto ``` -------------------------------- ### scope/4 example with alias and host Source: https://phoenix.hexdocs.pm/Phoenix.Router.html Example of defining a scope with path, alias, and host options, containing a GET route. ```elixir scope "/v1", API.V1, host: "api." do get "/pages/:id", PageController, :show end ``` -------------------------------- ### Provision a free database with gigalixir pg:create --free Source: https://phoenix.hexdocs.pm/gigalixir.md Creates a free tier database for your app. Run this command to provision a database at no cost. ```console $ gigalixir pg:create --free ``` -------------------------------- ### get/4 route example Source: https://phoenix.hexdocs.pm/Phoenix.Router.html Generates a route to handle a GET request to the given path. The example shows a typical route definition. ```elixir get("/events/:id", EventController, :action) ``` -------------------------------- ### Example product data after form submission Source: https://phoenix.hexdocs.pm/your_first_context.html Example output shown after submitting the product form with valid data, displaying the created product details. ```text Product created successfully. Title: Metaprogramming Elixir Description: Write Less Code, Get More Done (and Have Fun!) Price: 15.000000 Views: 0 ``` -------------------------------- ### Install Phoenix application generator with mix archive.install Source: https://phoenix.hexdocs.pm/installation.html Installs the phx_new archive, which provides the phx.new generator for creating new Phoenix applications. After installation, the generator is available for use in the next guide. ```shell $ mix archive.install hex phx_new ``` -------------------------------- ### Change into project directory Source: https://phoenix.hexdocs.pm/up_and_running.md Changes into the newly created hello directory before creating the database and starting the server. ```console $ cd hello ``` -------------------------------- ### sigil_p macro examples Source: https://phoenix.hexdocs.pm/Phoenix.VerifiedRoutes.md Examples of using the ~p sigil with route verification. Shows setup with use Phoenix.VerifiedRoutes, redirect usage, and HEEx link components with interpolated values. ```elixir use Phoenix.VerifiedRoutes, endpoint: MyAppWeb.Endpoint, router: MyAppWeb.Router redirect(to: ~p"/users/top") redirect(to: ~p"/users/#{@user}") ~H""" <.link href={~p"/users?page=#{@page}"}>profile <.link href={~p"/users?#{@params}"}>profile """ ``` -------------------------------- ### mix phx.new with explicit module name Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.New.html Equivalent to the previous example, but explicitly sets the module name to HelloWorld. ```shell $ mix phx.new hello_world --module HelloWorld ``` -------------------------------- ### Controller with show action (lib/hello_web/controllers/hello_controller.ex) Source: https://phoenix.hexdocs.pm/json_and_apis.html Defines a controller with a single `show` action that receives `conn` and `params` and renders the `:greet` template with the given params. ```elixir defmodule HelloWeb.HelloController do use HelloWeb, :controller def show(conn, params) do render(conn, :greet, params) end end ``` -------------------------------- ### Route definition: get "/users/:id", UserController, :show Source: https://phoenix.hexdocs.pm/Phoenix.Controller.md Example route that maps a GET request to the show action of UserController. This route causes the controller to be invoked as a plug. ```elixir get "/users/:id", UserController, :show ``` -------------------------------- ### mix phx.gen.html with --context-app option Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.Gen.Html.html Example command using the --context-app option to specify the context application. ```shell $ mix phx.gen.html Accounts User users --context-app my_app ``` -------------------------------- ### Example product details output Source: https://phoenix.hexdocs.pm/in_context_relationships.html Shows the expected output after saving a product with categories, including the categories list. ```text Title: Elixir Flashcards Description: Flash card set for the Elixir programming language Price: 5.000000 Views: 0 Categories: Education Books ``` -------------------------------- ### HTTP response for GET /api/urls Source: https://phoenix.hexdocs.pm/json_and_apis.html Example response showing a 200 status and empty JSON data array. ```http HTTP/1.1 200 OK cache-control: max-age=0, private, must-revalidate content-length: 11 content-type: application/json; charset=utf-8 date: Fri, 06 May 2022 21:22:42 GMT server: Cowboy x-request-id: Fuyg-wMl4S-hAfsAAAUk {"data":[]} ``` -------------------------------- ### Initialize Git repository Source: https://phoenix.hexdocs.pm/gigalixir.md Run these commands in the project directory to commit files to Git before deploying. ```console $ git init $ git add . $ git commit -m "Initial commit" ``` -------------------------------- ### mix phx.gen.html with --web flag Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.Gen.Html.html Example command using the --web flag to namespace the generated controller and HTML views. ```shell $ mix phx.gen.html Accounts User users --web Accounts ``` -------------------------------- ### Equivalent: mix phx.new.web hello_web --module HelloWeb Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.New.Web.md Shows the explicit module option equivalent to the default behavior of the previous example. ```shell $ mix phx.new.web hello_web --module HelloWeb ``` -------------------------------- ### Update aliases in mix.exs Source: https://phoenix.hexdocs.pm/asset_management.md Modify the aliases task to install npm packages during mix setup and use the new esbuild for assets.deploy. ```elixir defp aliases do [ setup: ["deps.get", "ecto.setup", "cmd --cd assets npm install"], ..., "assets.deploy": ["cmd --cd assets node build.js --deploy", "phx.digest"] ] end ``` -------------------------------- ### Create database with mix ecto.create Source: https://phoenix.hexdocs.pm/swapping_databases.md Run mix ecto.create to create the database for the Repo. The output confirms the database has been created. ```console $ mix ecto.create ``` -------------------------------- ### static_integrity/2 examples Source: https://phoenix.hexdocs.pm/Phoenix.VerifiedRoutes.md Shows how to call static_integrity/2 with a conn, socket, or endpoint module to get the integrity hash for a static asset. The output is a hex string. ```elixir iex> static_integrity(conn, "/assets/js/app.js") "813dfe33b5c7f8388bccaaa38eec8382" ``` ```elixir iex> static_integrity(socket, "/assets/js/app.js") "813dfe33b5c7f8388bccaaa38eec8382" ``` ```elixir iex> static_integrity(AppWeb.Endpoint, "/assets/js/app.js") "813dfe33b5c7f8388bccaaa38eec8382" ``` -------------------------------- ### Channel join and message handling example Source: https://phoenix.hexdocs.pm/js/index.html This example shows how to join a channel, listen for 'new_msg' events, push messages, and handle join responses with ok/error/timeout matches. It uses a chat room scenario with a room token for authorization. ```javascript let channel = socket.channel("room:123", {token: roomToken}) channel.on("new_msg", msg => console.log("Got message", msg) ) $input.onEnter( e => { channel.push("new_msg", {body: e.target.val}, 10000) .receive("ok", (msg) => console.log("created message", msg) ) .receive("error", (reasons) => console.log("create failed", reasons) ) .receive("timeout", () => console.log("Networking issue...") ) }) channel.join() .receive("ok", ({messages}) => console.log("catching up", messages) ) .receive("error", ({reason}) => console.log("failed join", reason) ) .receive("timeout", () => console.log("Networking issue. Still waiting...")) ``` -------------------------------- ### Add redirect_test route in lib/hello_web/router.ex Source: https://phoenix.hexdocs.pm/controllers.html Adds a GET route for /redirect_test that maps to PageController's redirect_test action. This route is required for the redirect example to work. ```elixir defmodule HelloWeb.Router do ... scope "/", HelloWeb do ... get "/", PageController, :home get "/redirect_test", PageController, :redirect_test ... end end ``` -------------------------------- ### Connect to PostgreSQL and list tables Source: https://phoenix.hexdocs.pm/ecto.html Shows how to connect to the hello_dev database and list relations to verify the users table and its sequence exist. ```shell $ psql -U postgres Type "help" for help. postgres=# \connect hello_dev You are now connected to database "hello_dev" as user "postgres". hello_dev=# \d List of relations Schema | Name | Type | Owner --------+-------------------+----------+---------- public | schema_migrations | table | postgres public | users | table | postgres public | users_id_seq | sequence | postgres (3 rows) hello_dev=# \q ``` -------------------------------- ### Example product_params output with Plug.Upload Source: https://phoenix.hexdocs.pm/file_uploads.md Example log output showing the product_params map with a "photo" key mapping to a Plug.Upload struct. The struct includes content_type, filename, and path to a temporary file. ```elixir %{"title" => "Metaprogramming Elixir", "description" => "Write Less Code, Get More Done (and Have Fun!)", "price" => "15.000000", "views" => "0", "photo" => %Plug.Upload{content_type: "image/png", filename: "meta-cover.png", path: "/var/folders/_6/xbsnn7tx6g9dblyx149nrvbw0000gn/T//plug-1434/multipart-558399-917557-1"}} ``` -------------------------------- ### Generate full URL with url/1 Source: https://phoenix.hexdocs.pm/routing.html Wrap a ~p path with Phoenix.VerifiedRoutes.url/1 to get a full URL. The example shows the output for ~p"/users" as http://localhost:4000/users. ```elixir url(~p"/users") "http://localhost:4000/users" ``` -------------------------------- ### Example Product Output Source: https://phoenix.hexdocs.pm/in_context_relationships.md Shows the expected output when viewing a product with categories after the changes. ```text text Title: Elixir Flashcards Description: Flash card set for the Elixir programming language Price: 5.000000 Views: 0 Categories: Education Books ``` -------------------------------- ### Get flash values in HEEx template Source: https://phoenix.hexdocs.pm/Phoenix.Flash.md Use Phoenix.Flash.get/2 to retrieve flash values by key from the @flash map. The example shows displaying the :info and :error keys in separate divs. ```heex
<%= Phoenix.Flash.get(@flash, :info) %>
<%= Phoenix.Flash.get(@flash, :error) %>
``` -------------------------------- ### Start IEx and alias User struct Source: https://phoenix.hexdocs.pm/ecto.html Commands to start IEx with mix and alias the Hello.User struct for easier testing. ```shell $ iex -S mix iex> alias Hello.User Hello.User ``` -------------------------------- ### Create Telemetry supervisor module (lib/my_app_web/telemetry.ex) Source: https://phoenix.hexdocs.pm/telemetry.html Defines the MyAppWeb.Telemetry supervisor with a metrics/0 function returning Telemetry.Metrics definitions. It starts :telemetry_poller with periodic measurements and includes commented-out reporter and measurement examples. ```elixir # lib/my_app_web/telemetry.ex defmodule MyAppWeb.Telemetry do use Supervisor import Telemetry.Metrics def start_link(arg) do Supervisor.start_link(__MODULE__, arg, name: __MODULE__) end def init(_arg) do children = [ {:telemetry_poller, measurements: periodic_measurements(), period: 10_000} # Add reporters as children of your supervision tree. # {Telemetry.Metrics.ConsoleReporter, metrics: metrics()} ] Supervisor.init(children, strategy: :one_for_one) end def metrics do [ # Phoenix Metrics summary("phoenix.endpoint.stop.duration", unit: {:native, :millisecond} ), summary("phoenix.router_dispatch.stop.duration", tags: [:route], unit: {:native, :millisecond} ), # VM Metrics summary("vm.memory.total", unit: {:byte, :kilobyte}), summary("vm.total_run_queue_lengths.total"), summary("vm.total_run_queue_lengths.cpu"), summary("vm.total_run_queue_lengths.io") ] end defp periodic_measurements do [ # A module, function and arguments to be invoked periodically. # This function must call :telemetry.execute/3 and a metric must be added above. # {MyApp, :count_users, []} ] end end ``` -------------------------------- ### Example implementation of fetch/2 Source: https://phoenix.hexdocs.pm/Phoenix.Presence.html Shows how to implement the fetch/2 callback to extend presence data with user information from the database, avoiding N+1 queries. ```elixir def fetch(_topic, presences) do query = from u in User, where: u.id in ^Map.keys(presences), select: {u.id, u} users = query |> Repo.all() |> Enum.into(%{}) for {key, %{metas: metas}} <- presences, into: %{} do {key, %{metas: metas, user: users[key]}} end end ``` -------------------------------- ### reply/2 example: asynchronous reply from handle_in and handle_info Source: https://phoenix.hexdocs.pm/Phoenix.Channel.html Shows a complete workflow for replying asynchronously: handle_in/3 starts a worker with a socket_ref, and handle_info/2 calls reply/2 when work completes. This demonstrates using reply/2 after the callback finishes. ```elixir def handle_in("work", payload, socket) do Worker.perform(payload, socket_ref(socket)) {:noreply, socket} end ``` ```elixir def handle_info({:work_complete, result, ref}, socket) do reply(ref, {:ok, result}) {:noreply, socket} end ``` -------------------------------- ### Deployment script for Phoenix application Source: https://phoenix.hexdocs.pm/deployment.html A shell script that outlines the steps to deploy a Phoenix application: initial setup, asset compilation, custom tasks like database migrations, and finally running the server. Use this as a starting point and add your own steps as needed. ```shell # Initial setup $ mix deps.get --only prod $ MIX_ENV=prod mix compile # Compile assets $ MIX_ENV=prod mix assets.deploy # Custom tasks (like DB migrations) $ MIX_ENV=prod mix ecto.migrate # Finally run the server $ PORT=4001 MIX_ENV=prod mix phx.server ``` -------------------------------- ### Run a single test by line number with mix test Source: https://phoenix.hexdocs.pm/testing.html Runs a single test by appending a colon and line number to the filename. The example runs the test starting on line 11 of error_html_test.exs. Output shows 2 tests, 0 failures, 1 excluded. ```shell $ mix test test/hello_web/controllers/error_html_test.exs:11 Including tags: [line: "11"] Excluding tags: [:test] . Finished in 0.1 seconds 2 tests, 0 failures, 1 excluded Randomized with seed 288117 ``` -------------------------------- ### Forwarded routes resolution example Source: https://phoenix.hexdocs.pm/Phoenix.VerifiedRoutes.md Shows how forwarded routes are resolved automatically. The main router forwards "/admin" to AppWeb.AdminRouter, which defines a get route for "/users". Forwarded paths like ~p"/admin/users" are verified as usual. ```elixir defmodule AppWeb.Router do ... forward "/admin", AppWeb.AdminRouter end ``` ```elixir defmodule AppWeb.AdminRouter do ... get "/users", AppWeb.Admin.UserController end ``` -------------------------------- ### mix phx.gen.html example with User schema Source: https://phoenix.hexdocs.pm/Mix.Tasks.Phx.Gen.Html.html Example command that generates a User schema for the users table within the Users context. ```shell $ mix phx.gen.html User users name:string age:integer ``` -------------------------------- ### underscore example Source: https://phoenix.hexdocs.pm/Phoenix.Naming.md Example of underscore/1 usage. ```elixir iex> Phoenix.Naming.underscore("MyApp") "my_app" ``` -------------------------------- ### Directory structure of lib/hello Source: https://phoenix.hexdocs.pm/directory_structure.html Shows the files in the lib/hello directory: application.ex, mailer.ex, and repo.ex. ```text lib/hello ├── application.ex ├── mailer.ex └── repo.ex ``` -------------------------------- ### Signing a token example Source: https://phoenix.hexdocs.pm/Phoenix.Token.md Example of signing a token with Phoenix.Token.sign/3. ```elixir iex> user_id = 99 iex> secret = "kjoy3o1zeidquwy1398juxzldjlksahdk3" iex> namespace = "user auth" iex> token = Phoenix.Token.sign(secret, namespace, user_id) ``` -------------------------------- ### resource_name examples Source: https://phoenix.hexdocs.pm/Phoenix.Naming.md Examples of resource_name/2 usage with and without a suffix. ```elixir iex> Phoenix.Naming.resource_name(MyApp.User) "user" ``` ```elixir iex> Phoenix.Naming.resource_name(MyApp.UserView, "View") "user" ``` -------------------------------- ### Controller action example Source: https://phoenix.hexdocs.pm/Phoenix.Controller.md Example controller module with a show/2 action that fetches a user and renders the :show template with the user assign. ```elixir defmodule MyAppWeb.UserController do use MyAppWeb, :controller def show(conn, %{"id" => id}) do user = Repo.get(User, id) render(conn, :show, user: user) end end ```