@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,569 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Sections"
|
|
3
|
+
description: "Learn how to utilize sections to build your Spree Storefront"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
Sections are the building blocks of all pages in Spree Storefront.
|
|
9
|
+
|
|
10
|
+
There are two types of sections:
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
- **Layout sections** — * eg. Header, Footer
|
|
14
|
+
* Present on all pages
|
|
15
|
+
- **Content sections** — * eg. Hero, Featured Products
|
|
16
|
+
* Present on specific pages
|
|
17
|
+
* can be managed via the Page Builder
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Let's take a look at the page structure of Spree Storefront:
|
|
21
|
+
|
|
22
|
+
<img src="/images/developer/storefront/page_structure.png" />
|
|
23
|
+
|
|
24
|
+
As you can see, the page is divided into sections. Each section is a component that is used to create the page.
|
|
25
|
+
Most sections are containers that consist of multiple blocks which you can manage via the Page Builder (add/customize/remove/change their order).
|
|
26
|
+
|
|
27
|
+
Each section consists of:
|
|
28
|
+
|
|
29
|
+
| File | Description | Example |
|
|
30
|
+
|------|-------------|---------|
|
|
31
|
+
| ActiveRecord model | Defines the section's preferences | [Spree::PageSections::ImageWithText](https://github.com/spree/spree/blob/main/core/app/models/spree/page_sections/image_with_text.rb) |
|
|
32
|
+
| Storefront view | Renders the section in the storefront - each theme can have its own view | [image_with_text.html.erb](https://github.com/spree/spree/blob/main/storefront/app/views/themes/default/spree/page_sections/_image_with_text.html.erb) |
|
|
33
|
+
| Admin page builder form | Configures the section in the admin panel | [image_with_text/_form.html.erb](https://github.com/spree/spree/blob/main/admin/app/views/spree/admin/page_sections/forms/_image_with_text.html.erb) |
|
|
34
|
+
|
|
35
|
+
## Layout Sections
|
|
36
|
+
|
|
37
|
+
We have two types of layout sections - Header and Footer. As the name suggests, they are rendered at the top and bottom of the page respectively. Between them, we have a main content area that is used to render the page sections.
|
|
38
|
+
|
|
39
|
+
### Header sections
|
|
40
|
+
|
|
41
|
+
#### Announcement Bar
|
|
42
|
+
|
|
43
|
+
<img src="/images/developer/storefront/announcement_bar.png" />
|
|
44
|
+
|
|
45
|
+
A simple announcement bar section that displays a message to the users.
|
|
46
|
+
|
|
47
|
+
* [Announcement Bar model](https://github.com/spree/spree/blob/main/core/app/models/spree/page_sections/announcement_bar.rb)
|
|
48
|
+
* [Announcement Bar view](https://github.com/spree/spree/blob/main/storefront/app/views/themes/default/spree/page_sections/_announcement_bar.html.erb)
|
|
49
|
+
* [Announcement Bar form](https://github.com/spree/spree/blob/main/admin/app/views/spree/admin/page_sections/forms/_announcement_bar.html.erb)
|
|
50
|
+
|
|
51
|
+
#### Header
|
|
52
|
+
|
|
53
|
+
<img src="/images/developer/storefront/header.png" />
|
|
54
|
+
|
|
55
|
+
Header is one of the most important sections in the storefront. It is used to display the store's logo, navigation menu, search bar, cart icon, and user menu.
|
|
56
|
+
|
|
57
|
+
Header can have a simple one-level navigation menu or a more complex multi-level menu (aka mega menu)
|
|
58
|
+
|
|
59
|
+
* [Header model](https://github.com/spree/spree/blob/main/core/app/models/spree/page_sections/header.rb)
|
|
60
|
+
* [Header view](https://github.com/spree/spree/blob/main/storefront/app/views/themes/default/spree/page_sections/_header.html.erb)
|
|
61
|
+
* [Header form](https://github.com/spree/spree/blob/main/admin/app/views/spree/admin/page_sections/forms/_header.html.erb)
|
|
62
|
+
|
|
63
|
+
### Footer sections
|
|
64
|
+
|
|
65
|
+
#### Newsletter
|
|
66
|
+
|
|
67
|
+
<img src="/images/developer/storefront/newsletter.png" />
|
|
68
|
+
|
|
69
|
+
A newsletter section that allows users to subscribe to the store's newsletter. If you connected your store to a newsletter provider (eg. Klaviyo, Mailchimp, etc.), you can use this section to collect emails and send them to your provider (Only in Spree 5.1+).
|
|
70
|
+
|
|
71
|
+
* [Newsletter model](https://github.com/spree/spree/blob/main/core/app/models/spree/page_sections/newsletter.rb)
|
|
72
|
+
* [Newsletter view](https://github.com/spree/spree/blob/main/storefront/app/views/themes/default/spree/page_sections/_newsletter.html.erb)
|
|
73
|
+
* [Newsletter form](https://github.com/spree/spree/blob/main/admin/app/views/spree/admin/page_sections/forms/_newsletter.html.erb)
|
|
74
|
+
|
|
75
|
+
#### Footer
|
|
76
|
+
|
|
77
|
+
<img src="/images/developer/storefront/footer.png" />
|
|
78
|
+
|
|
79
|
+
Footer is a section that is used to display the store's footer. It is typically used to display the store's logo, copyright information, store policies, and other important links.
|
|
80
|
+
|
|
81
|
+
* [Footer model](https://github.com/spree/spree/blob/main/core/app/models/spree/page_sections/footer.rb)
|
|
82
|
+
* [Footer view](https://github.com/spree/spree/blob/main/storefront/app/views/themes/default/spree/page_sections/_footer.html.erb)
|
|
83
|
+
* [Footer form](https://github.com/spree/spree/blob/main/admin/app/views/spree/admin/page_sections/forms/_footer.html.erb)
|
|
84
|
+
|
|
85
|
+
## Content Sections
|
|
86
|
+
|
|
87
|
+
> **WARNING:** Documentation on content sections is coming soon
|
|
88
|
+
|
|
89
|
+
## Architecture
|
|
90
|
+
|
|
91
|
+
Let's dive into the details of how sections work.
|
|
92
|
+
|
|
93
|
+
### Active Record Model
|
|
94
|
+
|
|
95
|
+
Each section's model inherit from [Spree::PageSection](https://github.com/spree/spree/blob/main/core/app/models/spree/page_section.rb) abstract model class.
|
|
96
|
+
|
|
97
|
+
#### Associations
|
|
98
|
+
|
|
99
|
+
Each sections has many blocks and links. You can call them via `section.blocks` and `section.links` respectively.
|
|
100
|
+
|
|
101
|
+
Section belongs to a polymorphic parent model called `pageable` which can be either `Spree::Page` (content sections) or `Spree::Theme` (layout sections).
|
|
102
|
+
|
|
103
|
+
You can access section's theme by calling `section.theme`.
|
|
104
|
+
|
|
105
|
+
#### Preferences
|
|
106
|
+
|
|
107
|
+
Each section has set of default [preferences](/developer/customization/model-preferences)
|
|
108
|
+
|
|
109
|
+
| Name | Description | Default Value |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| `text_color` | Color of text in the section | `nil` - uses theme's text color |
|
|
112
|
+
| `background_color` | Background color of the section | `nil` - uses theme's background color |
|
|
113
|
+
| `border_color` | Color of section borders | `nil` - uses theme's border color |
|
|
114
|
+
| `top_padding` | Padding space above section content (in pixels) | `40` |
|
|
115
|
+
| `bottom_padding` | Padding space below section content (in pixels) | `40` |
|
|
116
|
+
| `top_border_width` | Width of top border (in pixels) | `1` |
|
|
117
|
+
| `bottom_border_width` | Width of bottom border (in pixels) | `0` |
|
|
118
|
+
|
|
119
|
+
Particular sections can introduce their own preferences. For example, `Spree::PageSections::ImageWithText` has `desktop_image_alignment` and `vertical_alignment` preferences.
|
|
120
|
+
|
|
121
|
+
## Creating a New Section
|
|
122
|
+
|
|
123
|
+
This guide walks you through creating a custom section for your Spree storefront. We'll create a "Testimonials" section that displays customer reviews.
|
|
124
|
+
|
|
125
|
+
### Step 1: Create the Model
|
|
126
|
+
|
|
127
|
+
Create your section model that inherits from `Spree::PageSection`. Place it in `app/models/spree/page_sections/`:
|
|
128
|
+
|
|
129
|
+
```ruby app/models/spree/page_sections/testimonials.rb
|
|
130
|
+
module Spree
|
|
131
|
+
module PageSections
|
|
132
|
+
class Testimonials < Spree::PageSection
|
|
133
|
+
# Override default padding if needed
|
|
134
|
+
TOP_PADDING_DEFAULT = 60
|
|
135
|
+
BOTTOM_PADDING_DEFAULT = 60
|
|
136
|
+
|
|
137
|
+
# Define section-specific preferences
|
|
138
|
+
preference :heading, :string, default: 'What Our Customers Say'
|
|
139
|
+
preference :heading_size, :string, default: 'large'
|
|
140
|
+
preference :heading_alignment, :string, default: 'center'
|
|
141
|
+
preference :max_testimonials, :integer, default: 3
|
|
142
|
+
preference :show_rating, :boolean, default: true
|
|
143
|
+
|
|
144
|
+
# Validation for preferences
|
|
145
|
+
before_validation :ensure_valid_heading_size
|
|
146
|
+
before_validation :ensure_valid_alignment
|
|
147
|
+
|
|
148
|
+
# Icon displayed in the Page Builder sidebar
|
|
149
|
+
def icon_name
|
|
150
|
+
'quote'
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Define default blocks that are created with this section
|
|
154
|
+
def default_blocks
|
|
155
|
+
@default_blocks.presence || [
|
|
156
|
+
Spree::PageBlocks::Heading.new(
|
|
157
|
+
text: preferred_heading,
|
|
158
|
+
preferred_text_alignment: preferred_heading_alignment
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Which block types can be added to this section
|
|
164
|
+
def available_blocks_to_add
|
|
165
|
+
[
|
|
166
|
+
Spree::PageBlocks::Heading,
|
|
167
|
+
Spree::PageBlocks::Text
|
|
168
|
+
]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Enable block management in admin
|
|
172
|
+
def blocks_available?
|
|
173
|
+
true
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Allow reordering blocks
|
|
177
|
+
def can_sort_blocks?
|
|
178
|
+
true
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def ensure_valid_heading_size
|
|
184
|
+
self.preferred_heading_size = 'medium' unless %w[small medium large].include?(preferred_heading_size)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def ensure_valid_alignment
|
|
188
|
+
self.preferred_heading_alignment = 'center' unless %w[left center right].include?(preferred_heading_alignment)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Step 2: Register the Section
|
|
196
|
+
|
|
197
|
+
Add your section to `Spree.page_builder.page_sections` in your Spree initializer:
|
|
198
|
+
|
|
199
|
+
```ruby config/initializers/spree.rb
|
|
200
|
+
Rails.application.config.after_initialize do
|
|
201
|
+
Spree.page_builder.page_sections += [
|
|
202
|
+
Spree::PageSections::Testimonials
|
|
203
|
+
]
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> **INFO:** Sections are filtered by their `role` method. By default, sections have role `'content'` which makes them available in the Page Builder. Sections with role `'header'` or `'footer'` are layout sections.
|
|
208
|
+
|
|
209
|
+
### Step 3: Create the Admin Form
|
|
210
|
+
|
|
211
|
+
Create the admin form partial for configuring the section in the Page Builder. Place it in `app/views/spree/admin/page_sections/forms/`:
|
|
212
|
+
|
|
213
|
+
```erb app/views/spree/admin/page_sections/forms/_testimonials.html.erb
|
|
214
|
+
<div class="form-group">
|
|
215
|
+
<%= f.label :preferred_heading, Spree.t(:heading) %>
|
|
216
|
+
<%= f.text_field :preferred_heading,
|
|
217
|
+
class: 'form-control',
|
|
218
|
+
data: { action: 'auto-submit#submit' } %>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div class="form-group">
|
|
222
|
+
<%= f.label :preferred_heading_size, Spree.t(:heading_size) %>
|
|
223
|
+
<%= f.select :preferred_heading_size,
|
|
224
|
+
options_for_select([
|
|
225
|
+
[Spree.t(:small), 'small'],
|
|
226
|
+
[Spree.t(:medium), 'medium'],
|
|
227
|
+
[Spree.t(:large), 'large']
|
|
228
|
+
], @page_section.preferred_heading_size),
|
|
229
|
+
{},
|
|
230
|
+
{ class: 'custom-select', data: { action: 'auto-submit#submit' } } %>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="form-group">
|
|
234
|
+
<%= f.label :preferred_heading_alignment, Spree.t(:alignment) %>
|
|
235
|
+
<%= f.select :preferred_heading_alignment,
|
|
236
|
+
options_for_select([
|
|
237
|
+
[Spree.t(:left), 'left'],
|
|
238
|
+
[Spree.t(:center), 'center'],
|
|
239
|
+
[Spree.t(:right), 'right']
|
|
240
|
+
], @page_section.preferred_heading_alignment),
|
|
241
|
+
{},
|
|
242
|
+
{ class: 'custom-select', data: { action: 'auto-submit#submit' } } %>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<div class="form-group">
|
|
246
|
+
<%= f.label :preferred_max_testimonials, Spree.t(:max_items) %>
|
|
247
|
+
<%= f.number_field :preferred_max_testimonials,
|
|
248
|
+
class: 'form-control',
|
|
249
|
+
min: 1,
|
|
250
|
+
max: 10,
|
|
251
|
+
data: { action: 'auto-submit#submit' } %>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<div class="custom-control custom-checkbox mb-3">
|
|
255
|
+
<%= f.check_box :preferred_show_rating,
|
|
256
|
+
class: 'custom-control-input',
|
|
257
|
+
data: { action: 'auto-submit#submit' } %>
|
|
258
|
+
<%= f.label :preferred_show_rating, Spree.t(:show_rating), class: 'custom-control-label' %>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<%# Add design settings to the Design tab %>
|
|
262
|
+
<% content_for(:design_tab) do %>
|
|
263
|
+
<hr />
|
|
264
|
+
<% end %>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
> **INFO:** The `data: { action: 'auto-submit#submit' }` attribute enables live preview in the Page Builder - changes are saved automatically as the user types.
|
|
268
|
+
|
|
269
|
+
### Step 4: Create the Storefront View
|
|
270
|
+
|
|
271
|
+
Create the storefront partial that renders the section. Place it in your theme's views directory:
|
|
272
|
+
|
|
273
|
+
```erb app/views/themes/default/spree/page_sections/_testimonials.html.erb
|
|
274
|
+
<% cache_unless page_builder_enabled?, spree_storefront_base_cache_scope.call(section) do %>
|
|
275
|
+
<div style="<%= section_styles(section) %>" class="testimonials-section">
|
|
276
|
+
<div class="page-container">
|
|
277
|
+
<%# Heading %>
|
|
278
|
+
<% if section.preferred_heading.present? %>
|
|
279
|
+
<%
|
|
280
|
+
heading_class = case section.preferred_heading_size
|
|
281
|
+
when 'small' then 'text-lg'
|
|
282
|
+
when 'medium' then 'text-xl lg:text-2xl'
|
|
283
|
+
when 'large' then 'text-2xl lg:text-3xl'
|
|
284
|
+
end
|
|
285
|
+
%>
|
|
286
|
+
<h2 class="<%= heading_class %> font-medium mb-8 text-<%= section.preferred_heading_alignment %>">
|
|
287
|
+
<%= section.preferred_heading %>
|
|
288
|
+
</h2>
|
|
289
|
+
<% end %>
|
|
290
|
+
|
|
291
|
+
<%# Render blocks %>
|
|
292
|
+
<% section.blocks.includes(:rich_text_text).each do |block| %>
|
|
293
|
+
<% case block.type %>
|
|
294
|
+
<% when 'Spree::PageBlocks::Heading' %>
|
|
295
|
+
<h3 class="text-xl font-medium" <%= block_attributes(block) %>>
|
|
296
|
+
<%= block.text %>
|
|
297
|
+
</h3>
|
|
298
|
+
<% when 'Spree::PageBlocks::Text' %>
|
|
299
|
+
<div class="prose" <%= block_attributes(block) %>>
|
|
300
|
+
<%= block.text %>
|
|
301
|
+
</div>
|
|
302
|
+
<% end %>
|
|
303
|
+
<% end %>
|
|
304
|
+
|
|
305
|
+
<%# Your custom testimonials content %>
|
|
306
|
+
<div class="grid grid-cols-1 md:grid-cols-<%= section.preferred_max_testimonials %> gap-6">
|
|
307
|
+
<%# Add your testimonials rendering logic here %>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
<% end %>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Section Roles
|
|
315
|
+
|
|
316
|
+
Sections have different roles that determine where they appear:
|
|
317
|
+
|
|
318
|
+
| Role | Description | Example |
|
|
319
|
+
|------|-------------|---------|
|
|
320
|
+
| `content` | Available in Page Builder, can be added to any page | Rich Text, Image Banner |
|
|
321
|
+
| `system` | Core page functionality, usually not removable | Product Details, Cart |
|
|
322
|
+
| `header` | Header layout sections | Header, Announcement Bar |
|
|
323
|
+
| `footer` | Footer layout sections | Footer, Newsletter |
|
|
324
|
+
|
|
325
|
+
To set a section's role, override the `self.role` class method:
|
|
326
|
+
|
|
327
|
+
```ruby
|
|
328
|
+
def self.role
|
|
329
|
+
'content' # default
|
|
330
|
+
end
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Section with Image Upload
|
|
334
|
+
|
|
335
|
+
If your section needs an image, use the built-in `asset` attachment:
|
|
336
|
+
|
|
337
|
+
```ruby app/models/spree/page_sections/hero_banner.rb
|
|
338
|
+
module Spree
|
|
339
|
+
module PageSections
|
|
340
|
+
class HeroBanner < Spree::PageSection
|
|
341
|
+
include Spree::HasImageAltText
|
|
342
|
+
|
|
343
|
+
preference :image_alt, :string
|
|
344
|
+
|
|
345
|
+
def icon_name
|
|
346
|
+
'photo'
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Admin form with image upload:
|
|
354
|
+
|
|
355
|
+
```erb app/views/spree/admin/page_sections/forms/_hero_banner.html.erb
|
|
356
|
+
<%= render 'spree/admin/shared/page_section_image', f: f %>
|
|
357
|
+
|
|
358
|
+
<div class="form-group">
|
|
359
|
+
<%= f.label :preferred_image_alt, Spree.t(:alt_text) %>
|
|
360
|
+
<%= f.text_field :preferred_image_alt,
|
|
361
|
+
class: 'form-control',
|
|
362
|
+
data: { action: 'auto-submit#submit' } %>
|
|
363
|
+
</div>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Display in storefront:
|
|
367
|
+
|
|
368
|
+
```erb
|
|
369
|
+
<% if section.asset.attached? %>
|
|
370
|
+
<%= spree_image_tag section.asset,
|
|
371
|
+
width: 1200,
|
|
372
|
+
height: 600,
|
|
373
|
+
alt: section.image_alt,
|
|
374
|
+
class: 'w-full object-cover' %>
|
|
375
|
+
<% end %>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Section with Links
|
|
379
|
+
|
|
380
|
+
To add clickable links to your section, include the `Spree::HasPageLinks` concern (included by default) and define links:
|
|
381
|
+
|
|
382
|
+
```ruby
|
|
383
|
+
module Spree
|
|
384
|
+
module PageSections
|
|
385
|
+
class PromoBanner < Spree::PageSection
|
|
386
|
+
has_one :link, ->(ps) { ps.links },
|
|
387
|
+
class_name: 'Spree::PageLink',
|
|
388
|
+
as: :parent,
|
|
389
|
+
dependent: :destroy,
|
|
390
|
+
inverse_of: :parent
|
|
391
|
+
accepts_nested_attributes_for :link
|
|
392
|
+
|
|
393
|
+
def default_links
|
|
394
|
+
@default_links.presence || [
|
|
395
|
+
Spree::PageLink.new(label: Spree.t(:shop_now))
|
|
396
|
+
]
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Lazy Loading Sections
|
|
404
|
+
|
|
405
|
+
For sections that load external data (products, taxons), implement lazy loading to improve page performance:
|
|
406
|
+
|
|
407
|
+
```ruby
|
|
408
|
+
def lazy?
|
|
409
|
+
!Rails.env.test?
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def lazy_path(variables)
|
|
413
|
+
url_options = variables[:url_options] || {}
|
|
414
|
+
Spree::Core::Engine.routes.url_helpers.page_section_path(self, **url_options)
|
|
415
|
+
end
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Helper Methods
|
|
419
|
+
|
|
420
|
+
These helper methods are available in storefront section views:
|
|
421
|
+
|
|
422
|
+
| Helper | Description |
|
|
423
|
+
|--------|-------------|
|
|
424
|
+
| `section_styles(section)` | Returns inline CSS for section padding, colors, borders |
|
|
425
|
+
| `block_attributes(block)` | Returns data attributes for Page Builder editing |
|
|
426
|
+
| `page_builder_enabled?` | Returns true when in Page Builder preview mode |
|
|
427
|
+
| `spree_storefront_base_cache_scope` | Cache key scope for the section |
|
|
428
|
+
| `section_heading_styles(section)` | Returns inline CSS for heading text color |
|
|
429
|
+
| `page_builder_link_to(link, **options)` | Renders a link with Page Builder support |
|
|
430
|
+
|
|
431
|
+
### Adding Translations
|
|
432
|
+
|
|
433
|
+
Add translations for your section in your locale files:
|
|
434
|
+
|
|
435
|
+
```yaml config/locales/en.yml
|
|
436
|
+
en:
|
|
437
|
+
spree:
|
|
438
|
+
page_sections:
|
|
439
|
+
testimonials:
|
|
440
|
+
heading_default: "What Our Customers Say"
|
|
441
|
+
text_default: "Read reviews from our happy customers"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Complete Example
|
|
445
|
+
|
|
446
|
+
Here's a complete example putting it all together - a "Brand Story" section:
|
|
447
|
+
|
|
448
|
+
**Step 1: Create the model**
|
|
449
|
+
|
|
450
|
+
```ruby app/models/spree/page_sections/brand_story.rb
|
|
451
|
+
module Spree
|
|
452
|
+
module PageSections
|
|
453
|
+
class BrandStory < Spree::PageSection
|
|
454
|
+
include Spree::HasImageAltText
|
|
455
|
+
|
|
456
|
+
TOP_PADDING_DEFAULT = 80
|
|
457
|
+
BOTTOM_PADDING_DEFAULT = 80
|
|
458
|
+
|
|
459
|
+
preference :image_position, :string, default: 'left'
|
|
460
|
+
preference :image_alt, :string
|
|
461
|
+
|
|
462
|
+
def icon_name
|
|
463
|
+
'building-store'
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
def default_blocks
|
|
467
|
+
[
|
|
468
|
+
Spree::PageBlocks::Heading.new(text: 'Our Story'),
|
|
469
|
+
Spree::PageBlocks::Text.new(text: 'Share your brand story here...')
|
|
470
|
+
]
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def available_blocks_to_add
|
|
474
|
+
[Spree::PageBlocks::Heading, Spree::PageBlocks::Text, Spree::PageBlocks::Buttons]
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def blocks_available?
|
|
478
|
+
true
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def can_sort_blocks?
|
|
482
|
+
true
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
**Step 2: Register the section**
|
|
491
|
+
|
|
492
|
+
```ruby config/initializers/spree.rb
|
|
493
|
+
Rails.application.config.after_initialize do
|
|
494
|
+
Spree.page_builder.page_sections += [Spree::PageSections::BrandStory]
|
|
495
|
+
end
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
**Step 3: Create admin form**
|
|
500
|
+
|
|
501
|
+
```erb app/views/spree/admin/page_sections/forms/_brand_story.html.erb
|
|
502
|
+
<%= render 'spree/admin/shared/page_section_image', f: f %>
|
|
503
|
+
|
|
504
|
+
<div class="form-group">
|
|
505
|
+
<%= f.label :preferred_image_alt, Spree.t(:alt_text) %>
|
|
506
|
+
<%= f.text_field :preferred_image_alt,
|
|
507
|
+
class: 'form-control',
|
|
508
|
+
data: { action: 'auto-submit#submit' } %>
|
|
509
|
+
</div>
|
|
510
|
+
|
|
511
|
+
<% content_for(:design_tab) do %>
|
|
512
|
+
<div class="form-group">
|
|
513
|
+
<%= f.label :preferred_image_position, Spree.t(:image_position) %>
|
|
514
|
+
<%= f.select :preferred_image_position,
|
|
515
|
+
options_for_select([['Left', 'left'], ['Right', 'right']], @page_section.preferred_image_position),
|
|
516
|
+
{},
|
|
517
|
+
{ class: 'custom-select', data: { action: 'auto-submit#submit' } } %>
|
|
518
|
+
</div>
|
|
519
|
+
<hr />
|
|
520
|
+
<% end %>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
**Step 4: Create storefront view**
|
|
525
|
+
|
|
526
|
+
```erb app/views/themes/default/spree/page_sections/_brand_story.html.erb
|
|
527
|
+
<% cache_unless page_builder_enabled?, spree_storefront_base_cache_scope.call(section) do %>
|
|
528
|
+
<div style="<%= section_styles(section) %>" class="brand-story">
|
|
529
|
+
<div class="page-container">
|
|
530
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 items-center">
|
|
531
|
+
<% image_order = section.preferred_image_position == 'right' ? 'lg:order-2' : '' %>
|
|
532
|
+
|
|
533
|
+
<div class="<%= image_order %>">
|
|
534
|
+
<% if section.asset.attached? %>
|
|
535
|
+
<%= spree_image_tag section.asset,
|
|
536
|
+
width: 600,
|
|
537
|
+
height: 400,
|
|
538
|
+
alt: section.image_alt,
|
|
539
|
+
class: 'w-full rounded-lg' %>
|
|
540
|
+
<% end %>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<div>
|
|
544
|
+
<% section.blocks.each do |block| %>
|
|
545
|
+
<% case block.type %>
|
|
546
|
+
<% when 'Spree::PageBlocks::Heading' %>
|
|
547
|
+
<h2 class="text-2xl lg:text-3xl font-medium mb-4" <%= block_attributes(block) %>>
|
|
548
|
+
<%= block.text %>
|
|
549
|
+
</h2>
|
|
550
|
+
<% when 'Spree::PageBlocks::Text' %>
|
|
551
|
+
<div class="prose" <%= block_attributes(block) %>>
|
|
552
|
+
<%= block.text %>
|
|
553
|
+
</div>
|
|
554
|
+
<% when 'Spree::PageBlocks::Buttons' %>
|
|
555
|
+
<div class="mt-6" <%= block_attributes(block) %>>
|
|
556
|
+
<% if block.link %>
|
|
557
|
+
<%= page_builder_link_to block.link,
|
|
558
|
+
class: 'btn-primary',
|
|
559
|
+
target: (block.link.open_in_new_tab ? '_blank' : nil) %>
|
|
560
|
+
<% end %>
|
|
561
|
+
</div>
|
|
562
|
+
<% end %>
|
|
563
|
+
<% end %>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
<% end %>
|
|
569
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Rails Storefront Overview"
|
|
3
|
+
sidebarTitle: "Overview"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Rails Storefront is a mobile-first storefront that is fully customizable & themeable.
|
|
7
|
+
|
|
8
|
+
### Tech Stack
|
|
9
|
+
|
|
10
|
+
- [Ruby on Rails](https://rubyonrails.org/)
|
|
11
|
+
- [Tailwind CSS v4](https://tailwindcss.com/) — Responsive, mobile-first design
|
|
12
|
+
- [Turbo / Hotwire](https://turbo.hotwired.dev/) — Fast, SPA-like navigation
|
|
13
|
+
- [StimulusJS](https://stimulus.hotwired.dev/) — JavaScript controllers for interactivity
|
|
14
|
+
- [Importmaps](https://github.com/rails/importmap-rails) - NodeJS not required
|
|
15
|
+
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
You can install it by running
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bundle add spree_storefront
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then run the install generator:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bin/rails g spree:storefront:install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This will set up the storefront views, Tailwind CSS configuration, and page builder migrations.
|
|
31
|
+
|
|
32
|
+
You will also need to create your first theme:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
Spree::Store.default.send(:create_default_theme)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Architecture
|
|
39
|
+
|
|
40
|
+
Rails Storefront consists of:
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
- [Themes](/developer/storefront/themes) — Themes are a collection of styles, scripts and templates that are used to style and layout the storefront.
|
|
44
|
+
- [Pages](/developer/storefront/pages) — Pages are the main building blocks of the storefront. They are used to create the structure of the storefront. Each Theme comes with a set of default pages such as Home Page, Product Listing Page, Product Page, etc, but you can create your own custom landing pages as well.
|
|
45
|
+
- [Sections](/developer/storefront/sections) — Sections are the building blocks of the pages. They are used to create the structure of the pages. Each Section is a collection of Blocks.
|
|
46
|
+
- [Blocks](/developer/storefront/blocks) — Blocks are the smallest building blocks of the storefront. They are used to create the content of the pages.
|
|
47
|
+
- [Links](/developer/storefront/links) — Links are used to create the navigation of the storefront. They can be assigned to Sections and Blocks.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Page Builder
|
|
51
|
+
|
|
52
|
+
The storefront comes with a visual Page Builder that allows non-developers to build pages using a drag-and-drop interface. This allows your team to create new pages and sections, modify existing ones, and add new blocks to the pages in a no-code way.
|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
You can learn more about the Page Builder in the [User Documentation](/user/storefront/theme-editor).
|