A summary of the conventions in phoenix, particularly the file/module naming

Can someone please go over some of the more important conventions in a phoenix application.
(by convention I mean file naming (upper case, lower case, underscores, extensions), file locations, etc.)

Unlike rails, it seems you don’t have to put files in any particular folder structure like

/app/controllers
/app/views
etc.

Are most of the conventions around the template and views?

I think a lot of it you can infer by looking at the structure, from what I gather:

  • All filenames are lower case

  • Name your files/folders after the module it contains (seems like a general elixir practice unless your project only has a few modules)

  • CamelCase modules becomes snake_case files.

  • .ex files most of the time

  • .exs for “elixir script” files, things that won’t be compiled. Tests, etc.

  • .eex for “embedded elixir”, i.e stuff that has <%= %> to be pre-processed.

    • I haven’t tried but I actually think you could probably have any type of content (i.e. my_view.txt.eex) and have it be pre-processed and sent out with the correct mime type.
  • /assets/ is pretty freeform since js/css frameworks/packages come in all shapes and sizes

  • /lib/<app> is for what you could probably call model code in rails, probably more accurately its the business logic section. I think you should be able to cut-paste this folder somewhere and basically be able to stick a new UI over it without much effort outside of removing <App>Web.endpoint from the child processes.

  • /lib/<app>_web is for user facing elements (web controllers and views)

    • I believe Phoenix.Controller and Phoenix.Controller.Pipeline are where the smarts are to infer correct paths for your views, which are then inserted into Plug.Conn.private.
    • Since Elixir is compiled, controller file names aren’t actually important. You define routes in router.ex by the module symbol name and they’re looked up by that though obviously following the controllers/my_module.ex layout is helpful.
    • Phoenix.Template does some smarts to scan a directory and create functions for each file found that will return the template after preprocessing with vars you send etc.
    • Look at lib/<app>_web/<app>_web.ex to see what code is included into your controller & views.
  • /lib/app_web/views contain helper modules for each respective view, so user_view.ex should have helpers for your template/user/*.html.eex files. i.e. something like censor_complete_email(email) -> "pur*****@gmail.com"

  • /lib/app_web/templates follows what you’d expect akin to rails.

2 Likes

Just to clarify, are you stating best practises and common conventions or things that if you don’t do your app will break? (I was interested in the later, forced conventions that if you don’t do your app will break).

You can do this, I use EEx for plain text and XML too. But the MIME type is not automatically set from the filename, you need to ensure it’s correct yourself.

We should actually set the mime type for you. But we only do it for known extensions according to the Mime library.

1 Like

As far as I know the only enforced convention in the way that rails uses it is that templates need to be in the right directory in order to be discovered by default. For instance if you have a UserController controller and a UserView then the templates are expected to be in templates/user/.

I believe everything else just uses module names. Modules can (more or less) be defined anywhere and the convention is actually just a convention and not an “unspoken rule” like it is in rails.

2 Likes

Even the template location can be customized via the options passed to Phoenix.View/Phoenix.Template.

No doubt. But by default if it’s not in that directory it just won’t work. Hence why I said “by default” :wink: