Use template into others with different view and router

Hi! May someone helps me, please? I am trying to render a template into another template. My objective is to create a generic template with two links to log in or log out with the help of Ueberauth, and I want this template to appear in all the pages of my website.

This is the template that I have:

<section>
        <ul class="right">
              <%= if @conn.assigns[:user] do %>
                <li>
                  <%= link "Sign Out", to: auth_path(@conn, :signout) %>
                </li>
              <% else %>
                <li>
                  <%= link "Google Sign In", to: auth_path(@conn, :request, "google")%>
                </li>
              <% end%>
            </ul>
</section>

These are my templates and views files trees:

templates
    layouts
        auth
            auth.html.eex
        app.html.eex
    page
        index.html.eex
views
    auth_view.ex
    error_helpers.ex
    error_helpers.ex
    error_view.ex
    layout_view.ex
    page_view.ex

I just want to know how to insert the auth.html.eex into other templates. For example, at this moment I am just trying to insert it into the index page of Phoenix (The one that appears the first time yo create a new project).

I will appreciate if someone can help me.

What You need is shared views…

3 Likes

If you want it on every view, you can also add it to your app layout, e.g. add the following to templates\layouts\app.html.eex:

 <%= render MyAppWeb.Shared.AuthView, "auth.html", conn: @conn %>

Thanks so much

As a sidenote I do it a little bit differently than in the link.

Often I add a helpers folder in lib/any_web/helpers. I add a bootstrap_helper, with corresponding view, and template folder. I add it globally in any_web.ex, like this…

  def view do
    quote do
      use Phoenix.View,
        root: "lib/any_web/templates",
        namespace: AnyWeb

      # Import convenience functions from controllers
      import Phoenix.Controller, only: [get_flash: 1, get_flash: 2, view_module: 1]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML

      # Here I import some custom helpers
      import AnyWeb.Helpers.CheckboxHelper
      import AnyWeb.Helpers.BootstrapHelper
      import AnyWeb.Helpers.WaffleHelper
      import AnyWeb.Helpers.BaseHelper

      import AnyWeb.ErrorHelpers
      import AnyWeb.Gettext
      alias AnyWeb.Router.Helpers, as: Routes
    end
  end

These are 2 simple functions I put in helper. One is using content_tag, one render a template.

defmodule AnyWeb.Helpers.BootstrapHelper do
  @moduledoc """
  This is the documentation for the Bootstrap 4 helpers.
  It includes also fa helper, for Font awesome
  """
  use Phoenix.HTML

...

  def flash(message, mode) do
    class = "alert alert-#{mode} alert-dismissible fade show"
    content_tag(:div, class: class, role: "alert") do
      [
        message,
        content_tag(:button, type: :button, class: :close, "data-dismiss": :alert, "aria-label": "Close") do
          content_tag(:span) do
            raw("&times;")
          end
        end
      ]
    end
  end

  @doc """
  Dropdown helper
  """
  def dropdown(options \\ []) do
    render("dropdown.html", options)
  end

Then, in any template, I have access to helper functions to simplify building components. Like this…

<%= flash("hello world", "alert") %>

The main difference with the linked example is I import helpers…

If one day I decide to change css framework, I would just replace bootstrap helper with a new one.

2 Likes