lee

lee

I’m new to Phoenix (and Elixir in general); I’m coming to Phoenix from a Javascript background (I’m the author of ReactQL, to give you an idea on the typical stack I’m used to.), so forgive me if the naïve/novice query.

One thing that stumped me immediately in Phoenix was the implicit templates/layout/app.html.eex. I’m developing a pretty typical app which is chunked into several sections - a public front-end, the user app itself, an admin area, an API. Having a default central layout doesn’t serve the requirements of this app, so I spent the first little while trying to figure out how to disable it.

What I wound up with was just a plug in the :browser pipeline, pointing to a private function that disables the default layout. I then deleted templates and layout_view.ex. Finally, in my controllers, I created a second plug for specifying routes connections to that particular controller.

Whilst this was fairly trivial to do (and I’m not even sure that’s the only - or right - way to go about it), the notion of first disabling the layout and then setting a new one seems a bit like a code smell to my novice Phoenix nose. In other frameworks I’ve worked with, layouts don’t tend to be assumed until explicitly set; I’ve found they’re often not required.

So for my introductory question to this board (and thanks in advance for helping to further my currently very basic understanding of Phoenix!), I’m curious what prompted the design decision to make layout/app.html.eex (and LayoutView) an implicit choice? My first instinct was to search Phoenix generated code to look for a specific reference to “app.html”, assuming that I’d just need to comment out the default line to prevent it… but it looks like LayoutView is hard-coded in lib code.

Again, I’m new here so I may be missing something obvious, but this did strike me as a tad opinionated and I’m curious what may have led to it.

Showing Posts 1 to 8

hlx

hlx

Phoenix allows you to changes pretty much anything you want and I think most of the projects require an layout so they made it default.

You could do it like this:

# router.ex
pipeline :no_layout do
  plug: :put_layout, false
end

scope "/api", MyAPI do
  pipe_through [:browser, :no_layout]
  ( ... )
end

I fail to understand what you mean by this? Maybe the scope and extra pipeline make the second plug not needed anymore?

lpil

lpil

Creator of Gleam

I would say that in general Phoenix is an opinionated framework that makes a lot of opinionated decisions in order to provide a particular experience that fits the majority of web apps.

Whether this is the best way if a matter of personal preference. I think myself I would prefer it to be explicit and in the generated code, as you’ve suggested.

lee

lee OP

…I think myself I would prefer it to be explicit and in the generated code, as you’ve suggested.

Agreed. I found it slightly out of step with other generated code.

For example, this being the default :browser pipeline:

pipeline :browser do
  plug :accepts, ["html"]
  plug :fetch_session
  plug :fetch_flash
  plug :protect_from_forgery
  plug :put_secure_browser_headers
end

… makes it really simple for a newbie like me to see, at a glance, exactly what’s provided out-the-box.

If I want to disable or add anything new, it’s clear where to make the change.

Whereas layouts being handled by default outside of generated code, obfuscates behind a bit of background magic that wasn’t immediately clear how to override.

I wound up figuring out it was just a simple :put_layout, false (thanks @hlx for simplifying my superfluous private func), but that feels a bit like monkey-patching the core.

From my very limited/early impression, I would have preferred to see an explicit :put_response, {LayoutView, "app.html"} in generated code, so I could instead comment it out rather than override.

A small detail, but just some feedback on something that stumped me on first glance.

lee

lee OP

I fail to understand what you mean by this? Maybe the scope and extra pipeline make the second plug not needed anymore?

Apologies, a series of typos! That should be something along the lines of

I created a second plug in each controller, for overriding the default layout

lee

lee OP

That’s completely fair; I just expected it to wind up in generated code, like pipelines, sockets, routing, etc.

hlx

hlx

I feel I need to mention this in case you haven’t thought of it, in your controller you can also simply call put_layout/1 instead of using a separate plug for it:

# contollers/page_controller.ex
def MyAppWeb.PageController do
  use MyAppWeb, :controller

  plug :put_layout, {MyAppWeb.PageLayoutView, :page}

  def index()
end

See: Phoenix.Controller — Phoenix v1.8.8

hlx

hlx

I have to agree, having the plug :put_layout, {MyApp.LayoutView, :app} generated by default in the router would be nicer

lee

lee OP

I feel I need to mention this in case you haven’t thought of it, in your controller you can also simply call put_layout/1 instead of using a separate plug for it:

Thanks @hlx, I thought of that after seeing your original example disabling it – appreciated!

— All posts loaded —

Where Next? Top

Trending in Questions Top

itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
yarrichar
I’m very new to Elixir, so sorry if this is a silly question: I am wondering what happens to the mailbox of a process when the machine i...
New
pragdave
How do I tell Hologram not to escape HTML when substituting into templates? {Textile.render(@product.long_description)} escapes the HTM...
New
Fl4m3Ph03n1x
Background When trying to execute mix release on a Windows 11 machine for a Phoenix project I get the following error: * assembling mark...
New
rlipscombe
I’d like to create a file with 600 permissions (rw-------), but there’s a race condition if I create it and then change the permissions. ...
New
saleyn
Is there a way to import record definitions in the iex shell for pretty printing (similar to the rr command in the erl shell)? This woul...
New
rlipscombe
When I use Mix.install with a git dependency, using git@github.com:... how do I change the SSH identity used? I’ve got two Github accoun...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews