Guide

SlimX reads the Slim 5 grammar and renders the HTML Slim renders. Installing it is swapping a gem; this page covers the rest.

Rails

# Gemfile
gem "slimx" # instead of slim-rails

A railtie registers the .slim handler with Action View. Nothing else to configure:

  • output is escaped with Rails’ html_safe rules, and == outputs raw;
  • templates whose format is XML (.xml, .rss, .atom) render as XML, with <link /> and doctype xml;
  • annotate_rendered_view_with_filenames adds its BEGIN/END comments, and streaming works;
  • every - and = line compiles onto its template line, so an exception’s backtrace points at the right line — including after a ruby: block or a multi-line attribute list, where Slim drifts;
  • /# locals: (post:) declares a partial’s strict locals.

Tilt and plain Ruby

Sinatra, Hanami, Roda — anything on Tilt

require "slimx/tilt"

Tilt.new("page.slim").render(scope, title: "Hi")
SlimX::Template.new("page.slim", tailwind_classes: true)

Plain Ruby

require "slimx"

code = SlimX.compile(source, file: "page.slim")
# Ruby that builds the HTML in _buf and returns it

Tilt passes its options through to SlimX.compile. Registering SlimX takes the slim extension, so require slimx/tilt instead of slim, not both.

Options

Two settings apply everywhere, typically in config/initializers/slimx.rb:

SettingDefaultEffect
SlimX.strict = trueoffRefuse to compile a template slimx fmt would change. Strict mode
SlimX.tailwind_classes = trueoffLet class shortcuts read Tailwind class names. Tailwind

Each one can be overridden per compile, alongside the options of SlimX.compile and SlimX::Template:

OptionDefaultEffect
file:nilThe path shown in syntax errors and backtraces.
format::html:xml closes void tags (<br />) and allows doctype xml.
html_safe:when String#html_safe? existsLeave html_safe strings unescaped, the way Rails expects.
shortcuts:# → id, . → classSlim’s shortcut definitions, such as {"@" => {attr: "role"}, "&" => {tag: "input", attr: "type"}}.
strict:SlimX.strictStrict mode for this template.
tailwind_classes:SlimX.tailwind_classesTailwind class names for this template.

Tailwind class names

Slim cuts .rounded-b-[3px] at the bracket, renders .size-2.5 as class="size-2 5", and refuses .lg:[&:nth-child(3)]:hover:underline. Turn on tailwind_classes and the . shortcut takes any Tailwind class name:

Template

.p-1.rounded-b-[3px].lg:[&:nth-child(3)]:hover:underline
.font-['Open_Sans'].bg-(--brand).mx-0.5.w-1/2.!font-bold
ul.*:p-2

config/initializers/slimx.rb, and .slimx.yml for the CLI

SlimX.tailwind_classes = true
tailwind_classes: true

Attribute lists keep their meaning: Tailwind never puts a bracket right after a letter or a digit, so a.btn[href="/"] is still a link with a class and an href. A colon followed by a space still nests a tag (li.item: a), and a final / still closes one.

Checked on 7,505 templates from 31 apps: 16 compile differently with the option, every one of them a Tailwind class Slim breaks. It stays off by default all the same, so that switching from Slim changes no template. It only changes how templates are read: the compiled Ruby, so the render time, is the same.

Embedded engines

ruby:, javascript:, css: and markdown: work as in Slim, interpolation included. markdown: renders through Markly: add gem "markly" to use it. SlimX itself depends on no gem.

Migrating from Slim

  1. Slim defaults to format: :xhtml and sort_attrs: true. If you never changed them, first switch Slim to format: :html, sort_attrs: false and run your test suite: that is the HTML SlimX renders.
  2. Replace slim-rails (or slim) with gem "slimx".
  3. Remove any Slim::Engine.set_options or with_options call, and move custom shortcuts to the shortcuts: option.
  4. Run slimx fmt once and review the diff, then add slimx lint and slimx fmt --check to CI.
  5. Optionally, turn on SlimX.strict in development and test.

What SlimX leaves out

Each fails at compile time with a clear error instead of being silently ignored:

  • the XHTML format, sort_attrs, attr_quote, pretty, js_wrapper and every Temple option;
  • the coffee:, sass:, scss:, less:, erb:, builder:, textile:, rdoc:, asciidoc: and wiki engines, and /[if IE] conditional comments;
  • the logic_less, translator, include and smart plugins, and lambda shortcuts.

They can come back if people ask, as long as they cost nothing at render time.