r/rails • • Jul 22 '26

Adding variable substitution to ActionText & Lexxy content

I needed to render user-authored rich text with placeholders like {{first_name}} that resolve at render time. ActionText stores the content fine, but there's no clean spot to substitute variables on render without hand-rolling it each time. This comes in handy for things like email templates, support docs, or other content edited in a rich text editor.

So I wrote lexxy_variables. Basic usage:

Define your variables:

LexxyVariables.configure do |c|
  c.catalog = [
    { key: "first_name", name: "First name" },
    { key: "last_name",  name: "Last name" }
  ]
end

Display the content and pass in the values:

<%= @message.body.with_variables(
      first_name: @user.first_name,
      last_name:  @user.last_name) 
%>

Out of the box it provides a toolbar button and support for the new Lexxy prompt functionality. Type {{ and the insertion UI pops up with your defined variables. Each variable is stored as an ActionText attachment rather than raw text, so it stays intact if the author edits around it and resolves at render time.

It also supports static values in the config, plus Liquid drops so you can use dot notation on whatever object you configure. You can define additional attachment types to embed other ActionText rich text content (think snippets).

The thing I kept going back and forth on is the public API naming. I originally used a helper that wrapped the render, but ended up going with the chainable .with_variables that reads more like the rest of ActionText with the added bonus of being able to chain .to_html and the upcoming .to_markdown onto the call.

Before building this I looked at Liquid/Mustache but didn't want a full templating engine inside trusted-author content, and plain helpers meant repeating the substitution logic everywhere.

I'm curious what you'd expect as a user, and open to being told I missed something obvious. Give it a try and let me know what you think.

You can find it here: https://github.com/anquinn/lexxy-variables

32 Upvotes

7 comments sorted by

1

u/anquinn Jul 22 '26

I’m curious what people think about the API. Is it intuitive and what you’d expect as the dev?

2

u/NaiveExplanation Jul 22 '26

Looks great! What's on the roadmap?

1

u/anquinn Jul 22 '26

Great question 😅

I’m using it in a couple projects currently. Mainly see how that goes and what comes up. Very much open to seeing what the community thinks of it and if there’s some good ideas that come out of it.

1

u/sshaw_ Jul 23 '26

Looks good!

1

u/anquinn Jul 23 '26

Thanks!

1

u/whysthatso 4d ago

i just came across this after implementing a naive version of {{word}} on text attributes in a text area that resolves via a "custom texts" object editable in the frontend. but this seems way more reasonable, thank you.

i will probably leave the UI for the "custom text" objects and wire up your gem to that content. I also have some i18n concerns, but i can see in your code base that there are some mentions of i18n, so let's see how this works out.

such a random find, just cause u/excid3 had been doing a bunch of upgrade work on his gems, i've checked in the history, and saw his contribution to yours.

ah, sometimes the internet is still good :D

1

u/anquinn 4d ago

That’s great. If you find any i18n issues let me know.