Code Block
Display code snippets with a language badge, copy button, and basic syntax highlighting.
Key Features
- Dead simple - No HTML entity encoding required
- Block syntax - Display code without ERB execution
- Language badge - Shows language name in header
- Copy button - One-click copy using rui_clipboard
- Dark theme - Professional code display
- Basic highlighting - Server-side, no JavaScript required
- XSS safe - All code is HTML-escaped automatically
How It Works
Simple Ruby-Based Highlighter
This is not Prism.js, Highlight.js, or any JavaScript library. It's a simple Ruby module that uses regex patterns to add color classes to code tokens. Processing happens server-side - no JavaScript required.
The highlighter is intentionally basic. It's designed for documentation sites where "good enough" highlighting is better than adding JavaScript dependencies.
What It Does
- Highlights keywords, strings, symbols, comments
- Colors ERB tags and RUI helpers distinctly
- Works without any JavaScript
- Fast server-side rendering
- Works with Turbo and page caching
- Escapes HTML to prevent XSS
- Preserves whitespace and formatting
What It Doesn't Do
- Full syntax parsing (it's regex-based)
- Handle complex nested strings perfectly
- Support all programming languages
- Provide line numbers
- Highlight Python, Go, Rust code
- Match IDE-level accuracy
- Theme customization
Language Support
Not all languages have syntax highlighting. Some only get a label badge.
Languages WITH Highlighting
These languages have regex-based color highlighting:
| Language | Code | Highlights |
|---|---|---|
| ERB | :erb, :html |
ERB tags, RUI helpers, strings, symbols, keywords, HTML tags |
| Ruby | :ruby |
Keywords, strings, symbols, comments, constants, numbers |
| JavaScript | :javascript, :js, :ts |
Keywords, strings, comments, numbers |
| CSS | :css, :scss |
Selectors, properties, values, comments |
| JSON | :json |
Keys, string values, numbers, booleans |
| Bash | :bash, :shell, :sh |
Comments, strings, variables, common commands |
Languages WITHOUT Highlighting (Label Only)
These show a language badge but render as plain text:
:python Python:go Go:rust Rust:elixir Elixir:sql SQL:yaml YAML:markdown Markdown:plain Plain TextNote: Unknown languages will display in UPPERCASE as the badge label. The code will render as plain text.
Highlighting Examples
Ruby
class User < ApplicationRecord
has_many :posts
validates :email, presence: true
def full_name
"#{first_name} #{last_name}"
end
end
ERB
<%= rui_table do |table| %>
<% table.with_column(key: :name, label: "Name") %>
<% table.with_row(id: 1) do |row| %>
<% row.with_cell { "John Doe" } %>
<% end %>
<% end %>
JavaScript
const handleClick = async (event) => {
event.preventDefault();
const response = await fetch('/api/users');
const data = await response.json();
console.log(data);
};
CSS
.container{
display: flex;
gap: 1rem;
padding: 2rem;
}
.card{
border-radius: 0.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
JSON
{
"name": "RapidRailsUI",
"version": "0.26.0",
"rails": true,
"components": 25
}
Bash
# Install the gem
bundle add rapid_rails_ui
# Run the installer
rails generate rapid_rails_ui:install
# Start your server
bin/dev
Color Reference
The highlighter uses these colors for different token types:
| Token Type | Color | Examples |
|---|---|---|
| Keywords | Pink | def, class, if, do, end, const, function |
| Strings | Amber | "hello", 'world' |
| Symbols | Purple | :name, :id, :primary |
| Comments | Gray | # comment, // comment |
| Constants | Cyan | User, ApplicationRecord |
| Numbers | Orange | 123, 3.14, 0 |
| ERB Tags | Red | <%=, %> |
| RUI Helpers | Green | rui_button, rui_table |
| Method Calls | Sky | .with_column, .each |
Titles
Provide a custom title or let it default to the language name.
def hello
puts 'world'
end
def hello
puts 'world'
end
Displaying ERB Code
To show ERB code without execution, escape the ERB tags with an extra %:
ERB Escaping
Use <%%= instead of <%= to display ERB output tags.
Use <%% instead of <% to display ERB statement tags.
<%= rui_button("Click me", color: :primary) %>
Complete Usage Examples
Copy-paste ready examples for common use cases.
1. Block Syntax (Recommended)
Best for multi-line code. Content goes inside the block.
<%= rui_code_block(language: :ruby, title: "User Model") do %>
class User < ApplicationRecord
has_many :posts, dependent: :destroy
has_many :comments
validates :email, presence: true, uniqueness: true
validates :name, presence: true, length: { minimum: 2 }
def full_name
"#{first_name} #{last_name}"
end
end
<% end %>
2. String Argument (One-Liners)
Pass code as first argument for quick one-line snippets.
<% Install command %>
<%= rui_code_block("bundle add rapid_rails_ui", language: :bash) %>
<% Simple Ruby expression %>
<%= rui_code_block("User.find_by(email: 'admin@example.com')", language: :ruby) %>
<% Shell command with custom title %>
<%= rui_code_block("rails generate rapid_rails_ui:install", language: :bash, title: "Installation") %>
3. Keyword Argument (Dynamic Content)
Use code: keyword for content stored in variables.
<% From a model attribute %>
<%= rui_code_block(code: @snippet.content, language: @snippet.language.to_sym) %>
<% From a variable %>
<% code_example = "def greet(name)\n puts «xmrk19xmrk»quot;Hello, #{name}!\"\nend" %>
<%= rui_code_block(code: code_example, language: :ruby, title: "Greeting Method") %>
<% From a file (be careful with untrusted content) %>
<%= rui_code_block(code: File.read(Rails.root.join('app/models/user.rb')), language: :ruby) %>
4. With HTML Attributes
Pass custom classes, IDs, and data attributes.
<% Custom CSS class %>
<%= rui_code_block("npm install", language: :bash, class: "my-custom-class") %>
<% Custom ID for targeting %>
<%= rui_code_block("bundle exec rails server", language: :bash, id: "server-command") %>
<% Data attributes for JavaScript %>
<%= rui_code_block("rake db:migrate", language: :bash, data: { turbo: false, controller: "highlight" }) %>
<% Combined attributes %>
<%= rui_code_block(language: :ruby, title: "Complete Example", class: "mb-8", id: "main-example", data: { section: "intro" }) do %>
puts "Hello, World!"
<% end %>
5. All Options Combined
A complete example showing all available options.
<%= rui_code_block(
language: :ruby, # Required: syntax highlighting
title: "Complete Example", # Optional: custom header title
copy: true, # Optional: show copy button (default: true)
class: "my-code-block", # Optional: CSS classes
id: "example-1", # Optional: HTML ID
data: { section: "demo" } # Optional: data attributes
) do %>
class ApplicationController < ActionController::Base
before_action :authenticate_user!
private
def current_user
@current_user ||= User.find(session[:user_id])
end
end
<% end %>
Real-World Examples
Documentation Page
Common pattern for documentation sites.
<div class="prose dark:prose-invert">
<h2>Installation</h2>
<p>Add the gem to your Gemfile:</p>
<%= rui_code_block("gem 'rapid_rails_ui'", language: :ruby, title: "Gemfile") %>
<p>Then run:</p>
<%= rui_code_block(language: :bash, title: "Terminal") do %>
bundle install
rails generate rapid_rails_ui:install
<% end %>
<h2>Basic Usage</h2>
<p>Use the button component:</p>
<%= rui_code_block(language: :erb, title: "app/views/pages/home.html.erb") do %>
<%= rui_button("Click Me", color: :primary, size: :lg) %>
<% end %>
</div>
API Response Example
<h3>API Response</h3>
<%= rui_code_block(language: :json, title: "GET /api/users/1") do %>
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-15T10:30:00Z",
"posts_count": 42
}
<% end %>
Controller + View Example
<% Controller %>
<%= rui_code_block(language: :ruby, title: "app/controllers/posts_controller.rb") do %>
class PostsController < ApplicationController
def index
@posts = Post.published.includes(:author).page(params[:page])
end
def show
@post = Post.find(params[:id])
end
end
<% end %>
<% View %>
<%= rui_code_block(language: :erb, title: "app/views/posts/index.html.erb") do %>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<%= render @posts %>
</div>
<% end %>
Known Limitations
-
⚠
Nested quotes may not highlight perfectly - Escaped quotes like
\"inside strings can confuse the regex. -
⚠
No heredoc highlighting - Ruby heredocs (
<<~TEXT) are not specially handled. - ⚠ Large files may be slow - For 1000+ line code blocks, regex processing takes time.
- ⚠ No diff highlighting - Can't show added/removed lines like GitHub diffs.
For production applications requiring full syntax highlighting, consider using a JavaScript library like Prism.js or Highlight.js. This component is designed for documentation sites where simplicity and zero-JS is preferred.
Accessibility
The Code Block component follows accessibility best practices for displaying code content.
Semantic HTML
-
<pre>element preserves whitespace and formatting -
<code>element indicates code content to assistive technologies - Language badge provides context about code language
Keyboard Navigation
- Tab navigates to the copy button
- Enter or Space activates the copy button
- Focus states are clearly visible with ring styles
Visual Design
- High contrast syntax highlighting colors on dark background
- Monospace font for code readability
-
Copy button uses
rui_clipboardwith full accessibility support
API Reference
rui_code_block
Display code snippets with language badge and copy button
| Parameter | Type | Default | Description |
|---|---|---|---|
| code | String | — | Code to display (positional argument, keyword, or block) |
| language | Symbol |
:plain
|
Language identifier for syntax highlighting and badge |
| title | String | — | Header title (defaults to language name if not set) |
| copy | Boolean |
true
|
Show copy-to-clipboard button in header |
| class | String | — | Additional CSS classes for wrapper element |
| data | Hash | — | Custom data attributes for wrapper element |
| id | String | — | Custom HTML ID for wrapper element |
Usage Patterns
Three ways to provide code content
| Parameter | Type | Default | Description |
|---|---|---|---|
| Block syntax | Block | — | Recommended for multi-line code - content inside do...end block |
| Positional argument | String | — | First argument - good for one-liners |
| Keyword argument | String | — | code: keyword - good for variables |
Languages WITH Highlighting
These languages have syntax coloring via regex patterns
| Parameter | Type | Default | Description |
|---|---|---|---|
| :erb / :html | Symbol | — | ERB tags, RUI helpers, HTML tags, strings, symbols |
| :ruby | Symbol | — | Keywords, strings, symbols, comments, constants |
| :javascript / :js / :ts | Symbol | — | Keywords, strings, comments, numbers |
| :css / :scss | Symbol | — | Selectors, properties, values, comments |
| :json | Symbol | — | Keys, string values, numbers, booleans |
| :bash / :shell / :sh | Symbol | — | Comments, strings, variables, commands |
Languages WITHOUT Highlighting
Badge only - code renders as plain text
| Parameter | Type | Default | Description |
|---|---|---|---|
| :python / :py | Symbol | — | Python code (label only) |
| :go | Symbol | — | Go code (label only) |
| :rust | Symbol | — | Rust code (label only) |
| :sql | Symbol | — | SQL queries (label only) |
| :yaml / :yml | Symbol | — | YAML config (label only) |
| :markdown / :md | Symbol | — | Markdown (label only) |
| :plain | Symbol | — | Plain text (default) |