@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,298 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Links"
|
|
3
|
-
sidebarTitle: "Links"
|
|
4
|
-
description: "Learn how to use links for navigation in your Spree Storefront"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Links are used to create navigation throughout the storefront. They can be assigned to [sections](/developer/storefront/sections) and [blocks](/developer/storefront/blocks), enabling users to navigate to different pages, products, categories, or external URLs.
|
|
8
|
-
|
|
9
|
-
## How Links Work
|
|
10
|
-
|
|
11
|
-
The `Spree::PageLink` model provides a flexible way to link to various content types:
|
|
12
|
-
|
|
13
|
-
- **Internal pages** - Link to Pages, Products, Taxons, Posts
|
|
14
|
-
- **External URLs** - Link to any external website
|
|
15
|
-
- **Special links** - Email (`mailto:`) and phone (`tel:`) links
|
|
16
|
-
|
|
17
|
-
Links are managed through the Page Builder interface, where store staff can select what each link points to.
|
|
18
|
-
|
|
19
|
-
## Link Model
|
|
20
|
-
|
|
21
|
-
The [Spree::PageLink](https://github.com/spree/spree/blob/main/core/app/models/spree/page_link.rb) model has these key attributes:
|
|
22
|
-
|
|
23
|
-
| Attribute | Type | Description |
|
|
24
|
-
|-----------|------|-------------|
|
|
25
|
-
| `label` | String | Display text for the link |
|
|
26
|
-
| `url` | String | Custom URL (for external links) |
|
|
27
|
-
| `linkable` | Polymorphic | Reference to internal content (Page, Product, etc.) |
|
|
28
|
-
| `parent` | Polymorphic | Section or Block the link belongs to |
|
|
29
|
-
| `open_in_new_tab` | Boolean | Whether to open in new browser tab |
|
|
30
|
-
| `position` | Integer | Order when multiple links exist |
|
|
31
|
-
|
|
32
|
-
## Linkable Types
|
|
33
|
-
|
|
34
|
-
Links can point to various Spree models:
|
|
35
|
-
|
|
36
|
-
| Linkable Type | Description |
|
|
37
|
-
|---------------|-------------|
|
|
38
|
-
| `Spree::Page` | Internal pages (Home, Shop All, Custom pages) |
|
|
39
|
-
| `Spree::Product` | Product detail pages |
|
|
40
|
-
| `Spree::Taxon` | Category/collection pages |
|
|
41
|
-
| `Spree::Post` | Blog posts |
|
|
42
|
-
| Custom URL | Any external or internal URL |
|
|
43
|
-
|
|
44
|
-
## Using Links in Sections
|
|
45
|
-
|
|
46
|
-
### Single Link
|
|
47
|
-
|
|
48
|
-
For sections that need one link (like a banner):
|
|
49
|
-
|
|
50
|
-
```ruby app/models/spree/page_sections/promo_banner.rb
|
|
51
|
-
module Spree
|
|
52
|
-
module PageSections
|
|
53
|
-
class PromoBanner < Spree::PageSection
|
|
54
|
-
has_one :link, ->(ps) { ps.links },
|
|
55
|
-
class_name: 'Spree::PageLink',
|
|
56
|
-
as: :parent,
|
|
57
|
-
dependent: :destroy,
|
|
58
|
-
inverse_of: :parent
|
|
59
|
-
accepts_nested_attributes_for :link
|
|
60
|
-
|
|
61
|
-
def default_links
|
|
62
|
-
@default_links.presence || [
|
|
63
|
-
Spree::PageLink.new(label: Spree.t(:shop_now))
|
|
64
|
-
]
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Multiple Links
|
|
72
|
-
|
|
73
|
-
For sections that need multiple links (like navigation):
|
|
74
|
-
|
|
75
|
-
```ruby app/models/spree/page_sections/footer.rb
|
|
76
|
-
module Spree
|
|
77
|
-
module PageSections
|
|
78
|
-
class Footer < Spree::PageSection
|
|
79
|
-
# Links are provided by Spree::HasPageLinks concern
|
|
80
|
-
# which is included in Spree::PageSection by default
|
|
81
|
-
|
|
82
|
-
def default_links
|
|
83
|
-
@default_links.presence || [
|
|
84
|
-
Spree::PageLink.new(label: 'About Us'),
|
|
85
|
-
Spree::PageLink.new(label: 'Contact'),
|
|
86
|
-
Spree::PageLink.new(label: 'Privacy Policy')
|
|
87
|
-
]
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Using Links in Blocks
|
|
95
|
-
|
|
96
|
-
Blocks can also have links. Use the `Spree::HasOneLink` concern for single links:
|
|
97
|
-
|
|
98
|
-
```ruby app/models/spree/page_blocks/cta_button.rb
|
|
99
|
-
module Spree
|
|
100
|
-
module PageBlocks
|
|
101
|
-
class CtaButton < Spree::PageBlock
|
|
102
|
-
include Spree::HasOneLink
|
|
103
|
-
|
|
104
|
-
preference :button_style, :string, default: 'primary'
|
|
105
|
-
|
|
106
|
-
# Called when the link is deleted
|
|
107
|
-
def link_destroyed(_link)
|
|
108
|
-
destroy if page_links_count.zero?
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Accessing Links
|
|
116
|
-
|
|
117
|
-
```ruby
|
|
118
|
-
# Single link on a section
|
|
119
|
-
section.link
|
|
120
|
-
section.link.label
|
|
121
|
-
section.link.linkable_url
|
|
122
|
-
|
|
123
|
-
# Multiple links on a section
|
|
124
|
-
section.links
|
|
125
|
-
section.links.each do |link|
|
|
126
|
-
link.label
|
|
127
|
-
link.linkable_url
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Link on a block
|
|
131
|
-
block.link
|
|
132
|
-
block.link.label if block.link.present?
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Rendering Links
|
|
136
|
-
|
|
137
|
-
### Using the Helper
|
|
138
|
-
|
|
139
|
-
The `page_builder_link_to` helper renders links with Page Builder support:
|
|
140
|
-
|
|
141
|
-
```erb
|
|
142
|
-
<%# Basic usage %>
|
|
143
|
-
<%= page_builder_link_to section.link %>
|
|
144
|
-
|
|
145
|
-
<%# With custom label %>
|
|
146
|
-
<%= page_builder_link_to section.link, label: 'Click Here' %>
|
|
147
|
-
|
|
148
|
-
<%# With CSS class %>
|
|
149
|
-
<%= page_builder_link_to section.link, class: 'btn-primary' %>
|
|
150
|
-
|
|
151
|
-
<%# Open in new tab %>
|
|
152
|
-
<%= page_builder_link_to section.link,
|
|
153
|
-
target: (section.link.open_in_new_tab ? '_blank' : nil),
|
|
154
|
-
rel: (section.link.open_in_new_tab ? 'noopener noreferrer' : nil) %>
|
|
155
|
-
|
|
156
|
-
<%# With block content %>
|
|
157
|
-
<%= page_builder_link_to section.link do %>
|
|
158
|
-
<span class="icon">→</span>
|
|
159
|
-
<%= section.link.label %>
|
|
160
|
-
<% end %>
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Manual Link Rendering
|
|
164
|
-
|
|
165
|
-
For more control, you can render links manually:
|
|
166
|
-
|
|
167
|
-
```erb
|
|
168
|
-
<% if section.link.present? %>
|
|
169
|
-
<%= link_to section.link.linkable_url,
|
|
170
|
-
target: (section.link.open_in_new_tab ? '_blank' : nil),
|
|
171
|
-
rel: (section.link.open_in_new_tab ? 'noopener noreferrer' : nil),
|
|
172
|
-
class: 'btn-primary' do %>
|
|
173
|
-
<%= section.link.label %>
|
|
174
|
-
<% end %>
|
|
175
|
-
<% end %>
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Rendering Multiple Links
|
|
179
|
-
|
|
180
|
-
```erb
|
|
181
|
-
<nav class="footer-links">
|
|
182
|
-
<% section.links.each do |link| %>
|
|
183
|
-
<%= page_builder_link_to link, class: 'footer-link' %>
|
|
184
|
-
<% end %>
|
|
185
|
-
</nav>
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Admin Form for Links
|
|
189
|
-
|
|
190
|
-
In your section's admin form, render the link editor:
|
|
191
|
-
|
|
192
|
-
### Single Link
|
|
193
|
-
|
|
194
|
-
```erb app/views/spree/admin/page_sections/forms/_promo_banner.html.erb
|
|
195
|
-
<%= render 'spree/admin/shared/page_section_image', f: f %>
|
|
196
|
-
|
|
197
|
-
<div class="py-2">
|
|
198
|
-
<%= f.fields_for :link do |lf| %>
|
|
199
|
-
<div class="form-group">
|
|
200
|
-
<%= lf.label :linkable_type, Spree.t(:link) %>
|
|
201
|
-
<%= lf.select :linkable_type,
|
|
202
|
-
@page_section.allowed_linkable_types,
|
|
203
|
-
{ include_blank: false },
|
|
204
|
-
{ class: 'custom-select mb-3', data: { action: 'auto-submit#submit' } } %>
|
|
205
|
-
|
|
206
|
-
<div id="linkable_type_dropdown">
|
|
207
|
-
<%= render 'spree/admin/page_links/linkable_type_dropdown',
|
|
208
|
-
page_link: lf.object,
|
|
209
|
-
form_name: 'page_section[link_attributes]' %>
|
|
210
|
-
</div>
|
|
211
|
-
</div>
|
|
212
|
-
|
|
213
|
-
<div class="custom-control custom-checkbox">
|
|
214
|
-
<%= lf.check_box :open_in_new_tab,
|
|
215
|
-
class: 'custom-control-input',
|
|
216
|
-
data: { action: 'auto-submit#submit' } %>
|
|
217
|
-
<%= lf.label :open_in_new_tab, class: 'custom-control-label' %>
|
|
218
|
-
</div>
|
|
219
|
-
<% end %>
|
|
220
|
-
</div>
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
## Link URL Resolution
|
|
224
|
-
|
|
225
|
-
The `linkable_url` method returns the appropriate URL:
|
|
226
|
-
|
|
227
|
-
```ruby
|
|
228
|
-
link = Spree::PageLink.new(linkable: product)
|
|
229
|
-
link.linkable_url
|
|
230
|
-
# => "/products/red-shirt"
|
|
231
|
-
|
|
232
|
-
link = Spree::PageLink.new(url: "https://example.com")
|
|
233
|
-
link.linkable_url
|
|
234
|
-
# => "https://example.com"
|
|
235
|
-
|
|
236
|
-
link = Spree::PageLink.new(url: "example.com")
|
|
237
|
-
link.formatted_url
|
|
238
|
-
# => "http://example.com" # Adds protocol automatically
|
|
239
|
-
|
|
240
|
-
link = Spree::PageLink.new(url: "mailto:info@example.com")
|
|
241
|
-
link.formatted_url
|
|
242
|
-
# => "mailto:info@example.com" # Preserves mailto: protocol
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## Creating Links Programmatically
|
|
246
|
-
|
|
247
|
-
```ruby
|
|
248
|
-
# Link to an internal page
|
|
249
|
-
link = Spree::PageLink.create!(
|
|
250
|
-
parent: section,
|
|
251
|
-
label: 'Shop Now',
|
|
252
|
-
linkable: store.pages.find_by(type: 'Spree::Pages::ShopAll')
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
# Link to a product
|
|
256
|
-
link = Spree::PageLink.create!(
|
|
257
|
-
parent: section,
|
|
258
|
-
label: product.name,
|
|
259
|
-
linkable: product
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
# Link to a taxon
|
|
263
|
-
link = Spree::PageLink.create!(
|
|
264
|
-
parent: section,
|
|
265
|
-
label: 'New Arrivals',
|
|
266
|
-
linkable: store.taxons.find_by(name: 'New Arrivals')
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
# External link
|
|
270
|
-
link = Spree::PageLink.create!(
|
|
271
|
-
parent: section,
|
|
272
|
-
label: 'Visit Our Blog',
|
|
273
|
-
url: 'https://blog.example.com',
|
|
274
|
-
open_in_new_tab: true
|
|
275
|
-
)
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
## Automatic Label Setting
|
|
279
|
-
|
|
280
|
-
When a link's `linkable` is set, the label is automatically populated from the linked resource:
|
|
281
|
-
|
|
282
|
-
```ruby
|
|
283
|
-
link = Spree::PageLink.new(linkable: product)
|
|
284
|
-
link.valid?
|
|
285
|
-
link.label
|
|
286
|
-
# => "Red T-Shirt" (from product.name)
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
The label is derived from (in order):
|
|
290
|
-
1. `linkable.title`
|
|
291
|
-
2. `linkable.display_name`
|
|
292
|
-
3. `linkable.name`
|
|
293
|
-
|
|
294
|
-
## Related Documentation
|
|
295
|
-
|
|
296
|
-
- [Sections](/developer/storefront/sections) - Adding links to sections
|
|
297
|
-
- [Blocks](/developer/storefront/blocks) - Adding links to blocks
|
|
298
|
-
- [Pages](/developer/storefront/pages) - Understanding internal page linking
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Storefront Pages"
|
|
3
|
-
sidebarTitle: "Pages"
|
|
4
|
-
description: "Learn how to create and use pages in your Spree storefront"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Built-in Pages
|
|
8
|
-
|
|
9
|
-
Spree Storefront comes with a full set of built-in pages that you can customize via page builder.
|
|
10
|
-
|
|
11
|
-
| Page | Description | Class | URL |
|
|
12
|
-
|------|-------------|-------|------------|
|
|
13
|
-
| Home | The main landing page of your store | [Spree::Pages::Homepage](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/homepage.rb) | `/` |
|
|
14
|
-
| Product Details | Individual product display page | [Spree::Pages::ProductDetails](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/product_details.rb) | `/products/:id` |
|
|
15
|
-
| Taxon | Shows products filtered by taxon | [Spree::Pages::Taxon](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/taxon.rb) | `/t/:permalink` |
|
|
16
|
-
| Search Results | Displays search results for products | [Spree::Pages::SearchResults](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/search_results.rb) | `/search` |
|
|
17
|
-
| Shop All | Shows all products | [Spree::Pages::ShopAll](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/shop_all.rb) | `/products` |
|
|
18
|
-
| Blog | Shows your store's blog posts and articles | [Spree::Pages::PostList](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/post_list.rb) | `/posts` |
|
|
19
|
-
| Post | Individual blog post | [Spree::Pages::Post](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/post.rb) | `/posts/:permalink` |
|
|
20
|
-
| Password | Password page, when password protected storefront is enabled | [Spree::Pages::Password](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/password.rb) | `/` |
|
|
21
|
-
|
|
22
|
-
All of these page can be fully customized via page builder. You can add/remove sections, etc.
|
|
23
|
-
|
|
24
|
-
We're planning to add page builder support for the following pages in the next Spree releases:
|
|
25
|
-
|
|
26
|
-
- Cart
|
|
27
|
-
- Checkout
|
|
28
|
-
- Account
|
|
29
|
-
|
|
30
|
-
## Sections
|
|
31
|
-
|
|
32
|
-
Each page is made of [sections](/developer/storefront/sections). Sections are the building blocks of a page. They are used to create the page content.
|
|
33
|
-
|
|
34
|
-
You can fetch page sections using:
|
|
35
|
-
|
|
36
|
-
```ruby
|
|
37
|
-
current_page.sections
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Custom Landing Pages in the Admin
|
|
41
|
-
|
|
42
|
-
You can easily create your own landing pages by going to to the `Admin -> Storefront -> Pages` and clicking on the `New Page` button. More on this in the [Create a Landing Page](/user/storefront/create-page) guide. Each custom landing page can be customized via page builder.
|
|
43
|
-
|
|
44
|
-

|
|
45
|
-
|
|
46
|
-
Under the hood they use [Spree::Pages::Custom](https://github.com/spree/spree/blob/main/core/app/models/spree/pages/custom.rb) class.
|
|
47
|
-
|
|
48
|
-
## Building a new Page from scratch
|
|
49
|
-
|
|
50
|
-
If you need to build a page that is not one of the built-in pages, you can create your own page class. This will allow you to create a dedicated page for your business needs and at the same time allow your non-technical team to manage the page content without bugging you :)
|
|
51
|
-
|
|
52
|
-
Let's assume you need to create a page that displays pickup locations. You already created a new model `Spree::PickupLocation` and added some data to the database. Now you want to create a page that displays these pickup locations.
|
|
53
|
-
|
|
54
|
-
First, let's add a route for the new page.
|
|
55
|
-
|
|
56
|
-
```ruby
|
|
57
|
-
# config/routes.rb
|
|
58
|
-
Spree::Core::Engine.add_routes do
|
|
59
|
-
scope '(:locale)', locale: /#{Spree.available_locales.join('|')}/, defaults: { locale: nil } do # this line will enable translations for the new page
|
|
60
|
-
resources :pickup_locations, only: [:index]
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Now, create the new page class file:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
mkdir -p app/models/spree/pages && touch app/models/spree/pages/pickup_locations.rb
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Now, let's add the new page class:
|
|
72
|
-
|
|
73
|
-
```ruby
|
|
74
|
-
module Spree
|
|
75
|
-
module Pages
|
|
76
|
-
class PickupLocations < Spree::Page
|
|
77
|
-
# use https://tabler.io/icons to find the icon name
|
|
78
|
-
def icon_name
|
|
79
|
-
'map-marker-alt'
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# This method is used to determine if the page is customizable via page builder
|
|
83
|
-
def customizable?
|
|
84
|
-
true
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# this is the URL used to preview the page in the page builder UI
|
|
88
|
-
def page_builder_url
|
|
89
|
-
return unless page_builder_url_exists?(:pickup_locations_path)
|
|
90
|
-
|
|
91
|
-
Spree::Core::Engine.routes.url_helpers.pickup_locations_path
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# this is the default sections that will be shown on the page
|
|
95
|
-
# in the later guide for sections you will learn how to add custom sections
|
|
96
|
-
def default_sections
|
|
97
|
-
[
|
|
98
|
-
Spree::PageSections::PageTitle.new
|
|
99
|
-
]
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
You will need to register the new page in the `config/initializers/spree.rb` file:
|
|
107
|
-
|
|
108
|
-
**Spree 5.2+:**
|
|
109
|
-
|
|
110
|
-
```ruby config/initializers/spree.rb
|
|
111
|
-
Rails.application.config.after_initialize do
|
|
112
|
-
Spree.page_builder.pages << Spree::Pages::PickupLocations
|
|
113
|
-
end
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Spree 5.1 and below:**
|
|
117
|
-
|
|
118
|
-
```ruby config/initializers/spree.rb
|
|
119
|
-
Rails.application.config.after_initialize do
|
|
120
|
-
Rails.application.config.spree.pages << Spree::Pages::PickupLocations
|
|
121
|
-
end
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
Now, the controller:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
mkdir -p app/controllers/spree && touch app/controllers/spree/pickup_locations_controller.rb
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
```ruby
|
|
132
|
-
# app/controllers/spree/pickup_locations_controller.rb
|
|
133
|
-
module Spree
|
|
134
|
-
class PickupLocationsController < StoreController
|
|
135
|
-
def index
|
|
136
|
-
@current_page = current_theme.pages.find_by(type: 'Spree::Pages::PickupLocations') # this is very important, without this the page will not be found
|
|
137
|
-
@pickup_locations = current_store.pickup_locations
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Lastly we need to add a view file for the page:
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
mkdir -p app/views/spree/pickup_locations && touch app/views/spree/pickup_locations/index.html.erb
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
And add the following code to the view file:
|
|
150
|
-
|
|
151
|
-
```erb
|
|
152
|
-
<%= render_page(current_page, pickup_locations: @pickup_locations) %>
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
`render_page` is a helper method defined in the [Spree::PageHelper](https://github.com/spree/spree/blob/main/storefront/app/helpers/spree/page_helper.rb) module that renders the page. It fetches all page sections and renders them one by one in the order they are set in the page builder by store staff.
|
|
156
|
-
|
|
157
|
-
Passing `pickup_locations` variable to the `render_page` method allows you to use it in the page sections templates, eg.
|
|
158
|
-
|
|
159
|
-
```erb
|
|
160
|
-
<%= pickup_locations.each do |pickup_location| %>
|
|
161
|
-
<%= pickup_location.name %>
|
|
162
|
-
<% end %>
|
|
163
|
-
```
|