On this page:
1.1 Beeswax conversion
1.1.1 Your template is now a module
1.2 Pollen integration
8.12

1 Using Beeswax in a Pollen project🔗ℹ

The simplest way to understand Beeswax is to see it in use in its native habitat: a Pollen project. So let’s make a very small, simple one.

In an empty folder, save a Pollen source document:

"fleas.html.pm"

#lang pollen
 
(define-meta title "Lines on the Antiquity of Microbes")
 
pre{
Adam
Had ’em.
}

In the same folder, save an HTML template:

"template.html"

<html>

  <title>[POLLEN was here]</title>

  <h1>◊(hash-ref metas 'title)</h1>

  ◊(->html doc)

</html>

Our sample Pollen project is now fully operational; you can raco pollen render fleas.html and Pollen will create a "fleas.html" that matches our template.

You might have noticed we don’t have a "pollen.rkt" file in this project. We’ll add it in a bit.

1.1 Beeswax conversion🔗ℹ

We’re now going to create a Beeswax template.

Step one: open the same "template.html" in DrRacket and add the line #lang beeswax/template to the top, like this:

"template.html.rkt"

#lang beeswax/template
 
<html>
  <title>[BEESWAX was here]</title>
  <h1>(hash-ref metas 'title)</h1>
  (->html doc)
</html>

(Also change POLLEN to BEESWAX in the <title> tag as shown. This isn’t strictly necessary, but it will help make clear later on which template file we’re using.)

Step two: save the modified template to a new file with a ".rkt" extension: "template.html.rkt".

There, your template is now a Beeswax template! Beeswax templates use exactly the same syntax and facilities as normal Pollen templates, so adding the #lang line at the top and renaming the file is generally all you’ll need to do to convert an existing template.

You’ll notice DrRacket is now giving you the white-glove treatment: syntax highlighting, definition arrows, and a helpful toolbar button.

Within a beeswax/template file, you have access to all the same things you do inside a normal Pollen template: doc, metas, here, a number of Pollen functions , and of course everything provided from a nearby "pollen.rkt" file.

1.1.1 Your template is now a module🔗ℹ

Everything in a #lang beeswax/template file is wrapped in a function that is provided to other files. (This is similar to how #lang pollen files wrap their contents into the provided values doc and metas.) The function is always named apply-template and it takes three arguments: doc (which can be any value), metas (a hash table), and here, an output path in symbol form (i.e., a pagenode?).

You can see this by clicking the Run button at the top of the DrRacket window for "template.html.rkt" and poking around a little in the REPL:

> apply-template

#<procedure:apply-template>

When you call this function, it renders the values you pass it into the template and returns the bytes of the rendered result. Try calling apply-template with some placeholder values for doc, metas and here:

> (display (apply-template "What’s up doc?"
                           (hash 'title "Test")
                           'test.html))

<html>

  <title>[BEESWAX was here]</title>

  <h1>Test</h1>

  What’s up doc?

</html>

It’s not much of a leap at this point to render the "fleas.html.pm" Pollen source file we created:

; Get doc and metas
> (require "fleas.html.pm")
> (display (apply-template doc metas 'fleas.html))

<html>

  <title>[BEESWAX was here]</title>

  <h1>Lines on the Antiquity of Microbes</h1>

  <root><pre>Adam

Had ’em.</pre>

</root>

</html>

1.2 Pollen integration🔗ℹ

At this point, Pollen itself does not know anything about "template.html.rkt". If you tell Pollen to render "fleas.html" you’ll see it renders the file using the old "template.html" template:

> raco pollen render -f fleas.html

pollen: rendering fleas.html

pollen: rendering /fleas.html.pm

pollen: rendered /fleas.html (625 ms)

 

> cat fleas.html

<html>

  <title>[POLLEN was here]</title>

  <h1>Lines on the Antiquity of Microbes</h1>

  <root><pre>Adam

Had ’em.</pre>

</root>

</html>

But there is a way to tell Pollen to use Beeswax for the rendering step. In the same folder as "fleas.html.pm" create a new file "pollen.rkt":

"pollen.rkt"

#lang racket/base
 
(module setup racket/base
  (define external-renderer '(beeswax/for-pollen external-renderer))
  (provide external-renderer))

Now render the file again:

> raco pollen render -f fleas.html

pollen: rendering fleas.html

pollen: beeswax rendered /fleas.html (4ms)

 

> cat fleas.html

<html>

  <title>[BEESWAX was here]</title>

  <h1>Lines on the Antiquity of Microbes</h1>

  <root><pre>Adam

Had ’em.</pre>

</root>

</html>

 

The output of the first command shows that Pollen has involved Beeswax in the rendering process (“pollen: beeswax rendered …”. Looking at the contents of "fleas.html" confirms that the Beeswax template was used this time, not the Pollen one.

When Pollen sees a value for external-renderer provided by the setup submodule of a local "pollen.rkt" file, instead of rendering the file itself, it calls the function specified, and uses whatever it gets back as the rendered result.

The function external-renderer provided by beeswax/for-pollen does its own work to find the right Beeswax template (in this case "template.html.rkt"). It then uses that file’s apply-template function on the doc and metas from the source file, (pretty much just as we did manually in the previous section).

If you start the Pollen project server with raco pollen start and preview "fleas.html" you’ll see the Beeswax template also being used to render the live preview.

Note that modifying a Beeswax template does not invalidate Pollen’s render cache. We can tell Pollen to use Beeswax for rendering but it still does not know anything about our alternative template files, so it isn’t watching them for changes when determining when to force a re-render.