Skip to content

Commit 7863fd2

Browse files
committed
Add custom look
1 parent 94f3254 commit 7863fd2

25 files changed

+328
-37
lines changed

docs/adding_custom_field_types.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ Since we want to display an image, we can change it to:
5858
You can customize the other generated partials in the same way
5959
for custom behavior on the index and form pages.
6060

61+
## Using a Custom Look
62+
63+
If you want to generate a different look, run the following:
64+
65+
```bash
66+
rails generate administrate:field gravatar --look custom
67+
```
68+
69+
This will generate three files:
70+
71+
- `app/fields/gravatar_field.rb`
72+
- `app/views/fields/gravatar_field/looks/custom/_show.html.erb`
73+
- `app/views/fields/gravatar_field/looks/custom/_index.html.erb`
74+
- `app/views/fields/gravatar_field/looks/custom/_form.html.erb`
75+
6176
## Using your custom field
6277

6378
We need to tell Administrate which attributes we'd like to be displayed as a

docs/customizing_attribute_partials.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,17 @@ Changing numbers to display to three decimal places might look like this:
5454

5555
If you only want to change how an attribute appears
5656
on a single page (e.g. `index`), you may delete the unnecessary templates.
57+
58+
## Using a Custom Look
59+
60+
If you want to generate a different look, run the following:
61+
62+
```bash
63+
rails generate administrate:views:field number --look custom
64+
```
65+
66+
This will generate three files:
67+
68+
- `app/view/fields/number/looks/custom/_form.html.erb`
69+
- `app/view/fields/number/looks/custom/_index.html.erb`
70+
- `app/view/fields/number/looks/custom/_show.html.erb`

docs/customizing_dashboards.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,3 +647,28 @@ end
647647
<%= button_to "some action 3", [:some_action_3, namespace, field.resource] %>
648648
<% end %>
649649
```
650+
651+
## Custom Look
652+
653+
You can use the `look` option to change the field template.
654+
655+
```ruby
656+
ATTRIBUTE_TYPES = {
657+
customer: Field::BelongsTo.with_options(look: :customer_card)
658+
}
659+
```
660+
661+
The template path is derived from the class name of the field and falls back sequentially to its ancestor classes.
662+
For example, the path lookup order for a `BelongsTo` field is as follows:
663+
664+
```
665+
fields/belongs_to/looks/customer_card/
666+
fields/belongs_to/looks/default/
667+
fields/belongs_to/
668+
fields/associative/looks/customer_card/
669+
fields/associative/looks/default/
670+
fields/associative/
671+
fields/base/looks/customer_card/
672+
fields/base/looks/default/
673+
fields/base/
674+
```

lib/administrate/field/base.rb

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
module Administrate
55
module Field
66
class Base
7+
@partial_prefixes = {}
8+
9+
class << self
10+
attr_writer :partial_prefixes
11+
end
12+
13+
def self.inherited(subclass)
14+
super
15+
subclass.partial_prefixes = {}
16+
end
17+
718
def self.with_options(options = {})
819
Deferred.new(self, options)
920
end
@@ -36,17 +47,22 @@ def self.permitted_attribute(attr, _options = nil)
3647
attr
3748
end
3849

39-
def self.partial_prefixes
40-
@partial_prefixes ||=
50+
def self.partial_prefixes(look: :default)
51+
@partial_prefixes[look] ||=
4152
if superclass.respond_to?(:partial_prefixes)
42-
local_partial_prefixes + superclass.partial_prefixes
53+
local_partial_prefixes(look:) + superclass.partial_prefixes(look:)
4354
else
44-
local_partial_prefixes
55+
local_partial_prefixes(look:)
4556
end
4657
end
4758

48-
def self.local_partial_prefixes
49-
["fields/#{field_type}"]
59+
def self.local_partial_prefixes(look: :default)
60+
fallback = ["fields/#{field_type}/looks/default", "fields/#{field_type}"]
61+
if look == :default
62+
fallback
63+
else
64+
["fields/#{field_type}/looks/#{look}"] + fallback
65+
end
5066
end
5167

5268
def initialize(attribute, data, page, options = {})
@@ -84,7 +100,11 @@ def read_value(data)
84100
end
85101

86102
def partial_prefixes
87-
self.class.partial_prefixes
103+
self.class.partial_prefixes(look: look)
104+
end
105+
106+
def look
107+
(options.fetch(:look, :default).presence || :default).to_sym
88108
end
89109

90110
def required?

lib/generators/administrate/field/field_generator.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
module Administrate
22
module Generators
33
class FieldGenerator < Rails::Generators::NamedBase
4+
class_option(
5+
:look,
6+
type: :string,
7+
desc: "Specify the look for the field",
8+
default: ""
9+
)
10+
411
source_root File.expand_path("../templates", __FILE__)
512

613
def template_field_object
@@ -18,12 +25,17 @@ def copy_partials
1825

1926
private
2027

28+
def look
29+
options[:look]
30+
end
31+
2132
def copy_partial(partial_name)
2233
partial = "_#{partial_name}.html.erb"
34+
looks_dir = look.present? ? "looks/#{look}/" : ""
2335

2436
copy_file(
2537
partial,
26-
"app/views/fields/#{file_name}_field/#{partial}"
38+
"app/views/fields/#{file_name}_field/#{looks_dir}#{partial}"
2739
)
2840
end
2941
end

lib/generators/administrate/views/field_generator.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ module Administrate
44
module Generators
55
module Views
66
class FieldGenerator < Administrate::ViewGenerator
7+
class_option(
8+
:look,
9+
type: :string,
10+
desc: "Specify the look for the field",
11+
default: ""
12+
)
13+
714
def self.template_source_path
815
File.expand_path(
916
"../../../../../app/views/fields/",
@@ -30,6 +37,10 @@ def copy_partials
3037

3138
private
3239

40+
def look
41+
options[:look]
42+
end
43+
3344
def copy_field_partials(resource_path)
3445
copy_field_partial(resource_path, :index)
3546
copy_field_partial(resource_path, :show)
@@ -38,10 +49,11 @@ def copy_field_partials(resource_path)
3849

3950
def copy_field_partial(resource_path, partial_name)
4051
template_file = "#{resource_path}/_#{partial_name}.html.erb"
52+
looks_dir = look.present? ? "looks/#{look}/" : ""
4153

4254
copy_file(
4355
template_file,
44-
"app/views/fields/#{template_file}"
56+
"app/views/fields/#{resource_path}/#{looks_dir}_#{partial_name}.html.erb"
4557
)
4658
end
4759
end

spec/example_app/app/dashboards/line_item_dashboard.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class LineItemDashboard < Administrate::BaseDashboard
1212
created_at: Field::DateTime,
1313
updated_at: Field::DateTime,
1414
order: Field::BelongsTo,
15-
product: Field::BelongsTo.with_options(sorting_column: :name),
15+
product: Field::BelongsTo.with_options(sorting_column: :name, look: :product_card),
1616
quantity: Field::Number,
1717
total_price: Field::Number.with_options(prefix: "$", decimals: 2),
1818
unit_price: Field::Number.with_options(prefix: "$", decimals: 2)

spec/example_app/app/dashboards/page_dashboard.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class PageDashboard < Administrate::BaseDashboard
44
ATTRIBUTE_TYPES = {
5-
product: Field::BelongsTo,
5+
product: Field::BelongsTo.with_options(look: :product_card),
66
id: Field::Number,
77
title: Field::String,
88
body: Field::Text,
@@ -12,6 +12,7 @@ class PageDashboard < Administrate::BaseDashboard
1212

1313
COLLECTION_ATTRIBUTES = %i[
1414
id
15+
product
1516
title
1617
].freeze
1718

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<% if field.data %>
2+
<span>
3+
<% if field.data.image_url.present? %>
4+
<%= image_tag(
5+
field.data.image_url,
6+
alt: field.data.name,
7+
style: 'max-height: 2em; max-width: 2em;',
8+
) %>
9+
<% end %>
10+
<% if accessible_action?(field.data, :show) %>
11+
<%= link_to(
12+
field.display_associated_resource,
13+
[namespace, field.data],
14+
) %>
15+
<% else %>
16+
<%= field.display_associated_resource %>
17+
<% end %>
18+
</span>
19+
<% end %>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<% if field.data %>
2+
<span style="display: flex; align-items: center; gap: 0.2em;">
3+
<% if field.data.image_url.present? %>
4+
<%= image_tag(
5+
field.data.image_url,
6+
alt: field.data.name,
7+
style: 'max-height: 2em; max-width: 2em;',
8+
) %>
9+
<% end %>
10+
<% if accessible_action?(field.data, :show) %>
11+
<%= link_to(
12+
field.display_associated_resource,
13+
[namespace, field.data],
14+
) %>
15+
<% else %>
16+
<%= field.display_associated_resource %>
17+
<% end %>
18+
</span>
19+
<% end %>

0 commit comments

Comments
 (0)