@spree/docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/api-reference/platform/authentication.md +38 -0
- package/dist/api-reference/store-api/authentication.md +188 -0
- package/dist/api-reference/store-api/errors.md +277 -0
- package/dist/api-reference/store-api/idempotency.md +129 -0
- package/dist/api-reference/store-api/introduction.md +34 -0
- package/dist/api-reference/store-api/localization.md +279 -0
- package/dist/api-reference/store-api/metadata.md +160 -0
- package/dist/api-reference/store-api/monetary-amounts.md +65 -0
- package/dist/api-reference/store-api/querying.md +399 -0
- package/dist/api-reference/store-api/rate-limitting.md +103 -0
- package/dist/api-reference/store-api/relations.md +185 -0
- package/dist/api-reference/storefront/authentication.md +88 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
- package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
- package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
- package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
- package/dist/api-reference/v2/introduction.md +22 -0
- package/dist/api-reference/v2/pagination.md +37 -0
- package/dist/api-reference/webhooks-events.md +883 -0
- package/dist/developer/admin/admin.md +205 -0
- package/dist/developer/admin/authentication.md +59 -0
- package/dist/developer/admin/components.md +711 -0
- package/dist/developer/admin/custom-css.md +243 -0
- package/dist/developer/admin/custom-javascript.md +116 -0
- package/dist/developer/admin/extending-ui.md +1964 -0
- package/dist/developer/admin/form-builder.md +444 -0
- package/dist/developer/admin/helper-methods.md +531 -0
- package/dist/developer/admin/navigation.md +805 -0
- package/dist/developer/admin/tables.md +491 -0
- package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
- package/dist/developer/cli/quickstart.md +137 -0
- package/dist/developer/contributing/creating-an-extension.md +258 -0
- package/dist/developer/contributing/developing-spree.md +339 -0
- package/dist/developer/contributing/quickstart.md +32 -0
- package/dist/developer/contributing/updating-extensions.md +67 -0
- package/dist/developer/core-concepts/addresses.md +265 -0
- package/dist/developer/core-concepts/adjustments.md +107 -0
- package/dist/developer/core-concepts/architecture.md +177 -0
- package/dist/developer/core-concepts/calculators.md +323 -0
- package/dist/developer/core-concepts/customers.md +230 -0
- package/dist/developer/core-concepts/events.md +624 -0
- package/dist/developer/core-concepts/imports-exports.md +698 -0
- package/dist/developer/core-concepts/inventory.md +191 -0
- package/dist/developer/core-concepts/markets.md +250 -0
- package/dist/developer/core-concepts/media.md +167 -0
- package/dist/developer/core-concepts/metafields.md +187 -0
- package/dist/developer/core-concepts/orders.md +328 -0
- package/dist/developer/core-concepts/payments.md +710 -0
- package/dist/developer/core-concepts/pricing.md +163 -0
- package/dist/developer/core-concepts/products.md +360 -0
- package/dist/developer/core-concepts/promotions.md +322 -0
- package/dist/developer/core-concepts/reports.md +206 -0
- package/dist/developer/core-concepts/search-filtering.md +237 -0
- package/dist/developer/core-concepts/shipments.md +212 -0
- package/dist/developer/core-concepts/slugs.md +111 -0
- package/dist/developer/core-concepts/staff-roles.md +123 -0
- package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
- package/dist/developer/core-concepts/stores.md +117 -0
- package/dist/developer/core-concepts/taxes.md +135 -0
- package/dist/developer/core-concepts/translations.md +120 -0
- package/dist/developer/core-concepts/users.md +299 -0
- package/dist/developer/core-concepts/webhooks.md +378 -0
- package/dist/developer/create-spree-app/quickstart.md +158 -0
- package/dist/developer/customization/api.md +93 -0
- package/dist/developer/customization/authentication.md +88 -0
- package/dist/developer/customization/checkout.md +204 -0
- package/dist/developer/customization/configuration.md +55 -0
- package/dist/developer/customization/decorators.md +523 -0
- package/dist/developer/customization/dependencies.md +232 -0
- package/dist/developer/customization/emails.md +21 -0
- package/dist/developer/customization/extensions.md +92 -0
- package/dist/developer/customization/metadata.md +236 -0
- package/dist/developer/customization/model-preferences.md +130 -0
- package/dist/developer/customization/permissions.md +265 -0
- package/dist/developer/customization/quickstart.md +229 -0
- package/dist/developer/customization/routes.md +24 -0
- package/dist/developer/customization/v4/admin-panel.md +78 -0
- package/dist/developer/customization/v4/authentication.md +210 -0
- package/dist/developer/customization/v4/checkout.md +212 -0
- package/dist/developer/customization/v4/deface.md +251 -0
- package/dist/developer/customization/v4/images.md +86 -0
- package/dist/developer/customization/v4/storefront.md +450 -0
- package/dist/developer/deployment/assets.md +87 -0
- package/dist/developer/deployment/aws.md +335 -0
- package/dist/developer/deployment/caching.md +27 -0
- package/dist/developer/deployment/cdn.md +39 -0
- package/dist/developer/deployment/database.md +155 -0
- package/dist/developer/deployment/docker.md +128 -0
- package/dist/developer/deployment/emails.md +77 -0
- package/dist/developer/deployment/environment_variables.md +111 -0
- package/dist/developer/deployment/heroku.md +51 -0
- package/dist/developer/deployment/render.md +95 -0
- package/dist/developer/getting-started/quickstart.md +82 -0
- package/dist/developer/how-to/custom-payment-method.md +374 -0
- package/dist/developer/how-to/custom-promotion.md +373 -0
- package/dist/developer/how-to/custom-report.md +387 -0
- package/dist/developer/how-to/custom-search-provider.md +230 -0
- package/dist/developer/multi-store/quickstart.md +71 -0
- package/dist/developer/multi-store/setup.md +38 -0
- package/dist/developer/multi-tenant/configuration.md +41 -0
- package/dist/developer/multi-tenant/core-concepts.md +75 -0
- package/dist/developer/multi-tenant/installation.md +96 -0
- package/dist/developer/multi-tenant/quickstart.md +20 -0
- package/dist/developer/multi-vendor/installation.md +45 -0
- package/dist/developer/multi-vendor/quickstart.md +17 -0
- package/dist/developer/sdk/admin/quickstart.md +22 -0
- package/dist/developer/sdk/authentication.md +89 -0
- package/dist/developer/sdk/configuration.md +225 -0
- package/dist/developer/sdk/quickstart.md +82 -0
- package/dist/developer/sdk/store/account.md +67 -0
- package/dist/developer/sdk/store/cart-checkout.md +140 -0
- package/dist/developer/sdk/store/markets.md +151 -0
- package/dist/developer/sdk/store/payments.md +96 -0
- package/dist/developer/sdk/store/products.md +149 -0
- package/dist/developer/sdk/store/wishlists.md +52 -0
- package/dist/developer/security/pci_compliance.md +15 -0
- package/dist/developer/security/security_policy.md +68 -0
- package/dist/developer/storefront/blocks.md +285 -0
- package/dist/developer/storefront/custom-css.md +260 -0
- package/dist/developer/storefront/custom-javascript.md +166 -0
- package/dist/developer/storefront/helper-methods.md +1288 -0
- package/dist/developer/storefront/links.md +298 -0
- package/dist/developer/storefront/nextjs/architecture.md +150 -0
- package/dist/developer/storefront/nextjs/customization.md +141 -0
- package/dist/developer/storefront/nextjs/deployment.md +180 -0
- package/dist/developer/storefront/nextjs/quickstart.md +92 -0
- package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
- package/dist/developer/storefront/pages.md +163 -0
- package/dist/developer/storefront/sections.md +569 -0
- package/dist/developer/storefront/storefront.md +56 -0
- package/dist/developer/storefront/themes.md +161 -0
- package/dist/developer/tutorial/admin.md +134 -0
- package/dist/developer/tutorial/extending-models.md +380 -0
- package/dist/developer/tutorial/file-uploads.md +121 -0
- package/dist/developer/tutorial/introduction.md +33 -0
- package/dist/developer/tutorial/model.md +41 -0
- package/dist/developer/tutorial/page-builder.md +487 -0
- package/dist/developer/tutorial/rich-text.md +73 -0
- package/dist/developer/tutorial/seo.md +332 -0
- package/dist/developer/tutorial/storefront.md +352 -0
- package/dist/developer/tutorial/testing.md +558 -0
- package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
- package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
- package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
- package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
- package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
- package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
- package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
- package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
- package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
- package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
- package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
- package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
- package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
- package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
- package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
- package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
- package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
- package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
- package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
- package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
- package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
- package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
- package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
- package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
- package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
- package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
- package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
- package/dist/developer/upgrades/quickstart.md +36 -0
- package/dist/integrations/analytics/google-analytics.md +64 -0
- package/dist/integrations/analytics/google-tag-manager.md +78 -0
- package/dist/integrations/integrations.md +39 -0
- package/dist/integrations/marketing/klaviyo.md +99 -0
- package/dist/integrations/payments/adyen.md +90 -0
- package/dist/integrations/payments/paypal.md +41 -0
- package/dist/integrations/payments/razorpay.md +45 -0
- package/dist/integrations/payments/stripe.md +109 -0
- package/dist/integrations/search/meilisearch.md +236 -0
- package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
- package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
- package/package.json +27 -0
|
@@ -0,0 +1,805 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Extending Admin Navigation
|
|
3
|
+
sidebarTitle: Navigation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Spree Admin Dashboard provides a flexible navigation system that allows you to easily extend the sidebar navigation with your own menu items without modifying the core codebase. This enables safe updates while maintaining your customizations.
|
|
7
|
+
|
|
8
|
+
> **INFO:** Starting with Spree 5.2, the navigation system uses a declarative API accessible via `Spree.admin.navigation`. This allows you to programmatically add, modify, and remove navigation items directly in your initializers.
|
|
9
|
+
|
|
10
|
+
## Basic Usage
|
|
11
|
+
|
|
12
|
+
Add navigation items in your `config/initializers/spree.rb` file:
|
|
13
|
+
|
|
14
|
+
```ruby config/initializers/spree.rb
|
|
15
|
+
Rails.application.config.after_initialize do
|
|
16
|
+
sidebar_nav = Spree.admin.navigation.sidebar
|
|
17
|
+
|
|
18
|
+
sidebar_nav.add :brands,
|
|
19
|
+
label: :brands,
|
|
20
|
+
url: :admin_brands_path,
|
|
21
|
+
icon: 'award',
|
|
22
|
+
position: 35,
|
|
23
|
+
active: -> { controller_name == 'brands' },
|
|
24
|
+
if: -> { can?(:manage, Spree::Brand) }
|
|
25
|
+
end
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Available Options
|
|
29
|
+
|
|
30
|
+
All navigation items support the following options:
|
|
31
|
+
|
|
32
|
+
- **`label`** (`Symbol or String`) — The text label for the navigation item. Can be a symbol (translation key using `Spree.t`) or a string.
|
|
33
|
+
|
|
34
|
+
- **`url`** (`Symbol or Lambda`) — The URL for the navigation item. Can be a route helper symbol (`:admin_brands_path`) or a lambda returning a URL.
|
|
35
|
+
|
|
36
|
+
- **`icon`** (`String`) — Icon name from [Tabler Icons](https://tabler.io/icons).
|
|
37
|
+
|
|
38
|
+
- **`position`** (`Integer`) — Numeric position in the menu. Lower numbers appear first.
|
|
39
|
+
|
|
40
|
+
- **`active`** (`Lambda`) — Lambda to determine if the link should be highlighted as active. Receives view context.
|
|
41
|
+
|
|
42
|
+
- **`if`** (`Lambda`) — Conditional display logic. The item only appears if this lambda returns true. Has access to view context helpers like `can?`, `current_store`, etc.
|
|
43
|
+
|
|
44
|
+
- **`badge`** (`String or Lambda`) — Badge text/count to display next to the label. Can be a string or lambda that returns a value.
|
|
45
|
+
|
|
46
|
+
- **`badge_class`** (`String`) — CSS class for badge styling (e.g., `'badge-info'`, `'badge-warning'`).
|
|
47
|
+
|
|
48
|
+
- **`tooltip`** (`String`) — Tooltip text shown on hover.
|
|
49
|
+
|
|
50
|
+
- **`target`** (`String`) — Link target attribute (e.g., `'_blank'` to open in a new tab).
|
|
51
|
+
|
|
52
|
+
- **`section_label`** (`String`) — Creates a section divider with the given label instead of a clickable link.
|
|
53
|
+
|
|
54
|
+
- **`parent`** (`Symbol`) — The key of an existing navigation item to nest this item under. This is the simplest way to add items to existing submenus.
|
|
55
|
+
|
|
56
|
+
## Navigation Contexts
|
|
57
|
+
|
|
58
|
+
The navigation system supports multiple contexts. Spree provides predefined contexts for common use cases, and you can register custom contexts for your specific needs.
|
|
59
|
+
|
|
60
|
+
### Sidebar Navigation
|
|
61
|
+
|
|
62
|
+
The main sidebar navigation:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
sidebar_nav = Spree.admin.navigation.sidebar
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Settings Navigation
|
|
69
|
+
|
|
70
|
+
Navigation in the Settings area:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
settings_nav = Spree.admin.navigation.settings
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Page Tab Navigation
|
|
77
|
+
|
|
78
|
+
Spree provides several predefined tab contexts for common admin pages:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
tax_tabs = Spree.admin.navigation.tax_tabs
|
|
82
|
+
shipping_tabs = Spree.admin.navigation.shipping_tabs
|
|
83
|
+
team_tabs = Spree.admin.navigation.team_tabs
|
|
84
|
+
stock_tabs = Spree.admin.navigation.stock_tabs
|
|
85
|
+
returns_tabs = Spree.admin.navigation.returns_tabs
|
|
86
|
+
developers_tabs = Spree.admin.navigation.developers_tabs
|
|
87
|
+
audit_tabs = Spree.admin.navigation.audit_tabs
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Registering Contexts
|
|
91
|
+
|
|
92
|
+
Use `register_context` to create a new navigation context:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# Returns a Spree::Admin::Navigation instance
|
|
96
|
+
custom_tabs = Spree.admin.navigation.register_context(:custom_tabs)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- **`name`** (`Symbol or String`) — The unique name for the navigation context. Will be converted to a symbol internally.
|
|
100
|
+
|
|
101
|
+
**Returns:** `Spree::Admin::Navigation` - The navigation context instance
|
|
102
|
+
|
|
103
|
+
**Note:** Calling `register_context` multiple times with the same name returns the same instance (idempotent).
|
|
104
|
+
|
|
105
|
+
### Custom Tab Contexts
|
|
106
|
+
|
|
107
|
+
You can create custom tab contexts for your own admin pages using `register_context`:
|
|
108
|
+
|
|
109
|
+
```ruby config/initializers/spree.rb
|
|
110
|
+
Rails.application.config.after_initialize do
|
|
111
|
+
# Register custom tab navigation for your brands page
|
|
112
|
+
brand_tabs = Spree.admin.navigation.register_context(:brand_tabs)
|
|
113
|
+
|
|
114
|
+
brand_tabs.add :active_brands,
|
|
115
|
+
label: 'Active Brands',
|
|
116
|
+
url: -> { spree.admin_brands_path(status: 'active') },
|
|
117
|
+
position: 10,
|
|
118
|
+
active: -> { params[:status] == 'active' }
|
|
119
|
+
|
|
120
|
+
brand_tabs.add :archived_brands,
|
|
121
|
+
label: 'Archived Brands',
|
|
122
|
+
url: -> { spree.admin_brands_path(status: 'archived') },
|
|
123
|
+
position: 20,
|
|
124
|
+
active: -> { params[:status] == 'archived' }
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Then render the tabs in your view using the `render_tab_navigation` helper:
|
|
129
|
+
|
|
130
|
+
```erb app/views/spree/admin/brands/index.html.erb
|
|
131
|
+
<%= render_tab_navigation(:brand_tabs) %>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> **TIP:** Always register custom contexts in your initializer before accessing them. Attempting to access an unregistered context will raise a `NoMethodError`.
|
|
135
|
+
|
|
136
|
+
### Listing All Contexts
|
|
137
|
+
|
|
138
|
+
You can list all registered navigation contexts:
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
# Returns an array of context names (symbols)
|
|
142
|
+
Spree.admin.navigation.contexts
|
|
143
|
+
# => [:sidebar, :settings, :brand_tabs, :inventory_tabs]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Checking If a Context Exists
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
# Check if a context has been created
|
|
150
|
+
Spree.admin.navigation.context?(:brand_tabs)
|
|
151
|
+
# => true or false
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Creating Submenus
|
|
155
|
+
|
|
156
|
+
Add a parent item, then add child items using the `parent` option:
|
|
157
|
+
|
|
158
|
+
```ruby config/initializers/spree.rb
|
|
159
|
+
sidebar_nav.add :brands,
|
|
160
|
+
label: :brands,
|
|
161
|
+
url: :admin_brands_path,
|
|
162
|
+
icon: 'award',
|
|
163
|
+
position: 35,
|
|
164
|
+
if: -> { can?(:manage, Spree::Brand) }
|
|
165
|
+
|
|
166
|
+
sidebar_nav.add :all_brands,
|
|
167
|
+
label: 'All Brands',
|
|
168
|
+
url: :admin_brands_path,
|
|
169
|
+
position: 10,
|
|
170
|
+
parent: :brands,
|
|
171
|
+
active: -> { controller_name == 'brands' }
|
|
172
|
+
|
|
173
|
+
sidebar_nav.add :brand_categories,
|
|
174
|
+
label: 'Brand Categories',
|
|
175
|
+
url: :admin_brand_categories_path,
|
|
176
|
+
position: 20,
|
|
177
|
+
parent: :brands,
|
|
178
|
+
active: -> { controller_name == 'brand_categories' },
|
|
179
|
+
if: -> { can?(:manage, Spree::BrandCategory) }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
> **INFO:** Parent items are automatically marked as active when any of their children are active. You don't need to manually define the `active` option for parent items.
|
|
183
|
+
|
|
184
|
+
## Modifying Existing Navigation
|
|
185
|
+
|
|
186
|
+
### Finding Navigation Items
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
sidebar_nav = Spree.admin.navigation.sidebar
|
|
190
|
+
products_nav = sidebar_nav.find(:products)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Adding to Existing Submenus
|
|
194
|
+
|
|
195
|
+
Use the `parent` option to add an item to an existing submenu:
|
|
196
|
+
|
|
197
|
+
```ruby
|
|
198
|
+
sidebar_nav.add :brands,
|
|
199
|
+
label: :brands,
|
|
200
|
+
url: :admin_brands_path,
|
|
201
|
+
position: 50,
|
|
202
|
+
parent: :products,
|
|
203
|
+
active: -> { controller_name == 'brands' },
|
|
204
|
+
if: -> { can?(:manage, Spree::Brand) }
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Removing Navigation Items
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
sidebar_nav.remove(:vendors)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Updating Navigation Items
|
|
214
|
+
|
|
215
|
+
```ruby
|
|
216
|
+
sidebar_nav.update(:products, label: 'Catalog', icon: 'shopping-cart')
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Replacing Navigation Items
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
sidebar_nav.replace(:products, label: 'Products', icon: 'package') do |products|
|
|
223
|
+
# Define new submenu structure
|
|
224
|
+
end
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Moving Navigation Items
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
# Move to specific position
|
|
231
|
+
sidebar_nav.move(:brands, position: 25)
|
|
232
|
+
|
|
233
|
+
# Move before another item
|
|
234
|
+
sidebar_nav.move(:brands, before: :products)
|
|
235
|
+
|
|
236
|
+
# Move after another item
|
|
237
|
+
sidebar_nav.move(:brands, after: :products)
|
|
238
|
+
|
|
239
|
+
# Move to first position
|
|
240
|
+
sidebar_nav.move(:brands, position: :first)
|
|
241
|
+
|
|
242
|
+
# Move to last position
|
|
243
|
+
sidebar_nav.move(:brands, position: :last)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Advanced Examples
|
|
247
|
+
|
|
248
|
+
### Navigation with Dynamic Badge
|
|
249
|
+
|
|
250
|
+
```ruby
|
|
251
|
+
sidebar_nav.add :orders,
|
|
252
|
+
label: :orders,
|
|
253
|
+
url: :admin_orders_path,
|
|
254
|
+
icon: 'inbox',
|
|
255
|
+
position: 20,
|
|
256
|
+
active: -> { controller_name == 'orders' },
|
|
257
|
+
if: -> { can?(:manage, Spree::Order) },
|
|
258
|
+
badge: -> {
|
|
259
|
+
count = Spree::Order.ready_to_ship.count
|
|
260
|
+
count if count.positive?
|
|
261
|
+
},
|
|
262
|
+
badge_class: 'badge-warning'
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Section Dividers
|
|
266
|
+
|
|
267
|
+
```ruby
|
|
268
|
+
sidebar_nav.add :settings_section,
|
|
269
|
+
section_label: 'Settings',
|
|
270
|
+
position: 90
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Dynamic URLs
|
|
274
|
+
|
|
275
|
+
```ruby
|
|
276
|
+
sidebar_nav.add :store_settings,
|
|
277
|
+
label: :settings,
|
|
278
|
+
url: -> { spree.edit_admin_store_path(section: 'general-settings') },
|
|
279
|
+
icon: 'settings',
|
|
280
|
+
position: 100
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Complex Conditional Display
|
|
284
|
+
|
|
285
|
+
```ruby
|
|
286
|
+
sidebar_nav.add :vendors,
|
|
287
|
+
label: :vendors,
|
|
288
|
+
url: 'https://spreecommerce.org/marketplace-ecommerce/',
|
|
289
|
+
icon: 'heart-handshake',
|
|
290
|
+
position: 35,
|
|
291
|
+
if: -> { can?(:manage, current_store) && !defined?(SpreeEnterprise) },
|
|
292
|
+
badge: 'Enterprise',
|
|
293
|
+
tooltip: 'Multi-Vendor Marketplace is available in the Enterprise Edition',
|
|
294
|
+
target: '_blank'
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Complex Active State Logic
|
|
298
|
+
|
|
299
|
+
```ruby
|
|
300
|
+
sidebar_nav.add :products,
|
|
301
|
+
label: :products,
|
|
302
|
+
url: :admin_products_path,
|
|
303
|
+
icon: 'package',
|
|
304
|
+
position: 30,
|
|
305
|
+
active: -> {
|
|
306
|
+
%w[products external_categories taxons taxonomies option_types option_values
|
|
307
|
+
properties stock_items stock_transfers variants digital_assets].include?(controller_name)
|
|
308
|
+
},
|
|
309
|
+
if: -> { can?(:manage, Spree::Product) }
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Best Practices
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
- **Authorization** — Always use `if: -> { can?(...) }` to ensure users only see navigation items they have permission to access.
|
|
316
|
+
|
|
317
|
+
- **Translations** — Use symbols for labels (e.g., `label: :brands`) to support internationalization via `Spree.t`.
|
|
318
|
+
|
|
319
|
+
- **Active States** — Define clear active state logic using lambdas to highlight the current section properly.
|
|
320
|
+
|
|
321
|
+
- **Positioning** — Use consistent position intervals (e.g., 10, 20, 30) to leave room for future additions.
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
### Common Positioning Reference
|
|
325
|
+
|
|
326
|
+
Main sidebar navigation positions:
|
|
327
|
+
|
|
328
|
+
- Getting Started: 5
|
|
329
|
+
- Home: 10
|
|
330
|
+
- Orders: 20
|
|
331
|
+
- Returns: 25
|
|
332
|
+
- Products: 30
|
|
333
|
+
- Customers: 40
|
|
334
|
+
- Promotions: 50
|
|
335
|
+
- Reports: 60
|
|
336
|
+
- Storefront: 70
|
|
337
|
+
- Integrations: 80
|
|
338
|
+
- Settings Section: 90
|
|
339
|
+
- Settings: 100
|
|
340
|
+
- Admin Users: 110
|
|
341
|
+
|
|
342
|
+
### Troubleshooting
|
|
343
|
+
|
|
344
|
+
<details>
|
|
345
|
+
<summary>Navigation item not appearing</summary>
|
|
346
|
+
|
|
347
|
+
- Restart your server after modifying initializers
|
|
348
|
+
- Check authorization: ensure `if: -> { can?(...) }` returns true
|
|
349
|
+
- Verify the item isn't hidden by a parent's `if` condition
|
|
350
|
+
|
|
351
|
+
</details>
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
<details>
|
|
355
|
+
<summary>Active state not working</summary>
|
|
356
|
+
|
|
357
|
+
- Ensure `active:` lambda returns true/false
|
|
358
|
+
- Check that controller_name or other conditions match correctly
|
|
359
|
+
- For submenus, ensure parent uses same active logic as children
|
|
360
|
+
|
|
361
|
+
</details>
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
<details>
|
|
365
|
+
<summary>Badge not displaying</summary>
|
|
366
|
+
|
|
367
|
+
- Ensure the badge lambda returns a non-nil value
|
|
368
|
+
- Check that the badge value is truthy (empty strings won't display)
|
|
369
|
+
- For numeric badges, ensure the count is greater than 0
|
|
370
|
+
|
|
371
|
+
</details>
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Previous versions
|
|
377
|
+
|
|
378
|
+
> **WARNING:** The following documentation applies to Spree 5.1 and earlier. If you're using Spree 5.2+, please refer to the documentation above.
|
|
379
|
+
|
|
380
|
+
### How it works
|
|
381
|
+
|
|
382
|
+
The admin navigation system works through injection points defined throughout the sidebar. You can inject custom navigation items into these predefined locations, add new top-level menu items, or create nested submenus.
|
|
383
|
+
|
|
384
|
+
### Navigation Injection Points
|
|
385
|
+
|
|
386
|
+
The main navigation file is located at `admin/app/views/spree/admin/shared/sidebar/_store_nav.html.erb` and provides several injection points:
|
|
387
|
+
|
|
388
|
+
#### Available Injection Points
|
|
389
|
+
|
|
390
|
+
<details>
|
|
391
|
+
<summary>store_nav_partials</summary>
|
|
392
|
+
|
|
393
|
+
`store_nav_partials`
|
|
394
|
+
|
|
395
|
+
Injects navigation items into the main sidebar navigation, after the Reports item and before the Storefront and Integrations sections.
|
|
396
|
+
|
|
397
|
+
<img src="/images/developer/admin/store_nav_partials.png" alt="Main navigation injection point" />
|
|
398
|
+
|
|
399
|
+
This is the primary injection point for adding custom top-level navigation items.
|
|
400
|
+
|
|
401
|
+
</details>
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
<details>
|
|
405
|
+
<summary>store_products_nav_partials</summary>
|
|
406
|
+
|
|
407
|
+
`store_products_nav_partials`
|
|
408
|
+
|
|
409
|
+
Injects navigation items into the Products submenu, after the Properties item.
|
|
410
|
+
|
|
411
|
+
Use this to add product-related navigation items that logically belong under the Products section.
|
|
412
|
+
|
|
413
|
+
</details>
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
<details>
|
|
417
|
+
<summary>store_orders_nav_partials</summary>
|
|
418
|
+
|
|
419
|
+
`store_orders_nav_partials`
|
|
420
|
+
|
|
421
|
+
Injects navigation items into the Orders submenu, after the Draft Orders item.
|
|
422
|
+
|
|
423
|
+
Use this to add order-related navigation items.
|
|
424
|
+
|
|
425
|
+
</details>
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
<details>
|
|
429
|
+
<summary>store_settings_nav_partials</summary>
|
|
430
|
+
|
|
431
|
+
`store_settings_nav_partials`
|
|
432
|
+
|
|
433
|
+
Injects navigation items into the Settings section, after the Policies item.
|
|
434
|
+
|
|
435
|
+
Use this when Settings mode is active to add configuration-related items.
|
|
436
|
+
|
|
437
|
+
</details>
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
<details>
|
|
441
|
+
<summary>settings_nav_partials</summary>
|
|
442
|
+
|
|
443
|
+
`settings_nav_partials`
|
|
444
|
+
|
|
445
|
+
Injects navigation items at the end of the Settings section.
|
|
446
|
+
|
|
447
|
+
Use this to add additional settings-related navigation items.
|
|
448
|
+
|
|
449
|
+
</details>
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
### Using the nav_item Helper
|
|
453
|
+
|
|
454
|
+
The `nav_item` helper method is provided by `Spree::Admin::NavigationHelper` and makes it easy to create properly formatted navigation items.
|
|
455
|
+
|
|
456
|
+
### Method Signature
|
|
457
|
+
|
|
458
|
+
```ruby
|
|
459
|
+
nav_item(label = nil, url, icon: nil, active: nil, data: {})
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### Parameters
|
|
463
|
+
|
|
464
|
+
- **`label`** (`String`) — The text label for the navigation item. Can be HTML-safe content.
|
|
465
|
+
|
|
466
|
+
- **`url`** (`String`) — The URL the navigation item links to. Use the `spree.` route helper prefix.
|
|
467
|
+
|
|
468
|
+
- **`icon`** (`String`) — Optional icon name from [Tabler Icons](https://tabler.io/icons). The icon will be displayed before the label.
|
|
469
|
+
|
|
470
|
+
- **`active`** (`Boolean`) — Manually set whether the link should be marked as active. If not specified, it will be auto-detected based on the current URL.
|
|
471
|
+
|
|
472
|
+
- **`data`** (`Hash`) — Additional data attributes to add to the link element.
|
|
473
|
+
|
|
474
|
+
#### Basic Usage
|
|
475
|
+
|
|
476
|
+
```erb
|
|
477
|
+
<%= nav_item(Spree.t(:custom_section), spree.admin_custom_path, icon: 'star') %>
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### With Active State
|
|
481
|
+
|
|
482
|
+
```erb
|
|
483
|
+
<%= nav_item(
|
|
484
|
+
Spree.t(:inventory),
|
|
485
|
+
spree.admin_inventory_path,
|
|
486
|
+
icon: 'boxes',
|
|
487
|
+
active: controller_name == 'inventory'
|
|
488
|
+
) %>
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
#### With Block Content
|
|
492
|
+
|
|
493
|
+
```erb
|
|
494
|
+
<%= nav_item(nil, spree.admin_dashboard_path, icon: 'home') do %>
|
|
495
|
+
<%= icon 'home' %>
|
|
496
|
+
<%= Spree.t(:dashboard) %>
|
|
497
|
+
<span class="badge ml-auto">New</span>
|
|
498
|
+
<% end %>
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Adding a Simple Navigation Item
|
|
502
|
+
|
|
503
|
+
Let's add a new "Inventory" navigation item to the main sidebar.
|
|
504
|
+
|
|
505
|
+
#### Step 1: Create the Partial
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
mkdir -p app/views/spree/admin/shared
|
|
509
|
+
touch app/views/spree/admin/shared/_inventory_nav.html.erb
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
#### Step 2: Add Navigation Code
|
|
513
|
+
|
|
514
|
+
```erb app/views/spree/admin/shared/_inventory_nav.html.erb
|
|
515
|
+
<% if can?(:manage, Spree::Inventory) %>
|
|
516
|
+
<%= nav_item(
|
|
517
|
+
Spree.t(:inventory),
|
|
518
|
+
spree.admin_inventory_index_path,
|
|
519
|
+
icon: 'boxes',
|
|
520
|
+
active: controller_name == 'inventory'
|
|
521
|
+
) %>
|
|
522
|
+
<% end %>
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
> **TIP:** Always wrap your navigation items with authorization checks using `can?()` to ensure users only see menu items they have permission to access.
|
|
526
|
+
|
|
527
|
+
#### Step 3: Register the Partial
|
|
528
|
+
|
|
529
|
+
Add this to your `config/initializers/spree.rb`:
|
|
530
|
+
|
|
531
|
+
**Spree 5.2+:**
|
|
532
|
+
|
|
533
|
+
```ruby config/initializers/spree.rb
|
|
534
|
+
Rails.application.config.after_initialize do
|
|
535
|
+
Spree.admin.navigation.store << 'spree/admin/shared/inventory_nav'
|
|
536
|
+
end
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Spree 5.1 and below:**
|
|
540
|
+
|
|
541
|
+
```ruby config/initializers/spree.rb
|
|
542
|
+
Rails.application.config.spree_admin.store_nav_partials << 'spree/admin/shared/inventory_nav'
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
#### Step 4: Add Translations
|
|
547
|
+
|
|
548
|
+
In your `config/locales/en.yml`:
|
|
549
|
+
|
|
550
|
+
```yaml config/locales/en.yml
|
|
551
|
+
en:
|
|
552
|
+
spree:
|
|
553
|
+
inventory: "Inventory"
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
#### Step 5: Restart Your Server
|
|
557
|
+
|
|
558
|
+
Restart your web server to load the initializer changes. The navigation item should now appear in the sidebar.
|
|
559
|
+
|
|
560
|
+
### Creating Nested Navigation (Submenus)
|
|
561
|
+
|
|
562
|
+
To create a navigation item with a submenu, you need to use the `nav-submenu` class and manage the visibility based on the active state.
|
|
563
|
+
|
|
564
|
+
#### Example: Adding a Nested Menu
|
|
565
|
+
|
|
566
|
+
```erb
|
|
567
|
+
<% inventory_active = %w[inventory warehouses stock_movements].include?(controller_name) %>
|
|
568
|
+
|
|
569
|
+
<% if can?(:manage, Spree::Inventory) %>
|
|
570
|
+
<%= nav_item(
|
|
571
|
+
Spree.t(:inventory),
|
|
572
|
+
spree.admin_inventory_index_path,
|
|
573
|
+
icon: 'boxes',
|
|
574
|
+
active: inventory_active
|
|
575
|
+
) %>
|
|
576
|
+
|
|
577
|
+
<ul class="nav-submenu <% unless inventory_active %>d-none<% end %>">
|
|
578
|
+
<% if can?(:manage, Spree::Warehouse) %>
|
|
579
|
+
<%= nav_item(
|
|
580
|
+
Spree.t(:warehouses),
|
|
581
|
+
spree.admin_warehouses_path,
|
|
582
|
+
active: controller_name == 'warehouses'
|
|
583
|
+
) %>
|
|
584
|
+
<% end %>
|
|
585
|
+
|
|
586
|
+
<% if can?(:manage, Spree::StockMovement) %>
|
|
587
|
+
<%= nav_item(
|
|
588
|
+
Spree.t(:stock_movements),
|
|
589
|
+
spree.admin_stock_movements_path,
|
|
590
|
+
active: controller_name == 'stock_movements'
|
|
591
|
+
) %>
|
|
592
|
+
<% end %>
|
|
593
|
+
|
|
594
|
+
<%= render_admin_partials(:store_inventory_nav_partials) %>
|
|
595
|
+
</ul>
|
|
596
|
+
<% end %>
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
#### Key Points for Submenus
|
|
600
|
+
|
|
601
|
+
1. **Active State Variable**: Define a variable to track when any item in the menu group is active:
|
|
602
|
+
```erb
|
|
603
|
+
<% inventory_active = %w[inventory warehouses stock_movements].include?(controller_name) %>
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
2. **Parent Navigation Item**: Use the active state variable for the parent item:
|
|
607
|
+
```erb
|
|
608
|
+
<%= nav_item(..., active: inventory_active) %>
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
3. **Submenu Container**: Use the `nav-submenu` class and conditionally add `d-none` to hide when inactive:
|
|
612
|
+
```erb
|
|
613
|
+
<ul class="nav-submenu <% unless inventory_active %>d-none<% end %>">
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
4. **Child Items**: Add child navigation items within the submenu:
|
|
617
|
+
```erb
|
|
618
|
+
<%= nav_item(Spree.t(:child_item), spree.admin_child_path) %>
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
5. **Nested Injection Point** (Optional): Add an injection point within the submenu for further extensibility:
|
|
622
|
+
```erb
|
|
623
|
+
<%= render_admin_partials(:store_inventory_nav_partials) %>
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Advanced Examples
|
|
627
|
+
|
|
628
|
+
#### Navigation with Badge
|
|
629
|
+
|
|
630
|
+
```erb
|
|
631
|
+
<%= nav_item(nil, spree.admin_orders_path, icon: 'inbox', active: orders_active) do %>
|
|
632
|
+
<%= icon 'inbox' %>
|
|
633
|
+
<%= Spree.t(:orders) %>
|
|
634
|
+
<span class="badge ml-auto"><%= pending_orders_count %></span>
|
|
635
|
+
<% end %>
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
#### Navigation with Complex Active Logic
|
|
639
|
+
|
|
640
|
+
```erb
|
|
641
|
+
<% products_active = %w[products external_categories taxons taxonomies option_types option_values properties stock_items stock_transfers].include?(controller_name) || request.path.include?('products') %>
|
|
642
|
+
|
|
643
|
+
<%= nav_item(
|
|
644
|
+
Spree.t(:products),
|
|
645
|
+
spree.admin_products_path,
|
|
646
|
+
icon: 'package',
|
|
647
|
+
active: products_active
|
|
648
|
+
) %>
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
#### Extending Existing Submenus
|
|
652
|
+
|
|
653
|
+
To add an item to an existing submenu (e.g., Products), use the appropriate injection point:
|
|
654
|
+
|
|
655
|
+
**Create:** `app/views/spree/admin/shared/_custom_products_nav.html.erb`
|
|
656
|
+
|
|
657
|
+
```erb
|
|
658
|
+
<% if can?(:manage, Spree::CustomProductFeature) %>
|
|
659
|
+
<%= nav_item(
|
|
660
|
+
Spree.t(:custom_feature),
|
|
661
|
+
spree.admin_custom_product_feature_path,
|
|
662
|
+
active: controller_name == 'custom_product_features'
|
|
663
|
+
) %>
|
|
664
|
+
<% end %>
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**Register in** `config/initializers/spree.rb`:
|
|
668
|
+
|
|
669
|
+
**Spree 5.2+:**
|
|
670
|
+
|
|
671
|
+
```ruby config/initializers/spree.rb
|
|
672
|
+
Rails.application.config.after_initialize do
|
|
673
|
+
Spree.admin.navigation.store_products << 'spree/admin/shared/custom_products_nav'
|
|
674
|
+
end
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**Spree 5.1 and below:**
|
|
678
|
+
|
|
679
|
+
```ruby config/initializers/spree.rb
|
|
680
|
+
Rails.application.config.spree_admin.store_products_nav_partials << 'spree/admin/shared/custom_products_nav'
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
### Navigation in Settings Mode
|
|
685
|
+
|
|
686
|
+
When the admin is in "Settings mode" (the dedicated settings view), use the `settings_nav_partials` injection point:
|
|
687
|
+
|
|
688
|
+
```erb
|
|
689
|
+
<% if settings_active? %>
|
|
690
|
+
<!-- Settings mode is active -->
|
|
691
|
+
<%= nav_item(Spree.t(:custom_settings), spree.edit_admin_store_path(section: 'custom-settings'), icon: 'adjustments') %>
|
|
692
|
+
<% end %>
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Register with:
|
|
696
|
+
|
|
697
|
+
**Spree 5.2+:**
|
|
698
|
+
|
|
699
|
+
```ruby config/initializers/spree.rb
|
|
700
|
+
Rails.application.config.after_initialize do
|
|
701
|
+
Spree.admin.navigation.settings << 'spree/admin/shared/custom_settings_nav'
|
|
702
|
+
end
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Spree 5.1 and below:**
|
|
706
|
+
|
|
707
|
+
```ruby config/initializers/spree.rb
|
|
708
|
+
Rails.application.config.spree_admin.settings_nav_partials << 'spree/admin/shared/custom_settings_nav'
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
### Best Practices
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
- **Authorization** — Always use `can?()` checks to ensure users only see navigation items they have permission to access.
|
|
716
|
+
|
|
717
|
+
- **Translations** — Use `Spree.t()` for all navigation labels to support internationalization.
|
|
718
|
+
|
|
719
|
+
- **Icons** — Use consistent icons from [Tabler Icons](https://tabler.io/icons) that match Spree's design language.
|
|
720
|
+
|
|
721
|
+
- **Active States** — Define clear active state logic to highlight the current section in the navigation.
|
|
722
|
+
|
|
723
|
+
- **Route Helpers** — Always use `spree.` prefixed route helpers to reference admin routes correctly.
|
|
724
|
+
|
|
725
|
+
- **Injection Points** — Add your own injection points in submenus to allow further extensions by other developers.
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
### Common Patterns
|
|
729
|
+
|
|
730
|
+
#### Multiple Controller Check
|
|
731
|
+
|
|
732
|
+
```erb
|
|
733
|
+
<% active = %w[orders shipments payments].include?(controller_name) %>
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
#### Path-based Check
|
|
737
|
+
|
|
738
|
+
```erb
|
|
739
|
+
<% active = request.path.include?('products') %>
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
#### Controller and Action Check
|
|
743
|
+
|
|
744
|
+
```erb
|
|
745
|
+
<% active = controller_name == 'dashboard' && action_name == 'show' %>
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
#### Parameters-based Check
|
|
749
|
+
|
|
750
|
+
```erb
|
|
751
|
+
<% active = params[:section] == 'general-settings' %>
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
### Troubleshooting
|
|
755
|
+
|
|
756
|
+
<details>
|
|
757
|
+
<summary>Navigation item not appearing</summary>
|
|
758
|
+
|
|
759
|
+
- Ensure you've restarted your web server after adding the initializer
|
|
760
|
+
- Check that the authorization check (`can?()`) is passing
|
|
761
|
+
- Verify the partial path is correct (without `_` prefix and `.html.erb` suffix)
|
|
762
|
+
- Check that the route helper exists and is correct
|
|
763
|
+
|
|
764
|
+
</details>
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
<details>
|
|
768
|
+
<summary>Icon not displaying</summary>
|
|
769
|
+
|
|
770
|
+
- Verify the icon name exists in [Tabler Icons](https://tabler.io/icons)
|
|
771
|
+
- Check that you're using the correct parameter name: `icon:` not `icon_name:`
|
|
772
|
+
- Ensure the icon name is a string, e.g., `icon: 'boxes'`
|
|
773
|
+
|
|
774
|
+
</details>
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
<details>
|
|
778
|
+
<summary>Submenu not showing/hiding properly</summary>
|
|
779
|
+
|
|
780
|
+
- Ensure the active state variable includes all relevant controller names
|
|
781
|
+
- Check that the `nav-submenu` class is applied to the `<ul>` element
|
|
782
|
+
- Verify the `d-none` class is conditionally added when not active
|
|
783
|
+
- Make sure the parent nav item uses the same active state variable
|
|
784
|
+
|
|
785
|
+
</details>
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
<details>
|
|
789
|
+
<summary>Translation missing</summary>
|
|
790
|
+
|
|
791
|
+
- Add the translation key to your locale file
|
|
792
|
+
- Ensure the locale file is in the correct location
|
|
793
|
+
- Restart your server after adding translations
|
|
794
|
+
- Check for typos in the translation key
|
|
795
|
+
|
|
796
|
+
</details>
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
### Related Documentation
|
|
800
|
+
|
|
801
|
+
- [Extending Admin UI](/developer/admin/extending-ui) - Learn about other UI injection points
|
|
802
|
+
- [Admin Tables](/developer/admin/tables) - Customize admin list views
|
|
803
|
+
- [Helper Methods](/developer/admin/helper-methods) - Explore other admin helper methods
|
|
804
|
+
- [Permissions](/developer/customization/permissions) - Understand the authorization system
|
|
805
|
+
- [Customization Quickstart](/developer/customization/quickstart) - Overview of all customization options
|