How to insert a processed file in an HTML template?

Hello! I want to insert in an HTML Pollen template a JS file.

To be clearer, I want this JS file to be processed by Pollen (of maybe just Racket?), then inserted in a <script> in the <head> of the page template. Being inserted this way is a requirement because I want to block the page render until the JS is executed (this is for a theme switcher).

For a bit of context, I want my JS files processed so that I can share variables between my CSS and JS files (think of color variables).

I’ve tried require "filename.js.p", but I get a strange side effect. When doing so, the output of (->html doc) switches to the JS file instead of using the page.poly.pm markup file. But the JS output is processed fine by Pollen.

I’ve tried other methods (render was one of those), but the JS is either correctly placed in the <head> but not processed, either not printed at all.

Any ideas on how to make it work?

Just invoke the JavaScript file in your <head> section of your template like you would ordinarily, e.g., —

<head>
···
<script type="text/javascript" src="filename.js"></script>
···
</head>

And then make a Pollen source for your JS file, probably filename.js.pp. Then you can use your pollen.rkt variables and functions in the JS file too.

The Pollen project server will do the right thing. Namely, when the template is used, Pollen will render filename.js.ppfilename.js if needed, and then things proceed normally.

Thank you for your response.

Indeed, if I was using a separate JS file, I wouldn’t have any problem.

What I want is to have the JS file content directly inserted in the HTML file.

<head>
  <script>
    // JS content here
  </script>
</head>

The JS content is small, and I don’t like the fact that the rendering has to wait for this subsequential web request to start render anything (it’s used to manage dark/light themes according to local storage or OS settings, and must block the rendering to prevent a flash of wrong theme).

I want to reuse this snippet in other projects, that’s why I would prefer to keep its source separate from the template, so I can maintain it without having to edit each of my projects.

Ah, I see. When you wrote (require "filename.js.p") you implicitly imported an identifier called doc and thus shadowed the doc the template expected. You can work around this by introducing a prefix-in namespace like so—

(require (prefix-in js: "filename.js.p"))

Then the contents of the JS file will be represented by js:doc, which you can insert into the template wherever you want.

1 Like

It’s working! Thank you very much!

<head>
  <script>
    ◊(require (prefix-in js: "filename.js.p"))
    ◊|js:doc|
  </script>
</head>