
plutonium-forms
by radioactive-labs
Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, AI-ready.
SKILL.md
name: plutonium-forms description: Plutonium forms - custom templates, Phlex form components, field builders, and theming
Plutonium Forms
Plutonium forms are built on Phlexi::Form, providing a Ruby-first approach to form building with Phlex components.
Form Class Hierarchy
Phlexi::Form::Base
└── Plutonium::UI::Form::Base # Base with Plutonium components
├── Plutonium::UI::Form::Resource # Resource CRUD forms
│ └── Plutonium::UI::Form::Interaction # Interactive action forms
└── Plutonium::UI::Form::Query # Search/filter forms
Customizing Resource Forms
Override in Definition
class PostDefinition < ResourceDefinition
class Form < Form
def form_template
# Your custom form layout
render_fields
render_actions
end
end
end
Form Template Methods
| Method | Description |
|---|---|
form_template | Main template method to override |
render_fields | Render all permitted fields |
render_resource_field(name) | Render a single field by name |
render_actions | Render submit buttons |
fields_wrapper { } | Wrapper div for field grid |
actions_wrapper { } | Wrapper div for buttons |
Form Attributes
| Attribute | Description |
|---|---|
object / record | The form object being edited |
resource_fields | Array of permitted field names |
resource_definition | The definition instance |
Custom Form Layout
Sectioned Form
class PostDefinition < ResourceDefinition
class Form < Form
def form_template
section("Basic Information") {
render_resource_field :title
render_resource_field :slug
}
section("Content") {
render_resource_field :content
render_resource_field :excerpt
}
section("Publishing") {
render_resource_field :published_at
render_resource_field :category
}
render_actions
end
private
def section(title, &)
div(class: "mb-8") {
h3(class: "text-lg font-semibold mb-4 text-gray-900 dark:text-white") { title }
fields_wrapper(&)
}
end
end
end
Two-Column Layout
class Form < Form
def form_template
div(class: "grid grid-cols-1 lg:grid-cols-3 gap-6") {
# Main content - 2 columns
div(class: "lg:col-span-2") {
fields_wrapper {
render_resource_field :title
render_resource_field :content
}
}
# Sidebar - 1 column
div(class: "space-y-4") {
Panel {
h4(class: "font-medium mb-2") { "Settings" }
render_resource_field :status
render_resource_field :visibility
}
}
}
render_actions
end
end
Field Builder
When using render_resource_field, Plutonium uses the field builder. For custom rendering, use the field method directly.
Basic Field Usage
def form_template
# Using field builder directly
render field(:title).wrapped {|f| f.input_tag }
render field(:content).wrapped {|f| f.easymde_tag }
render field(:published).wrapped {|f| f.checkbox_tag }
render_actions
end
Field Builder Methods
The field builder (f) provides these tag methods:
| Method | Input Type |
|---|---|
f.input_tag | Text input (auto-detects type) |
f.string_tag | Text input |
f.text_tag | Textarea |
f.number_tag | Number input |
f.email_tag | Email input |
f.password_tag | Password input |
f.url_tag | URL input |
f.tel_tag | Telephone input |
f.hidden_tag | Hidden input |
f.checkbox_tag | Checkbox |
f.select_tag | Select dropdown |
f.radio_button_tag | Radio buttons |
Plutonium-Enhanced Tags
| Method | Description |
|---|---|
f.easymde_tag / f.markdown_tag | Markdown editor (EasyMDE) |
f.slim_select_tag | Enhanced select (Slim Select) |
f.flatpickr_tag | Date/time picker (Flatpickr) |
f.phone_tag / f.int_tel_input_tag | International phone input |
f.uppy_tag / f.file_tag | File upload (Uppy) |
f.secure_association_tag | Association with authorization |
f.belongs_to_tag | Belongs-to association |
f.has_many_tag | Has-many association |
f.has_one_tag | Has-one association |
f.key_value_store_tag | Key-value pairs |
Field with Options
# Select with choices
render field(:status).wrapped { |f|
f.select_tag(choices: %w[draft published archived])
}
# Date picker with options
render field(:published_at).wrapped { |f|
f.flatpickr_tag(min_date: Date.today, enable_time: true)
}
# File upload with restrictions
render field(:avatar).wrapped { |f|
f.uppy_tag(
allowed_file_types: %w[.jpg .png .gif],
max_file_size: 5.megabytes
)
}
Wrapped vs Unwrapped
# Wrapped - includes label, hint, errors
render field(:title).wrapped { |f| f.input_tag }
# Unwrapped - just the input element
render field(:title).input_tag
# Custom wrapper options
render field(:title).wrapped(class: "col-span-full") { |f|
f.input_tag
}
Input Configuration in Definitions
Define inputs in the definition, render them in the form:
class PostDefinition < ResourceDefinition
# Configure inputs
input :title, hint: "Be descriptive", placeholder: "Enter title"
input :content, as: :markdown
input :status, as: :select, choices: %w[draft published]
input :published_at, as: :flatpickr
# Custom input with block
input :category do |f|
choices = Category.active.pluck(:name, :id)
f.select_tag(choices: choices)
end
class Form < Form
def form_template
# render_resource_field uses the input configuration
render_resource_field :title
render_resource_field :content
render_resource_field :status
render_resource_field :published_at
render_resource_field :category
render_actions
end
end
end
Dynamic Forms (pre_submit)
Fields with pre_submit: true trigger form re-rendering on change:
class PostDefinition < ResourceDefinition
input :post_type, as: :select,
choices: %w[article video podcast],
pre_submit: true
input :video_url,
condition: -> { object.post_type == "video" }
input :podcast_url,
condition: -> { object.post_type == "podcast" }
end
When post_type changes, the form re-renders via Turbo and shows/hides conditional fields.
Nested Forms
For has_many / has_one associations with accepts_nested_attributes_for:
Model Setup
class Post < ResourceRecord
has_many :comments
accepts_nested_attributes_for :comments, allow_destroy: true
end
Definition Setup
class PostDefinition < ResourceDefinition
nested_input :comments do |n|
n.input :author_name
n.input :body, as: :text
end
# Or reference another definition
nested_input :comments, using: CommentDefinition, fields: %i[author_name body]
end
Custom Nested Rendering
class Form < Form
def form_template
render_resource_field :title
render_resource_field :content
# Nested fields are automatically handled
render_resource_field :comments
render_actions
end
end
Interaction Forms
Forms for interactive actions use Plutonium::UI::Form::Interaction:
class PublishPostInteraction < ResourceInteraction
attribute :publish_date, :date
attribute :notify_subscribers, :boolean, default: true
# Custom form
class Form < Form
def form_template
div(class: "space-y-4") {
render_resource_field :publish_date
render_resource_field :notify_subscribers
}
render_actions
end
end
end
Form Actions
Default Actions
def render_actions
actions_wrapper {
# "Create and add another" / "Update and continue editing" button
# Primary submit button
render submit_button
}
end
Custom Actions
def render_actions
actions_wrapper {
# Cancel link
a(href: resource_url_for(resource_class), class: "btn btn-secondary") {
"Cancel"
}
# Save as draft
button(type: :submit, name: "draft", value: "1", class: "btn") {
"Save Draft"
}
# Primary submit
render submit_button
}
end
Form Context
Inside form templates, you have access to:
class Form < Form
def form_template
# Form object
object # The record
record # Alias for object
object.new_record? # Check if creating
# Request context
current_user
current_parent
current_scoped_entity
request
params
# Definition
resource_definition
resource_fields # Permitted fields
# URL helpers
resource_url_for(object)
resource_url_for(Post, action: :new)
# Rails helpers
helpers.link_to(...)
end
end
Theming
Forms use a theme system for consistent styling:
class PostDefinition < ResourceDefinition
class Form < Form
class Theme < Plutonium::UI::Form::Theme
def self.theme
super.merge({
fields_wrapper: "grid grid-cols-2 gap-6",
actions_wrapper: "flex justify-between mt-8",
input: "w-full p-3 border-2 rounded-lg",
label: "block mb-1 font-bold text-gray-700"
})
end
end
end
end
Theme Keys
| Key | Description |
|---|---|
base | Form container |
fields_wrapper | Grid wrapper for fields |
actions_wrapper | Wrapper for buttons |
wrapper | Individual field wrapper |
label | Label styling |
input | Input styling |
hint | Hint text styling |
error | Error message styling |
button | Submit button styling |
checkbox | Checkbox styling |
select | Select styling |
Related Skills
plutonium-definition-fields- Input configuration (as:, hint:, condition:)plutonium-views- Custom page classesplutonium-assets- TailwindCSS and component themingplutonium-interaction- Interactive action formsplutonium-nested-resources- Parent/child forms
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon
