@spree/docs 0.1.0 → 0.1.2
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/dist/api-reference/store-api/errors.md +2 -2
- package/dist/api-reference/store-api/idempotency.md +1 -1
- package/dist/api-reference/store-api/localization.md +4 -4
- package/dist/api-reference/store-api/metadata.md +2 -2
- package/dist/api-reference/store.yaml +10599 -0
- package/dist/api-reference/storefront/authentication.md +2 -2
- package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +2 -2
- package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +2 -2
- package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +8 -8
- package/dist/api-reference/v2/introduction.md +2 -2
- package/dist/api-reference/webhooks-events.md +2 -2
- package/dist/developer/admin/admin.md +18 -18
- package/dist/developer/admin/components.md +1 -1
- package/dist/developer/admin/extending-ui.md +26 -26
- package/dist/developer/admin/helper-methods.md +2 -2
- package/dist/developer/admin/navigation.md +5 -5
- package/dist/developer/admin/tables.md +4 -4
- package/dist/developer/cli/quickstart.md +2 -2
- package/dist/developer/contributing/creating-an-extension.md +12 -12
- package/dist/developer/contributing/quickstart.md +1 -1
- package/dist/developer/core-concepts/addresses.md +11 -11
- package/dist/developer/core-concepts/adjustments.md +8 -8
- package/dist/developer/core-concepts/architecture.md +21 -21
- package/dist/developer/core-concepts/calculators.md +4 -4
- package/dist/developer/core-concepts/customers.md +9 -9
- package/dist/developer/core-concepts/events.md +5 -5
- package/dist/developer/core-concepts/inventory.md +5 -5
- package/dist/developer/core-concepts/markets.md +10 -10
- package/dist/developer/core-concepts/media.md +3 -3
- package/dist/developer/core-concepts/metafields.md +6 -6
- package/dist/developer/core-concepts/orders.md +14 -14
- package/dist/developer/core-concepts/payments.md +9 -9
- package/dist/developer/core-concepts/pricing.md +10 -10
- package/dist/developer/core-concepts/products.md +10 -10
- package/dist/developer/core-concepts/promotions.md +5 -5
- package/dist/developer/core-concepts/reports.md +2 -2
- package/dist/developer/core-concepts/search-filtering.md +7 -7
- package/dist/developer/core-concepts/shipments.md +13 -13
- package/dist/developer/core-concepts/slugs.md +3 -3
- package/dist/developer/core-concepts/staff-roles.md +7 -7
- package/dist/developer/core-concepts/store-credits-gift-cards.md +4 -4
- package/dist/developer/core-concepts/stores.md +15 -15
- package/dist/developer/core-concepts/taxes.md +11 -11
- package/dist/developer/core-concepts/translations.md +6 -6
- package/dist/developer/core-concepts/users.md +12 -12
- package/dist/developer/core-concepts/webhooks.md +8 -8
- package/dist/developer/create-spree-app/quickstart.md +5 -5
- package/dist/developer/customization/api.md +2 -2
- package/dist/developer/customization/authentication.md +2 -2
- package/dist/developer/customization/checkout.md +7 -7
- package/dist/developer/customization/decorators.md +24 -24
- package/dist/developer/customization/dependencies.md +1 -1
- package/dist/developer/customization/metadata.md +3 -3
- package/dist/developer/customization/permissions.md +1 -1
- package/dist/developer/customization/quickstart.md +9 -9
- package/dist/developer/customization/v4/checkout.md +3 -3
- package/dist/developer/customization/v4/deface.md +1 -1
- package/dist/developer/deployment/assets.md +1 -1
- package/dist/developer/deployment/aws.md +5 -5
- package/dist/developer/deployment/docker.md +2 -2
- package/dist/developer/deployment/environment_variables.md +1 -1
- package/dist/developer/deployment/render.md +5 -5
- package/dist/developer/getting-started/quickstart.md +2 -2
- package/dist/developer/how-to/custom-payment-method.md +6 -6
- package/dist/developer/how-to/custom-promotion.md +7 -7
- package/dist/developer/how-to/custom-report.md +3 -3
- package/dist/developer/how-to/custom-search-provider.md +7 -7
- package/dist/developer/multi-store/quickstart.md +1 -1
- package/dist/developer/multi-tenant/quickstart.md +1 -1
- package/dist/developer/sdk/authentication.md +1 -1
- package/dist/developer/sdk/configuration.md +1 -1
- package/dist/developer/sdk/store/markets.md +3 -3
- package/dist/developer/storefront/nextjs/customization.md +1 -1
- package/dist/developer/storefront/nextjs/quickstart.md +2 -2
- package/dist/developer/tutorial/admin.md +2 -2
- package/dist/developer/tutorial/extending-models.md +15 -15
- package/dist/developer/tutorial/file-uploads.md +1 -1
- package/dist/developer/tutorial/introduction.md +7 -7
- package/dist/developer/tutorial/rich-text.md +1 -1
- package/dist/developer/tutorial/testing.md +5 -61
- package/dist/developer/upgrades/3.7-to-4.0.md +1 -1
- package/dist/developer/upgrades/4.0-to-4.1.md +1 -1
- package/dist/developer/upgrades/4.10-to-5.0.md +1 -1
- package/dist/developer/upgrades/4.5-to-4.6.md +4 -4
- package/dist/developer/upgrades/4.8-to-4.9.md +1 -1
- package/dist/developer/upgrades/4.9-to-4.10.md +1 -1
- package/dist/developer/upgrades/5.0-to-5.1.md +1 -1
- package/dist/developer/upgrades/5.1-to-5.2.md +2 -2
- package/dist/developer/upgrades/5.2-to-5.3.md +2 -2
- package/dist/developer/upgrades/5.3-to-5.4.md +5 -5
- package/dist/developer/upgrades/quickstart.md +1 -1
- package/dist/integrations/integrations.md +10 -10
- package/dist/integrations/payments/adyen.md +1 -1
- package/dist/integrations/search/meilisearch.md +2 -2
- package/package.json +7 -2
- package/dist/developer/storefront/blocks.md +0 -285
- package/dist/developer/storefront/custom-css.md +0 -260
- package/dist/developer/storefront/custom-javascript.md +0 -166
- package/dist/developer/storefront/helper-methods.md +0 -1288
- package/dist/developer/storefront/links.md +0 -298
- package/dist/developer/storefront/pages.md +0 -163
- package/dist/developer/storefront/sections.md +0 -569
- package/dist/developer/storefront/storefront.md +0 -56
- package/dist/developer/storefront/themes.md +0 -161
- package/dist/developer/tutorial/page-builder.md +0 -487
- package/dist/developer/tutorial/seo.md +0 -332
- package/dist/developer/tutorial/storefront.md +0 -352
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Storefront Themes"
|
|
3
|
-
sidebarTitle: "Themes"
|
|
4
|
-
description: "Learn how to develop themes for your Spree storefront"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Themes are the main building blocks of the storefront. They hold styles, settings, and templates for the storefront.
|
|
8
|
-
|
|
9
|
-
## Default Theme
|
|
10
|
-
|
|
11
|
-
Spree comes with a default theme called `default`. It is used as a base for all the themes and contains the core styles and scripts. This theme is included with the Spree Commerce core and is always available.
|
|
12
|
-
|
|
13
|
-
## Creating a New Theme
|
|
14
|
-
|
|
15
|
-
You can create your custom themes by following the steps below.
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
bin/rails g spree:storefront:theme MyTheme
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
This command will create a new theme called `my_theme` in the `app/views/themes` directory and copy the default theme files to the new theme.
|
|
22
|
-
|
|
23
|
-
It will also add a line in your `config/initializers/spree.rb` file to load the new theme.
|
|
24
|
-
|
|
25
|
-
```ruby config/initializers/spree.rb
|
|
26
|
-
Spree.page_builder.themes << Spree::Themes::MyTheme
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Now you can go to **Admin Dashboard -> Storefront -> Themes**, you should see a new section **Add new theme** with your theme name. Click **Add** button to activate the theme.
|
|
30
|
-
|
|
31
|
-
### Theme Templates
|
|
32
|
-
|
|
33
|
-
Theme has the following template structure:
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
├── account
|
|
37
|
-
│ ├── store_credits
|
|
38
|
-
│ ├── profile
|
|
39
|
-
│ ├── orders
|
|
40
|
-
│ ├── newsletter
|
|
41
|
-
│ └── addresses
|
|
42
|
-
├── checkout
|
|
43
|
-
├── contacts
|
|
44
|
-
├── orders
|
|
45
|
-
├── page_sections
|
|
46
|
-
├── policies
|
|
47
|
-
├── posts
|
|
48
|
-
├── products
|
|
49
|
-
├── search
|
|
50
|
-
├── settings
|
|
51
|
-
├── shared
|
|
52
|
-
└── wishlists
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Each directory contains standard [Ruby on Rails ERB templates](https://guides.rubyonrails.org/action_view_overview.html) for the corresponding page.
|
|
56
|
-
|
|
57
|
-
The `page_sections` directory contains sections that are used globally across the storefront.
|
|
58
|
-
|
|
59
|
-
The `shared` directory contains shared components that are used across the storefront.
|
|
60
|
-
|
|
61
|
-
### Theme Settings
|
|
62
|
-
|
|
63
|
-
The theme settings are stored in the `app/models/spree/themes/my_theme.rb` file.
|
|
64
|
-
|
|
65
|
-
```ruby
|
|
66
|
-
module Spree
|
|
67
|
-
module Themes
|
|
68
|
-
class MyTheme < Spree::Theme
|
|
69
|
-
def self.metadata
|
|
70
|
-
{
|
|
71
|
-
authors: ['Spree Commerce'], # replace with your name
|
|
72
|
-
license: 'MIT' # replace with your license
|
|
73
|
-
}
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# COLORS
|
|
77
|
-
# main colors
|
|
78
|
-
preference :primary_color, :string, default: '#000000'
|
|
79
|
-
preference :accent_color, :string, default: '#F0EFE9'
|
|
80
|
-
preference :danger_color, :string, default: '#C73528'
|
|
81
|
-
preference :neutral_color, :string, default: '#999999'
|
|
82
|
-
preference :background_color, :string, default: '#FFFFFF'
|
|
83
|
-
preference :text_color, :string, default: '#000000'
|
|
84
|
-
preference :success_color, :string, default: '#00C773'
|
|
85
|
-
|
|
86
|
-
# buttons
|
|
87
|
-
preference :button_background_color, :string
|
|
88
|
-
preference :button_text_color, :string, default: '#ffffff'
|
|
89
|
-
preference :button_hover_background_color, :string
|
|
90
|
-
preference :button_hover_text_color, :string
|
|
91
|
-
preference :button_border_color, :string
|
|
92
|
-
|
|
93
|
-
# borders
|
|
94
|
-
preference :border_color, :string, default: '#E9E7DC'
|
|
95
|
-
preference :sidebar_border_color, :string
|
|
96
|
-
|
|
97
|
-
preference :secondary_button_background_color, :string
|
|
98
|
-
preference :secondary_button_text_color, :string
|
|
99
|
-
preference :secondary_button_hover_background_color, :string
|
|
100
|
-
preference :secondary_button_hover_text_color, :string
|
|
101
|
-
|
|
102
|
-
# inputs
|
|
103
|
-
preference :input_text_color, :string, default: '#6b7280'
|
|
104
|
-
preference :input_background_color, :string, default: '#ffffff'
|
|
105
|
-
preference :input_border_color, :string
|
|
106
|
-
preference :input_focus_border_color, :string
|
|
107
|
-
preference :input_focus_background_color, :string
|
|
108
|
-
preference :input_focus_text_color, :string
|
|
109
|
-
|
|
110
|
-
# sidebar (checkout)
|
|
111
|
-
preference :checkout_sidebar_background_color, :string, default: '#f3f4f6'
|
|
112
|
-
preference :checkout_divider_background_color, :string
|
|
113
|
-
preference :checkout_sidebar_text_color, :string
|
|
114
|
-
|
|
115
|
-
# TYPOGRAPHY
|
|
116
|
-
preference :custom_font_code, :string, default: nil
|
|
117
|
-
# body
|
|
118
|
-
preference :font_family, :string, default: 'Inter'
|
|
119
|
-
preference :font_size_scale, :integer, default: 100
|
|
120
|
-
# headers
|
|
121
|
-
preference :header_font_family, :string, default: 'Inter'
|
|
122
|
-
preference :header_font_size_scale, :integer, default: 100
|
|
123
|
-
preference :headings_uppercase, :boolean, default: true
|
|
124
|
-
|
|
125
|
-
# BUTTONS
|
|
126
|
-
preference :button_border_thickness, :integer, default: 1
|
|
127
|
-
preference :button_border_opacity, :integer, default: 100
|
|
128
|
-
preference :button_border_radius, :integer, default: 100
|
|
129
|
-
preference :button_shadow_opacity, :integer, default: 0
|
|
130
|
-
preference :button_shadow_horizontal_offset, :integer, default: 0
|
|
131
|
-
preference :button_shadow_vertical_offset, :integer, default: 4
|
|
132
|
-
preference :button_shadow_blur, :integer, default: 5
|
|
133
|
-
|
|
134
|
-
# INPUTS
|
|
135
|
-
preference :input_border_thickness, :integer, default: 1
|
|
136
|
-
preference :input_border_opacity, :integer, default: 100
|
|
137
|
-
preference :input_border_radius, :integer, default: 8
|
|
138
|
-
preference :input_shadow_opacity, :integer, default: 0
|
|
139
|
-
preference :input_shadow_horizontal_offset, :integer, default: 0
|
|
140
|
-
preference :input_shadow_vertical_offset, :integer, default: 4
|
|
141
|
-
preference :input_shadow_blur, :integer, default: 5
|
|
142
|
-
|
|
143
|
-
# BORDERS
|
|
144
|
-
preference :border_width, :integer, default: 1
|
|
145
|
-
preference :border_radius, :integer, default: 6
|
|
146
|
-
preference :border_shadow_opacity, :integer, default: 0
|
|
147
|
-
preference :border_shadow_horizontal_offset, :integer, default: 0
|
|
148
|
-
preference :border_shadow_vertical_offset, :integer, default: 4
|
|
149
|
-
preference :border_shadow_blur, :integer, default: 5
|
|
150
|
-
|
|
151
|
-
# PRODUCT IMAGES
|
|
152
|
-
preference :product_listing_image_height, :integer, default: 300
|
|
153
|
-
preference :product_listing_image_width, :integer, default: 300
|
|
154
|
-
preference :product_listing_image_height_mobile, :integer, default: 190
|
|
155
|
-
preference :product_listing_image_width_mobile, :integer, default: 190
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
These are standard [Spree preferences](/developer/customization/model-preferences) that are configurable via Page Builder.
|
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Page Builder Integration
|
|
3
|
-
description: Learn how to connect your Brands feature to Page Builder for admin-manageable pages
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
In this tutorial, we'll enhance our brand pages by integrating them with Spree's Page Builder. This allows store administrators to customize page layouts, add sections, and modify designs without touching code.
|
|
7
|
-
|
|
8
|
-
> **INFO:** This guide assumes you've completed the [Storefront](/developer/tutorial/storefront) tutorial and have working brand pages.
|
|
9
|
-
|
|
10
|
-
## What We're Building
|
|
11
|
-
|
|
12
|
-
By the end of this tutorial, you'll have:
|
|
13
|
-
|
|
14
|
-
- A **Brand List** page type manageable via Page Builder
|
|
15
|
-
- A **Brand** page type for individual brand pages
|
|
16
|
-
- Custom sections: `BrandGrid` and `BrandBanner`
|
|
17
|
-
- Full admin customization support
|
|
18
|
-
|
|
19
|
-
## Understanding Page Builder Architecture
|
|
20
|
-
|
|
21
|
-
Page Builder uses three main components:
|
|
22
|
-
|
|
23
|
-
| Component | Purpose |
|
|
24
|
-
|-----------|---------|
|
|
25
|
-
| **Page** | Defines the page type (e.g., Homepage, Product Details, Brand List) |
|
|
26
|
-
| **Section** | Reusable content blocks within a page (e.g., Hero Banner, Product Grid) |
|
|
27
|
-
| **Block** | Smallest units within sections (e.g., Heading, Text, Button) |
|
|
28
|
-
|
|
29
|
-
## Step 1: Create Page Types
|
|
30
|
-
|
|
31
|
-
### Brand List Page
|
|
32
|
-
|
|
33
|
-
Create a page type for the brands listing:
|
|
34
|
-
|
|
35
|
-
```ruby app/models/spree/pages/brand_list.rb
|
|
36
|
-
module Spree
|
|
37
|
-
module Pages
|
|
38
|
-
class BrandList < Spree::Page
|
|
39
|
-
def icon_name
|
|
40
|
-
'building-store'
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def customizable?
|
|
44
|
-
true
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def page_builder_url
|
|
48
|
-
return unless page_builder_url_exists?(:brands_path)
|
|
49
|
-
|
|
50
|
-
Spree::Core::Engine.routes.url_helpers.brands_path
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def default_sections
|
|
54
|
-
[
|
|
55
|
-
Spree::PageSections::PageTitle.new(
|
|
56
|
-
preferred_heading: Spree.t(:brands)
|
|
57
|
-
),
|
|
58
|
-
Spree::PageSections::BrandGrid.new
|
|
59
|
-
]
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Brand Page
|
|
67
|
-
|
|
68
|
-
Create a page type for individual brand pages:
|
|
69
|
-
|
|
70
|
-
```ruby app/models/spree/pages/brand.rb
|
|
71
|
-
module Spree
|
|
72
|
-
module Pages
|
|
73
|
-
class Brand < Spree::Page
|
|
74
|
-
def icon_name
|
|
75
|
-
'tag'
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def customizable?
|
|
79
|
-
true
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def page_builder_url
|
|
83
|
-
return unless page_builder_url_exists?(:brands_path)
|
|
84
|
-
|
|
85
|
-
brand = Spree::Brand.first
|
|
86
|
-
return unless brand
|
|
87
|
-
|
|
88
|
-
Spree::Core::Engine.routes.url_helpers.brand_path(brand)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def default_sections
|
|
92
|
-
[
|
|
93
|
-
Spree::PageSections::BrandBanner.new,
|
|
94
|
-
Spree::PageSections::ProductGrid.new(
|
|
95
|
-
preferred_heading: Spree.t(:products)
|
|
96
|
-
)
|
|
97
|
-
]
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Step 2: Register Pages
|
|
105
|
-
|
|
106
|
-
Add your pages to the Spree configuration:
|
|
107
|
-
|
|
108
|
-
```ruby config/initializers/spree.rb
|
|
109
|
-
Rails.application.config.after_initialize do
|
|
110
|
-
# Register custom pages
|
|
111
|
-
Spree.page_builder.pages += [
|
|
112
|
-
Spree::Pages::BrandList,
|
|
113
|
-
Spree::Pages::Brand
|
|
114
|
-
]
|
|
115
|
-
end
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Step 3: Create Custom Sections
|
|
119
|
-
|
|
120
|
-
### Brand Grid Section
|
|
121
|
-
|
|
122
|
-
This section displays a grid of all brands:
|
|
123
|
-
|
|
124
|
-
```ruby app/models/spree/page_sections/brand_grid.rb
|
|
125
|
-
module Spree
|
|
126
|
-
module PageSections
|
|
127
|
-
class BrandGrid < Spree::PageSection
|
|
128
|
-
TOP_PADDING_DEFAULT = 40
|
|
129
|
-
BOTTOM_PADDING_DEFAULT = 40
|
|
130
|
-
|
|
131
|
-
preference :show_description, :boolean, default: false
|
|
132
|
-
|
|
133
|
-
def icon_name
|
|
134
|
-
'layout-grid'
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# Content sections can be added/removed in Page Builder
|
|
138
|
-
def self.role
|
|
139
|
-
'content'
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def brands
|
|
143
|
-
Spree::Brand.order(:name)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Brand Banner Section
|
|
151
|
-
|
|
152
|
-
This section displays the brand header with logo and description:
|
|
153
|
-
|
|
154
|
-
```ruby app/models/spree/page_sections/brand_banner.rb
|
|
155
|
-
module Spree
|
|
156
|
-
module PageSections
|
|
157
|
-
class BrandBanner < Spree::PageSection
|
|
158
|
-
TOP_PADDING_DEFAULT = 60
|
|
159
|
-
BOTTOM_PADDING_DEFAULT = 40
|
|
160
|
-
|
|
161
|
-
preference :show_logo, :boolean, default: true
|
|
162
|
-
preference :show_description, :boolean, default: true
|
|
163
|
-
preference :layout, :string, default: 'horizontal'
|
|
164
|
-
|
|
165
|
-
before_validation :ensure_valid_layout
|
|
166
|
-
|
|
167
|
-
def icon_name
|
|
168
|
-
'id-badge'
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# System sections are part of the core page functionality
|
|
172
|
-
def self.role
|
|
173
|
-
'system'
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def can_be_deleted?
|
|
177
|
-
false
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
private
|
|
181
|
-
|
|
182
|
-
def ensure_valid_layout
|
|
183
|
-
self.preferred_layout = 'horizontal' unless %w[horizontal vertical].include?(preferred_layout)
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Step 4: Register Sections
|
|
191
|
-
|
|
192
|
-
Add your sections to the configuration:
|
|
193
|
-
|
|
194
|
-
```ruby config/initializers/spree.rb
|
|
195
|
-
Rails.application.config.after_initialize do
|
|
196
|
-
# Register custom pages
|
|
197
|
-
Spree.page_builder.pages += [
|
|
198
|
-
Spree::Pages::BrandList,
|
|
199
|
-
Spree::Pages::Brand
|
|
200
|
-
]
|
|
201
|
-
|
|
202
|
-
# Register custom sections
|
|
203
|
-
Spree.page_builder.page_sections += [
|
|
204
|
-
Spree::PageSections::BrandGrid,
|
|
205
|
-
Spree::PageSections::BrandBanner
|
|
206
|
-
]
|
|
207
|
-
end
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Step 5: Create Admin Forms
|
|
211
|
-
|
|
212
|
-
Admin section forms use Spree's Admin Form Builder, which provides helper methods like `spree_select` and `spree_check_box` for consistent styling and functionality.
|
|
213
|
-
|
|
214
|
-
### Brand Grid Admin Form
|
|
215
|
-
|
|
216
|
-
```erb app/views/spree/admin/page_sections/forms/_brand_grid.html.erb
|
|
217
|
-
<%= f.spree_check_box :preferred_show_description,
|
|
218
|
-
label: Spree.t(:show_description),
|
|
219
|
-
data: { action: 'auto-submit#submit' } %>
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Brand Banner Admin Form
|
|
223
|
-
|
|
224
|
-
```erb app/views/spree/admin/page_sections/forms/_brand_banner.html.erb
|
|
225
|
-
<%= f.spree_check_box :preferred_show_logo,
|
|
226
|
-
label: Spree.t(:show_logo),
|
|
227
|
-
data: { action: 'auto-submit#submit' } %>
|
|
228
|
-
|
|
229
|
-
<%= f.spree_check_box :preferred_show_description,
|
|
230
|
-
label: Spree.t(:show_description),
|
|
231
|
-
data: { action: 'auto-submit#submit' } %>
|
|
232
|
-
|
|
233
|
-
<% content_for(:design_tab) do %>
|
|
234
|
-
<%= f.spree_select :preferred_layout,
|
|
235
|
-
options_for_select([
|
|
236
|
-
[Spree.t(:horizontal), 'horizontal'],
|
|
237
|
-
[Spree.t(:vertical), 'vertical']
|
|
238
|
-
], @page_section.preferred_layout),
|
|
239
|
-
{ label: Spree.t(:layout) },
|
|
240
|
-
{ data: { action: 'auto-submit#submit' } } %>
|
|
241
|
-
<hr />
|
|
242
|
-
<% end %>
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Step 6: Create Storefront Views
|
|
246
|
-
|
|
247
|
-
### Brand Grid Section View
|
|
248
|
-
|
|
249
|
-
```erb app/views/themes/default/spree/page_sections/_brand_grid.html.erb
|
|
250
|
-
<% cache_unless page_builder_enabled?, spree_storefront_base_cache_scope.call(section) do %>
|
|
251
|
-
<div style="<%= section_styles(section) %>">
|
|
252
|
-
<div class="page-container">
|
|
253
|
-
<% brands = section.brands %>
|
|
254
|
-
<% if brands.any? %>
|
|
255
|
-
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
|
|
256
|
-
<% brands.each do |brand| %>
|
|
257
|
-
<%= link_to spree.brand_path(brand),
|
|
258
|
-
class: 'block group',
|
|
259
|
-
data: { turbo_frame: '_top' } do %>
|
|
260
|
-
<div class="aspect-square bg-accent rounded-lg overflow-hidden mb-3">
|
|
261
|
-
<% if brand.logo.attached? %>
|
|
262
|
-
<%= spree_image_tag brand.logo,
|
|
263
|
-
width: 300,
|
|
264
|
-
height: 300,
|
|
265
|
-
class: 'w-full h-full object-contain p-6 group-hover:scale-105 transition-transform',
|
|
266
|
-
alt: brand.name %>
|
|
267
|
-
<% else %>
|
|
268
|
-
<div class="w-full h-full flex items-center justify-center">
|
|
269
|
-
<span class="text-4xl font-medium text-neutral-400">
|
|
270
|
-
<%= brand.name.first.upcase %>
|
|
271
|
-
</span>
|
|
272
|
-
</div>
|
|
273
|
-
<% end %>
|
|
274
|
-
</div>
|
|
275
|
-
<h3 class="font-medium group-hover:text-primary transition-colors">
|
|
276
|
-
<%= brand.name %>
|
|
277
|
-
</h3>
|
|
278
|
-
<% if section.preferred_show_description && brand.description.present? %>
|
|
279
|
-
<p class="mt-1 text-sm text-neutral-600 line-clamp-2">
|
|
280
|
-
<%= brand.description.to_plain_text.truncate(100) %>
|
|
281
|
-
</p>
|
|
282
|
-
<% end %>
|
|
283
|
-
<% end %>
|
|
284
|
-
<% end %>
|
|
285
|
-
</div>
|
|
286
|
-
<% else %>
|
|
287
|
-
<p class="text-neutral-600"><%= Spree.t(:no_brands_found) %></p>
|
|
288
|
-
<% end %>
|
|
289
|
-
</div>
|
|
290
|
-
</div>
|
|
291
|
-
<% end %>
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Brand Banner Section View
|
|
295
|
-
|
|
296
|
-
```erb app/views/themes/default/spree/page_sections/_brand_banner.html.erb
|
|
297
|
-
<% cache_unless page_builder_enabled?, spree_storefront_base_cache_scope.call(section) do %>
|
|
298
|
-
<div style="<%= section_styles(section) %>">
|
|
299
|
-
<div class="page-container">
|
|
300
|
-
<% if brand.present? %>
|
|
301
|
-
<div class="<%= section.preferred_layout == 'horizontal' ? 'flex flex-col md:flex-row gap-8 items-start' : 'text-center' %>">
|
|
302
|
-
<% if section.preferred_show_logo && brand.logo.attached? %>
|
|
303
|
-
<div class="<%= section.preferred_layout == 'horizontal' ? 'w-32 h-32 flex-shrink-0' : 'w-40 h-40 mx-auto mb-6' %> bg-accent rounded-lg">
|
|
304
|
-
<%= spree_image_tag brand.logo,
|
|
305
|
-
width: 160,
|
|
306
|
-
height: 160,
|
|
307
|
-
class: 'w-full h-full object-contain p-4',
|
|
308
|
-
alt: brand.name %>
|
|
309
|
-
</div>
|
|
310
|
-
<% end %>
|
|
311
|
-
|
|
312
|
-
<div>
|
|
313
|
-
<h1 class="text-2xl lg:text-3xl font-medium mb-4">
|
|
314
|
-
<%= brand.name %>
|
|
315
|
-
</h1>
|
|
316
|
-
|
|
317
|
-
<% if section.preferred_show_description && brand.description.present? %>
|
|
318
|
-
<div class="prose max-w-none text-neutral-600">
|
|
319
|
-
<%= brand.description %>
|
|
320
|
-
</div>
|
|
321
|
-
<% end %>
|
|
322
|
-
</div>
|
|
323
|
-
</div>
|
|
324
|
-
<% end %>
|
|
325
|
-
</div>
|
|
326
|
-
</div>
|
|
327
|
-
<% end %>
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## Step 7: Update the Controller
|
|
331
|
-
|
|
332
|
-
Update your controller to use Page Builder pages:
|
|
333
|
-
|
|
334
|
-
```ruby app/controllers/spree/brands_controller.rb
|
|
335
|
-
module Spree
|
|
336
|
-
class BrandsController < StoreController
|
|
337
|
-
before_action :load_brand, only: [:show]
|
|
338
|
-
|
|
339
|
-
def index
|
|
340
|
-
# Load the Page Builder page
|
|
341
|
-
@current_page = current_theme.pages.find_by(type: 'Spree::Pages::BrandList')
|
|
342
|
-
|
|
343
|
-
# Fallback data if sections need it
|
|
344
|
-
@brands = Spree::Brand.order(:name)
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
def show
|
|
348
|
-
# Load the Page Builder page
|
|
349
|
-
@current_page = current_theme.pages.find_by(type: 'Spree::Pages::Brand')
|
|
350
|
-
|
|
351
|
-
# Load products for the ProductGrid section
|
|
352
|
-
@products = @brand.products
|
|
353
|
-
.active(current_currency)
|
|
354
|
-
.includes(storefront_products_includes)
|
|
355
|
-
.page(params[:page])
|
|
356
|
-
.per(12)
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
private
|
|
360
|
-
|
|
361
|
-
def load_brand
|
|
362
|
-
@brand = Spree::Brand.find(params[:id])
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
def accurate_title
|
|
366
|
-
if @brand
|
|
367
|
-
@brand.meta_title.presence || @brand.name
|
|
368
|
-
else
|
|
369
|
-
Spree.t(:brands)
|
|
370
|
-
end
|
|
371
|
-
end
|
|
372
|
-
end
|
|
373
|
-
end
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
## Step 8: Update Views to Use Page Builder
|
|
377
|
-
|
|
378
|
-
### Brand List Index View
|
|
379
|
-
|
|
380
|
-
```erb app/views/themes/default/spree/brands/index.html.erb
|
|
381
|
-
<%= render_page(@current_page, brands: @brands) %>
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### Brand Show View
|
|
385
|
-
|
|
386
|
-
```erb app/views/themes/default/spree/brands/show.html.erb
|
|
387
|
-
<%= render_page(@current_page, brand: @brand, products: @products) %>
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
The `render_page` helper automatically renders all sections in the order defined in Page Builder.
|
|
391
|
-
|
|
392
|
-
## Step 9: Passing Variables to Sections
|
|
393
|
-
|
|
394
|
-
Section views receive variables passed to `render_page`. Update your section views to use them:
|
|
395
|
-
|
|
396
|
-
```erb app/views/themes/default/spree/page_sections/_brand_banner.html.erb
|
|
397
|
-
<% # 'brand' variable is passed from the controller via render_page %>
|
|
398
|
-
<% cache_unless page_builder_enabled?, [spree_storefront_base_cache_scope.call(section), brand] do %>
|
|
399
|
-
<div style="<%= section_styles(section) %>">
|
|
400
|
-
<%# ... use 'brand' variable ... %>
|
|
401
|
-
</div>
|
|
402
|
-
<% end %>
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
## Step 10: Add Translations
|
|
406
|
-
|
|
407
|
-
```yaml config/locales/en.yml
|
|
408
|
-
en:
|
|
409
|
-
spree:
|
|
410
|
-
brands: Brands
|
|
411
|
-
no_brands_found: No brands found.
|
|
412
|
-
products_by_brand: "Products by %{brand}"
|
|
413
|
-
show_description: Show description
|
|
414
|
-
show_logo: Show logo
|
|
415
|
-
layout: Layout
|
|
416
|
-
horizontal: Horizontal
|
|
417
|
-
vertical: Vertical
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
## Testing Page Builder Integration
|
|
421
|
-
|
|
422
|
-
1. Start your Rails server
|
|
423
|
-
2. Go to **Admin → Storefront → Pages**
|
|
424
|
-
3. You should see "Brand List" and "Brand" pages
|
|
425
|
-
4. Click on a page to customize it in Page Builder
|
|
426
|
-
5. Add, remove, or reorder sections
|
|
427
|
-
6. Customize section settings
|
|
428
|
-
7. Preview changes in real-time
|
|
429
|
-
|
|
430
|
-
## Section Roles Explained
|
|
431
|
-
|
|
432
|
-
| Role | Description | Can Delete? | Example |
|
|
433
|
-
|------|-------------|-------------|---------|
|
|
434
|
-
| `content` | General content sections | Yes | BrandGrid, ImageBanner |
|
|
435
|
-
| `system` | Core page functionality | No | BrandBanner, ProductDetails |
|
|
436
|
-
| `header` | Layout header sections | No | Header, AnnouncementBar |
|
|
437
|
-
| `footer` | Layout footer sections | No | Footer, Newsletter |
|
|
438
|
-
|
|
439
|
-
## Complete File Structure
|
|
440
|
-
|
|
441
|
-
After completing this tutorial, you should have:
|
|
442
|
-
|
|
443
|
-
```
|
|
444
|
-
app/
|
|
445
|
-
├── controllers/spree/
|
|
446
|
-
│ └── brands_controller.rb
|
|
447
|
-
├── models/spree/
|
|
448
|
-
│ ├── pages/
|
|
449
|
-
│ │ ├── brand.rb
|
|
450
|
-
│ │ └── brand_list.rb
|
|
451
|
-
│ └── page_sections/
|
|
452
|
-
│ ├── brand_banner.rb
|
|
453
|
-
│ └── brand_grid.rb
|
|
454
|
-
└── views/
|
|
455
|
-
├── spree/admin/page_sections/forms/
|
|
456
|
-
│ ├── _brand_banner.html.erb
|
|
457
|
-
│ └── _brand_grid.html.erb
|
|
458
|
-
└── themes/default/spree/
|
|
459
|
-
├── brands/
|
|
460
|
-
│ ├── index.html.erb
|
|
461
|
-
│ └── show.html.erb
|
|
462
|
-
└── page_sections/
|
|
463
|
-
├── _brand_banner.html.erb
|
|
464
|
-
└── _brand_grid.html.erb
|
|
465
|
-
|
|
466
|
-
config/
|
|
467
|
-
├── initializers/
|
|
468
|
-
│ └── spree.rb (updated)
|
|
469
|
-
└── locales/
|
|
470
|
-
└── en.yml (updated)
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
## Benefits of Page Builder Integration
|
|
474
|
-
|
|
475
|
-
| Without Page Builder | With Page Builder |
|
|
476
|
-
|---------------------|-------------------|
|
|
477
|
-
| Developers edit views for layout changes | Admins customize layouts in browser |
|
|
478
|
-
| Code deployment required for design changes | Real-time preview and publish |
|
|
479
|
-
| Fixed page structure | Drag-and-drop section ordering |
|
|
480
|
-
| Hardcoded settings | Admin-configurable preferences |
|
|
481
|
-
|
|
482
|
-
## Related Documentation
|
|
483
|
-
|
|
484
|
-
- [Sections](/developer/storefront/sections) - Creating custom sections
|
|
485
|
-
- [Blocks](/developer/storefront/blocks) - Adding blocks to sections
|
|
486
|
-
- [Pages](/developer/storefront/pages) - Page types and routing
|
|
487
|
-
- [Themes](/developer/storefront/themes) - Theme customization
|