onelixir

onelixir

Question about Phoenix Directory Structure

The Phoenix Framework Doc shows the Directory Structure like this:

lib/hello_web
├── controllers
│   ├── page_controller.ex
│   ├── page_html.ex
│   ├── error_html.ex
│   ├── error_json.ex
│   └── page_html
│       └── home.html.heex
├── components
│   ├── core_components.ex
│   ├── layouts.ex
│   └── layouts
│       ├── app.html.heex
│       └── root.html.heex
├── endpoint.ex
├── gettext.ex
├── router.ex
└── telemetry.ex

I have some question about this:

  1. Now we have just one page controller, inside controllers directory we have 2 page_* files and 1 page_* directory, if we also add JSON support, then one more file, one controller = 3 files + 1 directory, if we have 10 controllers, will we have 30 files + 10 directories in controllers directory?
  2. If we also need email, like in Rails, where should we put its directory, do we have some generator? And how about jobs?

I ask these questions because I just come from Rails, Phoenix looks simple but also brought too much confuse.

I truely hope Phoenix world have a book like 《 Agile Web Development with Rails 7》, The official document is good, but lack of focus and best practices.

Most Liked

sodapopcan

sodapopcan

It’s really just because the framework isn’t concerned about where your files are. For example, our Rails app was split up by feature so we ended up with many directories that essentially each had a mini Rails apps in them. It’s not the biggest deal in to make this work but you’re still going against the framework conventions. You also lose the social friction of new people coming into the app expecting it to look like a Rails app and it doesn’t. Phoenix doesn’t set up any such expectation. I’m not really saying it’s a massive, life-changing improvement but it is part of what drew me to Phoenix even if I do miss some stuff about Rails.

As far as Ecto vs ActiveRecord goes, I would say that is a massive improvement. It takes a bit to get comfortable with the shift away from an ORM, but Ecto is essentially like a super powerful and better designed arel. You don’t run into the same scaling issues with it since it just returns structs (which are no heavier than bare maps) as opposed to massive objects with methods spanning at least five different concerns.

sodapopcan

sodapopcan

Phoenix is not opinionated like Rails. There is a tiny bit of “magic” happening with via some dabs of reflection but it’s not pervasive. Phoenix doesn’t care at all where you put your files and the generated structure is more of a guideline. In fact, Phoenix is arguably closer to Sinatra than it is to Rails with $ mix phx.new being what makes it a full fullstack framework. There are single file examples of Phoenix apps out there!

I also came from Rails so I definitely shared some of your pain. I was particularly perturbed that many examples don’t show you exactly were to put files. I’m not saying this is better or worse, but you get used to it pretty quickly.

Your example is actually slightly flawed when comparing number of files to Rails. In Rails, the equivalent page_ files you mentioned would be controllers/page_controller.rb and views/pages/show.html.erb and helpers/page_helper.rb, so actually 3 files and 3 directories! The _html files in Phoenix are a new concept but basically they used to be called views. Phoenix splits up the concept of “view” into “html” and “template” (it used to be “view” and “template”) where html compiles the templates and controllers render the html. This is actually closer to how the general concept of a view quote-unquote “should” work (the “view” is the presentation logic whereas the “template” is the static markup) whereas Rails simplifies it by combining view+template then optionally allowing a ‘helper’ file if you need added presentation logic. In Phoenix, you would put your “helpers” in the PageHTML module. So, you are right in that Phoenix always forces you to have three modules (er, two modules + one template). If you’re strictly concerned about number of files and you don’t mind putting your templates in functions, you can actually define your templates right in PageHTML then you don’t need the show.html.heex file:

defmodule MyAppWeb.PageHTML do
  # ...
  def show(assigns) do
    ~H"""
    <h1>I'm the show page</h1>
    """
  end
end

I actually don’t use the default directory structure at all for web. I don’t have many controllers as I often have LiveViews but I break up my Web module into site sections, so I don’t have a controllers or live directory. Mine would look like this:

my_app_web/
  page/
    page_controller.ex
    page_html.ex
    html/
      show.html.heex

You don’t have to do anything special to make this work—just move the files around. Although you’ll have to likely have to change the glob given to PageHTML.embed_templates.

onelixir

onelixir

Thank you so much again, I think I learn a lot from your answers, I will dive into Phoenix to feel the feeling you feel.

Also, one of the most happy thing in Elixir land is because we have so kindly people like you :heart:

Where Next?

Popular in Discussions Top

scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19814 150
New
pillaiindu
In django there is a cache framework backed by memcached. Rails also puts a lot of emphasis on caching, and even the idea of russian-doll...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
nburkley
AWS re:Invent is on at the moment with some interesting announcements. One new feature in particular is the Lambda Runtime API for AWS La...
New
tomekowal
Hey guys! I want to create a toy project that shows a chart of temperature over time and updates every 5 seconds. I feel LiveView is per...
New
shishini
I think this twitter post and youtube video didn’t get as much attention as I hoped I am still new to Elixir, so can’t really judge ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement