webassembly icon indicating copy to clipboard operation
webassembly copied to clipboard

Examples of "partials"

Open wkhere opened this issue 10 years ago • 8 comments

wkhere avatar Feb 24 '15 18:02 wkhere

I greatly prefer the builder style for creating html, but reuse-ability is definitely key. Is there a way to do 'partials' or call out to other functions to dry up repetive stuff like form input wrappers (etc)?

collin avatar May 19 '15 02:05 collin

This is exactly what I've been looking for. How do you do partials?

decapo01 avatar Sep 28 '18 03:09 decapo01

Hello.

Unfortunately partials occured to be broken due to the fact how builder macro works. It can hardly be fixed without a big internal redesign.

Sorry to say that... I am not using Elixir very actively nowadays.

This issue should be renamed as it is misleading- suggests that partials are working as we expect from other frameworks/libs.

wkhere avatar Oct 18 '18 03:10 wkhere

I actually figured out a way to get this working with what you have. I meant to comment on this but I also stopped working in elixir. I'm not sure how maintainable this is but if you specify the text tag you can put more html inside.

def layout(content) do
    use WebAssembly
    builder do
      html do
        head do
          title "Home"
        end
        body do
          div class: "container" do
            h1 "Hello"
            ul do
              li "list item 1"
              li "list item 2"
            end
            div do
              text content
            end
          end
        end
      end
    end
  end

  def home_content([%Person{} | _] = persons) do
    use WebAssembly
    builder do
      div class: "some-class" do
        h2 "This is home content"
          for per <- persons, do:
            p "#{per.name} #{per.age}"
        div do
          p "another paragraph"
        end
      end
    end
  end

I was able to get that to work with a phoenix controller like this

  def about(conn, _params) do
    p = [
      newPerson("jim", 232),
      newPerson("will",23)
    ]
    conn
      |> put_resp_content_type("text/html", "utf-8")
      |> send_resp(200,home(home_content(p)))
  end

decapo01 avatar Oct 19 '18 22:10 decapo01

Interesting. Yeah.

I was aiming at more ambitious solution but this may work.

Thank you, it is going to get me to bring back my Elixir hacking env, not tomorrow but hopefully soon.

wkhere avatar Oct 23 '18 21:10 wkhere

I think the text macro could be aliased to eval to make it more clear that in this context we want to evaluate what comes from another builder invocation, what do you think? Would it make the code more readable?

wkhere avatar Oct 23 '18 21:10 wkhere

Yeah I think eval sounds right for that situation. I was taking a break from scala when I tried this. The play framework has a type safe templating engine and I was trying to mimic that in elixir which is what brought me here. You can user the linter to tell you if you have errors for whatever structure you put in without having to load the page. I probably won't be using elixir much anytime soon though so whatever you call it is cool with me.

decapo01 avatar Oct 24 '18 20:10 decapo01

Optimistic type safety, generally possible in Erlang/Elixir with dialyzer, is used in WebAssembly, but this all works in a slightly different way than you may expect.

Main point of WebAssembly is that you can intermix html DSL and regular Elixir language; it's done in a way that DSL is actually macros which modify via Agent API the process-local stack of html element "scopes" (core.ex) and the whole processing is actually done at runtime.

So, dialyzer can prove that calls from DSL to this Agent machinery implementation are type safe (for the quite relaxed definition of possible inputs/outputs, see types.ex) but that's it, it has nothing to do with the correctness of the code describing the page, or partial. I would of course love to have it but I don't know how to do it while still retaining this property of mixed WebAssembly DSL & Elixir.

I would recap that the advantages of WebAssembly are:

  • kind of visual pleasure, if you like it,
  • ability to intermix html DSL with regular Elixir code,
  • a speed gain and less gc based on a fact that the output is iolist without flattening, and this is perfectly good input for the low-level Erlang networking code,
  • syntax of your DSL is verified to some extent, in a way that Elixir can check if you invoke macros in a proper way, but that's it; there are known dark corners already (#9); type safety - rather not.

wkhere avatar Oct 25 '18 11:10 wkhere