chemist

chemist

I need some help to clear my thoughts.

I need to render another HTML page within a page but will like to replace some tags within be it while rendering OR before render.

<div>
    <%= String.replace(render("greeting.html"), ["<h1"], fn "<h1" -> "<h2 onclick='console.log('yo')" end) %>
</div>

May I know your thoughts how it can be done?

And second question, will the rendered file have access to the javascript functions in the parent/containing page?

Thank you!

Showing Posts 1 to 10

kokolegorille

kokolegorille

Using regex to transform html is not what I would do… maybe use Floki, and set attributes wherever needed.

I would try to separate html from js. You can do it using js, and attach event handler to the dom.

Maybe passing some parameters, like the js to run, to the child would be good too.

And maybe use some helpers, You should avoid logic in the template.

chemist

chemist OP

Many thanks for the suggestiom. I agree Floki is an incredibly powerful library but as the raw_html generated may not always be an EXACT copy, it may not be suitable.

Good suggestion regarding the seperation of HTML from JS. Will need to refactor later on.

Will love your thoughts on this

page_template.html.eex
<div>
    <%= raw rendertem() %>
</div>
page_view.ex
defmodule TestWeb.PageView do
  use TestWeb, :view

  def rendertem do
              {:ok, htmlfile} = File.read("lib/test_web/templates/page/template.html.eex")
              String.replace(htmlfile, ["<div"], fn "<div" -> ~s("<div onclick="console.log\('Clicked'\);") end)
  end
end

Many thanks.

al2o3cr

al2o3cr

This problem is usually solved by having the template contain EEX code that does whatever behavior you’re looking for. Where is that file coming from that you’d need to transform it this way?

chemist

chemist OP

The file is an user uploaded HTML file (here its called template.html - which i admit is misleading) that is loaded as part of a main page and some interactivity (such as the js onclick event) must be dynamically loaded along with it.

So how is the above? Is there a better way? I tried EEx.eval_file instead of File.read but it was very slow.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

You’re serving untrusted HTML to end users?

chemist

chemist OP

This is just an experiment.

The template is created internally.

So any insight on how one can replace the html tags to include an onclick event while rendering within a parent page? Thanks. And i agree its good practice to ensure it is sanitized prior.

al2o3cr

al2o3cr

When mutating HTML, definitely use something like Floki to get escaping and quoting right. For instance, both of the examples in this thread create broken HTML:

<%= String.replace(render("greeting.html"), ["<h1"], fn "<h1" -> "<h2 onclick='console.log('yo')" end) %>
  • replaces the h1 opening tag with an h2 but doesn’t change the closing tag
  • creates an invalid attribute with the ' inside onclick='...'
String.replace(htmlfile, ["<div"], fn "<div" -> ~s("<div onclick="console.log\('Clicked'\);") end)
  • replaces <div with "<div ..." with extra double-quotes

Alternatively, consider alternative approaches:

  • generate the HTML with the needed attribute

  • bind a click event listener to the element dynamically; for instance, render the template inside a div and use that to attach a handler:

# in the HTML
<div class="template-content">
  <%= render the template %>
</div>

# in the page JS
$(".template-content h2").click(...)

The rendered file’s contents will be seamlessly included - there’s no sandboxing / isolation, the bytes from the template will be presented as part of the parent page.

chemist

chemist OP

I am so grateful to you for such a well thought out and very reasonable reply.

What i am trying to actually is to append an alpinejs x-on:click attribute to specific html tags.

Besides the typo where h2 was supposed to read h1…

My concern is floki and other html libraries rewrite the html. My need is that all formatting must be preserved with just x-on attributes injected whereever required. And as x-on is being used, it obliviates the need for a seperate event listener.

Thank you and I hope i dont appear argumentative because i actually agree with all your suggestions. Just i am operating within constraints. Hope to hear your views.

al2o3cr

al2o3cr

Hmmm, yeah Alpine seems to take some pretty vigorous liberties with HTML structure:

<div x-data="{ open: false }">
    <button @click="open = true">Open Dropdown</button>

    <ul
        x-show="open"
        @click.away="open = false"
    >
        Dropdown Body
    </ul>
</div>

However, if the template already contains Alpine-flavored markup it seems simplest to write the handlers directly there, instead of trying to insert them at runtime. :thinking:

chemist

chemist OP

Exactly. Alpinejs doesnt make using a HTML parser easy.

Sorry what do you mean by writing the handlers directly there?

Do you mean, editing the template prior to runtime?

Many thanks

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
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
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews