@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,352 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Storefront
|
|
3
|
+
description: Learn how to create storefront pages for your Brands feature
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
In this tutorial, we'll create storefront pages to display brands to your customers. We'll start with a simple Rails approach using controllers and views, then in the next guide we'll connect it to Page Builder.
|
|
7
|
+
|
|
8
|
+
> **INFO:** This guide assumes you've completed the [Model](/developer/tutorial/model), [Admin](/developer/tutorial/admin), [Rich Text](/developer/tutorial/rich-text), [File Uploads](/developer/tutorial/file-uploads), and [Extending Core Models](/developer/tutorial/extending-models) tutorials. You should have a working `Spree::Brand` model with products associated to brands.
|
|
9
|
+
|
|
10
|
+
## What We're Building
|
|
11
|
+
|
|
12
|
+
By the end of this tutorial, you'll have:
|
|
13
|
+
|
|
14
|
+
- A custom theme for your store
|
|
15
|
+
- A brands listing page at `/brands`
|
|
16
|
+
- Individual brand pages at `/brands/:id`
|
|
17
|
+
- Styled views using Tailwind CSS
|
|
18
|
+
|
|
19
|
+
## Step 1: Create a Custom Theme
|
|
20
|
+
|
|
21
|
+
Before adding custom views, create your own theme. This is important because:
|
|
22
|
+
|
|
23
|
+
- **Upgrade safety** - Your customizations won't be overwritten when updating Spree
|
|
24
|
+
- **Clean separation** - Your code stays separate from Spree's default theme
|
|
25
|
+
- **Full control** - You get a complete copy of all templates to customize
|
|
26
|
+
|
|
27
|
+
Run the theme generator:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bin/rails g spree:storefront:theme MyStore
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This creates:
|
|
34
|
+
- `app/views/themes/my_store/` - Copy of all storefront templates
|
|
35
|
+
- `app/models/spree/themes/my_store.rb` - Theme configuration class
|
|
36
|
+
|
|
37
|
+
The generator also updates your `config/initializers/spree.rb`:
|
|
38
|
+
|
|
39
|
+
```ruby config/initializers/spree.rb
|
|
40
|
+
Spree.page_builder.themes << Spree::Themes::MyStore
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Activate Your Theme
|
|
44
|
+
|
|
45
|
+
1. Go to **Admin → Storefront → Themes**
|
|
46
|
+
2. Find your new theme in the "Add new theme" section
|
|
47
|
+
3. Click **Add** to activate it
|
|
48
|
+
|
|
49
|
+
> **WARNING:** Always create a custom theme for production stores. Never modify the default theme directly - your changes will be lost during Spree upgrades.
|
|
50
|
+
|
|
51
|
+
## Step 2: Add Routes
|
|
52
|
+
|
|
53
|
+
Now let's add routes for our brand pages. Create or update your routes file:
|
|
54
|
+
|
|
55
|
+
```ruby config/routes.rb
|
|
56
|
+
Spree::Core::Engine.add_routes do
|
|
57
|
+
scope '(:locale)', locale: /#{Spree.available_locales.join('|')}/, defaults: { locale: nil } do
|
|
58
|
+
resources :brands, only: [:index, :show]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> **INFO:** The `scope '(:locale)'` wrapper enables internationalization - URLs like `/fr/brands` will work automatically if you have French locale enabled.
|
|
64
|
+
|
|
65
|
+
## Step 3: Create the Controller
|
|
66
|
+
|
|
67
|
+
Create a controller that inherits from `Spree::StoreController`. This base controller provides:
|
|
68
|
+
|
|
69
|
+
- Access to `current_store`, `current_theme`, `current_currency`
|
|
70
|
+
- User authentication helpers
|
|
71
|
+
- Storefront layout and helpers
|
|
72
|
+
- SEO and meta tag support
|
|
73
|
+
|
|
74
|
+
```ruby app/controllers/spree/brands_controller.rb
|
|
75
|
+
module Spree
|
|
76
|
+
class BrandsController < StoreController
|
|
77
|
+
before_action :load_brand, only: [:show]
|
|
78
|
+
|
|
79
|
+
def index
|
|
80
|
+
@brands = Spree::Brand.order(:name)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def show
|
|
84
|
+
@products = @brand.products.active(current_currency).includes(storefront_products_includes)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def load_brand
|
|
90
|
+
@brand = Spree::Brand.find(params[:id])
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Override to set page title for SEO
|
|
94
|
+
def accurate_title
|
|
95
|
+
if @brand
|
|
96
|
+
@brand.name
|
|
97
|
+
else
|
|
98
|
+
Spree.t(:brands)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Key Points
|
|
106
|
+
|
|
107
|
+
- **Inherit from `Spree::StoreController`** - Not `ApplicationController`. This gives you access to all storefront functionality.
|
|
108
|
+
- **Use `current_store`** - Always scope queries to the current store for multi-store support.
|
|
109
|
+
- **Override `accurate_title`** - This sets the page `<title>` tag.
|
|
110
|
+
|
|
111
|
+
> **TIP:** Want SEO-friendly URLs like `/brands/nike` instead of `/brands/123`? See the [SEO](/developer/tutorial/seo) tutorial to add slug support.
|
|
112
|
+
|
|
113
|
+
## Step 4: Create the Views
|
|
114
|
+
|
|
115
|
+
Storefront views live in your theme directory. Create the brands views in your custom theme:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
mkdir -p app/views/themes/my_store/spree/brands
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Your theme's view structure:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
app/views/themes/my_store/spree/brands/
|
|
125
|
+
├── index.html.erb
|
|
126
|
+
├── show.html.erb
|
|
127
|
+
└── _brand_card.html.erb
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Brands Listing Page
|
|
131
|
+
|
|
132
|
+
```erb app/views/themes/my_store/spree/brands/index.html.erb
|
|
133
|
+
<div class="page-container py-8">
|
|
134
|
+
<h1 class="text-2xl lg:text-3xl font-medium mb-8">
|
|
135
|
+
<%= Spree.t(:brands) %>
|
|
136
|
+
</h1>
|
|
137
|
+
|
|
138
|
+
<% if @brands.any? %>
|
|
139
|
+
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
|
|
140
|
+
<% @brands.each do |brand| %>
|
|
141
|
+
<%= render 'brand_card', brand: brand %>
|
|
142
|
+
<% end %>
|
|
143
|
+
</div>
|
|
144
|
+
<% else %>
|
|
145
|
+
<p class="text-neutral-600">
|
|
146
|
+
<%= Spree.t(:no_brands_found) %>
|
|
147
|
+
</p>
|
|
148
|
+
<% end %>
|
|
149
|
+
</div>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Brand Card Partial
|
|
153
|
+
|
|
154
|
+
```erb app/views/themes/my_store/spree/brands/_brand_card.html.erb
|
|
155
|
+
<%= link_to spree.brand_path(brand),
|
|
156
|
+
class: 'block group',
|
|
157
|
+
data: { turbo_frame: '_top' } do %>
|
|
158
|
+
<div class="aspect-square bg-accent rounded-lg overflow-hidden mb-3">
|
|
159
|
+
<% if brand.logo.attached? %>
|
|
160
|
+
<%= spree_image_tag brand.logo,
|
|
161
|
+
width: 300,
|
|
162
|
+
height: 300,
|
|
163
|
+
class: 'w-full h-full object-contain p-6 group-hover:scale-105 transition-transform',
|
|
164
|
+
alt: brand.name %>
|
|
165
|
+
<% else %>
|
|
166
|
+
<div class="w-full h-full flex items-center justify-center">
|
|
167
|
+
<span class="text-4xl font-medium text-neutral-400">
|
|
168
|
+
<%= brand.name.first.upcase %>
|
|
169
|
+
</span>
|
|
170
|
+
</div>
|
|
171
|
+
<% end %>
|
|
172
|
+
</div>
|
|
173
|
+
<h2 class="font-medium group-hover:text-primary transition-colors">
|
|
174
|
+
<%= brand.name %>
|
|
175
|
+
</h2>
|
|
176
|
+
<% end %>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Single Brand Page
|
|
180
|
+
|
|
181
|
+
```erb app/views/themes/my_store/spree/brands/show.html.erb
|
|
182
|
+
<div class="page-container py-8">
|
|
183
|
+
<%# Brand Header %>
|
|
184
|
+
<div class="flex flex-col md:flex-row gap-8 mb-12">
|
|
185
|
+
<% if @brand.logo.attached? %>
|
|
186
|
+
<div class="w-32 h-32 bg-accent rounded-lg flex-shrink-0">
|
|
187
|
+
<%= spree_image_tag @brand.logo,
|
|
188
|
+
width: 128,
|
|
189
|
+
height: 128,
|
|
190
|
+
class: 'w-full h-full object-contain p-4',
|
|
191
|
+
alt: @brand.name %>
|
|
192
|
+
</div>
|
|
193
|
+
<% end %>
|
|
194
|
+
|
|
195
|
+
<div>
|
|
196
|
+
<h1 class="text-2xl lg:text-3xl font-medium mb-4">
|
|
197
|
+
<%= @brand.name %>
|
|
198
|
+
</h1>
|
|
199
|
+
|
|
200
|
+
<% if @brand.description.present? %>
|
|
201
|
+
<div class="prose max-w-none text-neutral-600">
|
|
202
|
+
<%= @brand.description %>
|
|
203
|
+
</div>
|
|
204
|
+
<% end %>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
<%# Products Grid %>
|
|
209
|
+
<% if @products.any? %>
|
|
210
|
+
<h2 class="text-xl font-medium mb-6">
|
|
211
|
+
<%= Spree.t(:products_by_brand, brand: @brand.name) %>
|
|
212
|
+
</h2>
|
|
213
|
+
|
|
214
|
+
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
|
|
215
|
+
<%= render 'spree/shared/products', products: @products %>
|
|
216
|
+
</div>
|
|
217
|
+
<% else %>
|
|
218
|
+
<p class="text-neutral-600">
|
|
219
|
+
<%= Spree.t(:no_products_found) %>
|
|
220
|
+
</p>
|
|
221
|
+
<% end %>
|
|
222
|
+
</div>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Step 5: Add Translations
|
|
226
|
+
|
|
227
|
+
Add the necessary translations:
|
|
228
|
+
|
|
229
|
+
```yaml config/locales/en.yml
|
|
230
|
+
en:
|
|
231
|
+
spree:
|
|
232
|
+
brands: Brands
|
|
233
|
+
no_brands_found: No brands found.
|
|
234
|
+
products_by_brand: "Products by %{brand}"
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Step 6: Add Navigation Link (Optional)
|
|
238
|
+
|
|
239
|
+
To add a link to brands in your header navigation, you can use the Admin Dashboard:
|
|
240
|
+
|
|
241
|
+
1. Go to **Storefront → Theme Editor**
|
|
242
|
+
2. Click on **Header** section
|
|
243
|
+
3. Add a new navigation link pointing to `/brands`
|
|
244
|
+
|
|
245
|
+
Or programmatically in your header partial:
|
|
246
|
+
|
|
247
|
+
```erb
|
|
248
|
+
<%= link_to Spree.t(:brands), spree.brands_path, class: 'nav-link' %>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Understanding the View Structure
|
|
252
|
+
|
|
253
|
+
### Theme Directory
|
|
254
|
+
|
|
255
|
+
Views are organized by theme in `app/views/themes/{theme_name}/spree/`:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
app/views/themes/my_store/spree/
|
|
259
|
+
├── brands/ # Your brand views
|
|
260
|
+
├── products/ # Product views
|
|
261
|
+
├── shared/ # Shared partials
|
|
262
|
+
└── page_sections/ # Page Builder sections
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
> **INFO:** Spree looks for views in your active theme first. If a view isn't found, it falls back to the default theme. This means you only need to copy and customize the files you want to change.
|
|
266
|
+
|
|
267
|
+
### Key CSS Classes
|
|
268
|
+
|
|
269
|
+
Spree's default theme uses these common patterns:
|
|
270
|
+
|
|
271
|
+
| Class | Purpose |
|
|
272
|
+
|-------|---------|
|
|
273
|
+
| `page-container` | Centered container with max-width and padding |
|
|
274
|
+
| `bg-accent` | Uses theme's accent background color |
|
|
275
|
+
| `text-primary` | Uses theme's primary text color |
|
|
276
|
+
| `btn-primary` | Primary button style |
|
|
277
|
+
| `btn-secondary` | Secondary button style |
|
|
278
|
+
|
|
279
|
+
### Using Spree Helpers
|
|
280
|
+
|
|
281
|
+
```erb
|
|
282
|
+
<%# Image helper with automatic optimization %>
|
|
283
|
+
<%= spree_image_tag image, width: 400, height: 400 %>
|
|
284
|
+
|
|
285
|
+
<%# URL helpers %>
|
|
286
|
+
<%= spree.brands_path %>
|
|
287
|
+
<%= spree.brand_path(brand) %>
|
|
288
|
+
|
|
289
|
+
<%# Translation helper %>
|
|
290
|
+
<%= Spree.t(:brands) %>
|
|
291
|
+
|
|
292
|
+
<%# Price display %>
|
|
293
|
+
<%= display_price(product.price_in(current_currency)) %>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Testing Your Pages
|
|
297
|
+
|
|
298
|
+
Start your Rails server and visit:
|
|
299
|
+
|
|
300
|
+
- `http://localhost:3000/brands` - Brand listing
|
|
301
|
+
- `http://localhost:3000/brands/1` - Single brand (using the brand's ID)
|
|
302
|
+
|
|
303
|
+
> **TIP:** Want SEO-friendly URLs like `/brands/nike` instead of `/brands/1`? See the [SEO](/developer/tutorial/seo) tutorial to add slug support, meta tags, and Open Graph data.
|
|
304
|
+
|
|
305
|
+
## What's Next?
|
|
306
|
+
|
|
307
|
+
You now have working brand pages using standard Rails MVC patterns. In the next guide, [Testing](/developer/tutorial/testing), we'll write automated tests for your feature to make sure it works as expected, also in the future when you make changes to your code.
|
|
308
|
+
|
|
309
|
+
## Complete Controller Example
|
|
310
|
+
|
|
311
|
+
Here's the complete controller with all features:
|
|
312
|
+
|
|
313
|
+
```ruby app/controllers/spree/brands_controller.rb
|
|
314
|
+
module Spree
|
|
315
|
+
class BrandsController < StoreController
|
|
316
|
+
before_action :load_brand, only: [:show]
|
|
317
|
+
|
|
318
|
+
def index
|
|
319
|
+
@brands = Spree::Brand.order(:name)
|
|
320
|
+
.page(params[:page])
|
|
321
|
+
.per(24)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def show
|
|
325
|
+
@products = @brand.products.active(current_currency).includes(storefront_products_includes)
|
|
326
|
+
@page_description = @brand.description&.to_plain_text&.truncate(160)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
private
|
|
330
|
+
|
|
331
|
+
def load_brand
|
|
332
|
+
@brand = Spree::Brand.find(params[:id])
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def accurate_title
|
|
336
|
+
if @brand
|
|
337
|
+
@brand.name
|
|
338
|
+
else
|
|
339
|
+
Spree.t(:brands)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
> **INFO:** To use SEO-friendly slugs like `/brands/nike` instead of `/brands/1`, follow the [SEO](/developer/tutorial/seo) tutorial.
|
|
347
|
+
|
|
348
|
+
## Related Documentation
|
|
349
|
+
|
|
350
|
+
- [Storefront Overview](/developer/storefront/storefront) - Storefront architecture
|
|
351
|
+
- [Custom CSS](/developer/storefront/custom-css) - Styling with Tailwind
|
|
352
|
+
- [Helper Methods](/developer/storefront/helper-methods) - Available helpers
|