Is there any inbuilt functionality for providing template inheritance for eex templates?

Is there any inbuilt functionality for providing template inheritance for eex templates, something like jinja2 has (in the Python world).

PS: this is my first web application in elixir and I am trying to build it without phoenix.

1 Like

Currently not, and I do not think it should be part of it. There are many different ways to compose templates, and currently you can implement a small wrapper around the way you prefer most.

How do they do it? Only a minority of the community has used python and even less will have used that library.

What do you use instead? Pure plugs? Or are you talking HTTP directly? Do you have any reasons for this?

The requirement is to have the common parts (like the <html>, <head> etc. ) and then have separate .html.eex files for body contents for various pages (index, about etc.). If its not too much, can you please guide me as to how I should go about this…

Well you are right, not many here will be familiar with it. Basically in the derived templates, you just put a extend "base.html" tag at the top. The library would then inject the base html contents here. Also they have concept of content blocks. So you could define a “navigation” content block inside the <body> tag in base.html and then if you specify that content block in any derived template, it would replace the default contents for that particular content block before generating the final html. I understand I am not making much sense here, so I will stop here :slight_smile:

Yes actually ! I am using Plugs for creating the application. The only reason for not going for Phoenix straight-on is that its code contains a lot of macros and I am not really comfortable reading and then making sense of that much macro code. I see that its a beautifully designed framework but I was hoping of starting small.

The easiest might be to simply have an outer template, which has some assign for the inner content, then have many templates for the inner content.

Then roughly do assigns |> render_inner() |> &(Map.puts(assigns, :content, &1)).() |> render_outer().

Yupp, I did not understand anything, except, that the current template shouldn’t know about anything from the outside.

By doing something like your extend you basically couple those templates. Swapping designs on the fly will be a hard thing, while still easily possible with my aproach above.

Also changing the title of the page shouldn’t be done by the inner template. It is meant to just display the data. The “controller” is the entitiy that is aware of the full context, and therefore should assign a title. And only the rendering stage should then decide if a title is needed at all (perhaps we are rendering in a desktop application and do not touch the window title here?)

Thank you for the pointer, I will write some wrapper functions in line with this and see how it goes.

To those who come to this topic, please check out the last portion of this blog post. You can build a solution on those lines.

Thank you @NobbZ for the help.

1 Like

Enjoyable read, thanks for sharing. Helps solidify the knowledge of how eex works

I’m interested in this but is it up-to-date? I couldn’t compile it:

warning: variable "assigns" does not exist and is being expanded to "assigns()", please use parentheses to remove the ambiguity or change the variable name                                                        
  vlans.conf.eex:1                                                                                                                                                                                                 
                                                                                                                                                                                                                   
** (CompileError) vlans.conf.eex:2: expected "assigns" to expand to an existing variable or be part of a match                                                                                                     
    (elixir) expanding macro: Kernel.var!/1
    vlans.conf.eex:2: Render.vlans/1
    (elixir) expanding macro: Kernel.<>/2
    vlans.conf.eex:8: Render.vlans/1
    (elixir) expanding macro: Kernel.<>/2
    vlans.conf.eex:8: Render.vlans/1
    (elixir) expanding macro: Kernel.if/2
    vlans.conf.eex:1: Render.vlans/1
1 Like

@amarandon sorry I didnt log into elixirforum for quite some time… Are you still facing this issue?

1 Like

Unfortunately the blog is not online anymore. Could you tell me the basics of the solution?

Btw I found this : https://bash-shell.net/blog/phoenix-django-devs-block-tag/