@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.
Files changed (183) hide show
  1. package/README.md +54 -0
  2. package/dist/api-reference/platform/authentication.md +38 -0
  3. package/dist/api-reference/store-api/authentication.md +188 -0
  4. package/dist/api-reference/store-api/errors.md +277 -0
  5. package/dist/api-reference/store-api/idempotency.md +129 -0
  6. package/dist/api-reference/store-api/introduction.md +34 -0
  7. package/dist/api-reference/store-api/localization.md +279 -0
  8. package/dist/api-reference/store-api/metadata.md +160 -0
  9. package/dist/api-reference/store-api/monetary-amounts.md +65 -0
  10. package/dist/api-reference/store-api/querying.md +399 -0
  11. package/dist/api-reference/store-api/rate-limitting.md +103 -0
  12. package/dist/api-reference/store-api/relations.md +185 -0
  13. package/dist/api-reference/storefront/authentication.md +88 -0
  14. package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
  15. package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
  16. package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
  17. package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
  18. package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
  19. package/dist/api-reference/v2/introduction.md +22 -0
  20. package/dist/api-reference/v2/pagination.md +37 -0
  21. package/dist/api-reference/webhooks-events.md +883 -0
  22. package/dist/developer/admin/admin.md +205 -0
  23. package/dist/developer/admin/authentication.md +59 -0
  24. package/dist/developer/admin/components.md +711 -0
  25. package/dist/developer/admin/custom-css.md +243 -0
  26. package/dist/developer/admin/custom-javascript.md +116 -0
  27. package/dist/developer/admin/extending-ui.md +1964 -0
  28. package/dist/developer/admin/form-builder.md +444 -0
  29. package/dist/developer/admin/helper-methods.md +531 -0
  30. package/dist/developer/admin/navigation.md +805 -0
  31. package/dist/developer/admin/tables.md +491 -0
  32. package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
  33. package/dist/developer/cli/quickstart.md +137 -0
  34. package/dist/developer/contributing/creating-an-extension.md +258 -0
  35. package/dist/developer/contributing/developing-spree.md +339 -0
  36. package/dist/developer/contributing/quickstart.md +32 -0
  37. package/dist/developer/contributing/updating-extensions.md +67 -0
  38. package/dist/developer/core-concepts/addresses.md +265 -0
  39. package/dist/developer/core-concepts/adjustments.md +107 -0
  40. package/dist/developer/core-concepts/architecture.md +177 -0
  41. package/dist/developer/core-concepts/calculators.md +323 -0
  42. package/dist/developer/core-concepts/customers.md +230 -0
  43. package/dist/developer/core-concepts/events.md +624 -0
  44. package/dist/developer/core-concepts/imports-exports.md +698 -0
  45. package/dist/developer/core-concepts/inventory.md +191 -0
  46. package/dist/developer/core-concepts/markets.md +250 -0
  47. package/dist/developer/core-concepts/media.md +167 -0
  48. package/dist/developer/core-concepts/metafields.md +187 -0
  49. package/dist/developer/core-concepts/orders.md +328 -0
  50. package/dist/developer/core-concepts/payments.md +710 -0
  51. package/dist/developer/core-concepts/pricing.md +163 -0
  52. package/dist/developer/core-concepts/products.md +360 -0
  53. package/dist/developer/core-concepts/promotions.md +322 -0
  54. package/dist/developer/core-concepts/reports.md +206 -0
  55. package/dist/developer/core-concepts/search-filtering.md +237 -0
  56. package/dist/developer/core-concepts/shipments.md +212 -0
  57. package/dist/developer/core-concepts/slugs.md +111 -0
  58. package/dist/developer/core-concepts/staff-roles.md +123 -0
  59. package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
  60. package/dist/developer/core-concepts/stores.md +117 -0
  61. package/dist/developer/core-concepts/taxes.md +135 -0
  62. package/dist/developer/core-concepts/translations.md +120 -0
  63. package/dist/developer/core-concepts/users.md +299 -0
  64. package/dist/developer/core-concepts/webhooks.md +378 -0
  65. package/dist/developer/create-spree-app/quickstart.md +158 -0
  66. package/dist/developer/customization/api.md +93 -0
  67. package/dist/developer/customization/authentication.md +88 -0
  68. package/dist/developer/customization/checkout.md +204 -0
  69. package/dist/developer/customization/configuration.md +55 -0
  70. package/dist/developer/customization/decorators.md +523 -0
  71. package/dist/developer/customization/dependencies.md +232 -0
  72. package/dist/developer/customization/emails.md +21 -0
  73. package/dist/developer/customization/extensions.md +92 -0
  74. package/dist/developer/customization/metadata.md +236 -0
  75. package/dist/developer/customization/model-preferences.md +130 -0
  76. package/dist/developer/customization/permissions.md +265 -0
  77. package/dist/developer/customization/quickstart.md +229 -0
  78. package/dist/developer/customization/routes.md +24 -0
  79. package/dist/developer/customization/v4/admin-panel.md +78 -0
  80. package/dist/developer/customization/v4/authentication.md +210 -0
  81. package/dist/developer/customization/v4/checkout.md +212 -0
  82. package/dist/developer/customization/v4/deface.md +251 -0
  83. package/dist/developer/customization/v4/images.md +86 -0
  84. package/dist/developer/customization/v4/storefront.md +450 -0
  85. package/dist/developer/deployment/assets.md +87 -0
  86. package/dist/developer/deployment/aws.md +335 -0
  87. package/dist/developer/deployment/caching.md +27 -0
  88. package/dist/developer/deployment/cdn.md +39 -0
  89. package/dist/developer/deployment/database.md +155 -0
  90. package/dist/developer/deployment/docker.md +128 -0
  91. package/dist/developer/deployment/emails.md +77 -0
  92. package/dist/developer/deployment/environment_variables.md +111 -0
  93. package/dist/developer/deployment/heroku.md +51 -0
  94. package/dist/developer/deployment/render.md +95 -0
  95. package/dist/developer/getting-started/quickstart.md +82 -0
  96. package/dist/developer/how-to/custom-payment-method.md +374 -0
  97. package/dist/developer/how-to/custom-promotion.md +373 -0
  98. package/dist/developer/how-to/custom-report.md +387 -0
  99. package/dist/developer/how-to/custom-search-provider.md +230 -0
  100. package/dist/developer/multi-store/quickstart.md +71 -0
  101. package/dist/developer/multi-store/setup.md +38 -0
  102. package/dist/developer/multi-tenant/configuration.md +41 -0
  103. package/dist/developer/multi-tenant/core-concepts.md +75 -0
  104. package/dist/developer/multi-tenant/installation.md +96 -0
  105. package/dist/developer/multi-tenant/quickstart.md +20 -0
  106. package/dist/developer/multi-vendor/installation.md +45 -0
  107. package/dist/developer/multi-vendor/quickstart.md +17 -0
  108. package/dist/developer/sdk/admin/quickstart.md +22 -0
  109. package/dist/developer/sdk/authentication.md +89 -0
  110. package/dist/developer/sdk/configuration.md +225 -0
  111. package/dist/developer/sdk/quickstart.md +82 -0
  112. package/dist/developer/sdk/store/account.md +67 -0
  113. package/dist/developer/sdk/store/cart-checkout.md +140 -0
  114. package/dist/developer/sdk/store/markets.md +151 -0
  115. package/dist/developer/sdk/store/payments.md +96 -0
  116. package/dist/developer/sdk/store/products.md +149 -0
  117. package/dist/developer/sdk/store/wishlists.md +52 -0
  118. package/dist/developer/security/pci_compliance.md +15 -0
  119. package/dist/developer/security/security_policy.md +68 -0
  120. package/dist/developer/storefront/blocks.md +285 -0
  121. package/dist/developer/storefront/custom-css.md +260 -0
  122. package/dist/developer/storefront/custom-javascript.md +166 -0
  123. package/dist/developer/storefront/helper-methods.md +1288 -0
  124. package/dist/developer/storefront/links.md +298 -0
  125. package/dist/developer/storefront/nextjs/architecture.md +150 -0
  126. package/dist/developer/storefront/nextjs/customization.md +141 -0
  127. package/dist/developer/storefront/nextjs/deployment.md +180 -0
  128. package/dist/developer/storefront/nextjs/quickstart.md +92 -0
  129. package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
  130. package/dist/developer/storefront/pages.md +163 -0
  131. package/dist/developer/storefront/sections.md +569 -0
  132. package/dist/developer/storefront/storefront.md +56 -0
  133. package/dist/developer/storefront/themes.md +161 -0
  134. package/dist/developer/tutorial/admin.md +134 -0
  135. package/dist/developer/tutorial/extending-models.md +380 -0
  136. package/dist/developer/tutorial/file-uploads.md +121 -0
  137. package/dist/developer/tutorial/introduction.md +33 -0
  138. package/dist/developer/tutorial/model.md +41 -0
  139. package/dist/developer/tutorial/page-builder.md +487 -0
  140. package/dist/developer/tutorial/rich-text.md +73 -0
  141. package/dist/developer/tutorial/seo.md +332 -0
  142. package/dist/developer/tutorial/storefront.md +352 -0
  143. package/dist/developer/tutorial/testing.md +558 -0
  144. package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
  145. package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
  146. package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
  147. package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
  148. package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
  149. package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
  150. package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
  151. package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
  152. package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
  153. package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
  154. package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
  155. package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
  156. package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
  157. package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
  158. package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
  159. package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
  160. package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
  161. package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
  162. package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
  163. package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
  164. package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
  165. package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
  166. package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
  167. package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
  168. package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
  169. package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
  170. package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
  171. package/dist/developer/upgrades/quickstart.md +36 -0
  172. package/dist/integrations/analytics/google-analytics.md +64 -0
  173. package/dist/integrations/analytics/google-tag-manager.md +78 -0
  174. package/dist/integrations/integrations.md +39 -0
  175. package/dist/integrations/marketing/klaviyo.md +99 -0
  176. package/dist/integrations/payments/adyen.md +90 -0
  177. package/dist/integrations/payments/paypal.md +41 -0
  178. package/dist/integrations/payments/razorpay.md +45 -0
  179. package/dist/integrations/payments/stripe.md +109 -0
  180. package/dist/integrations/search/meilisearch.md +236 -0
  181. package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
  182. package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
  183. package/package.json +27 -0
@@ -0,0 +1,130 @@
1
+ ---
2
+ title: Model Preferences
3
+ ---
4
+
5
+ Model preferences allow you to easily extend Spree models with configuration options. Thanks to this you can store useful information on Spree models, eg.
6
+
7
+ ```ruby
8
+ user.preferred_language = "English"
9
+ user.save
10
+ ```
11
+
12
+ ## Defining Model Preferences
13
+
14
+ To define a model preference, you need to add them to your model class.
15
+
16
+ Make sure to generate a migration to add the `preferences` column to the table. This column will store the preferences in a serialized format.
17
+
18
+ ```ruby
19
+ rails g migration AddPreferencesToSpreeUsers preferences:text
20
+ ```
21
+
22
+ Run the migration.
23
+
24
+ ```ruby
25
+ rails db:migrate
26
+ ```
27
+
28
+ ```ruby
29
+ class Spree::User < ApplicationRecord
30
+ # ... you existing code ...
31
+
32
+ # include the preferable module
33
+ include Spree::Preferences::Preferable
34
+ # define the preferences
35
+ preference :language, :string, default: "English"
36
+ preference :sms_marketing, :boolean, default: false
37
+ end
38
+ ```
39
+
40
+ This will add a `language` preference to the `User` model. The preference will be stored in the newly created `preferences` column of the `spree_users` table. You can add more preferences to the model in the same way.
41
+
42
+ ## Accessing Model Preferences
43
+
44
+ Once preferences have been defined for a model, they can be accessed either using the shortcut methods that are generated for each preference or the generic methods that are not specific to a particular preference.
45
+
46
+ ### Shortcut Methods
47
+
48
+ There are several shortcut methods that are generated. They are shown below.
49
+
50
+ Query methods:
51
+
52
+ ```ruby
53
+ user.prefers_sms_marketing? # => false
54
+ ```
55
+
56
+ Reader methods:
57
+
58
+ ```ruby
59
+ user.preferred_sms_marketing # => false
60
+ user.preferred_language # => "English"
61
+ ```
62
+
63
+ Writer methods:
64
+
65
+ ```ruby
66
+ user.prefers_sms_marketing = false # => false
67
+ user.preferred_language = "English" # => "English"
68
+ ```
69
+
70
+ > **NOTE:** Remember to run `user.save` after setting the preference value to save the changes to the database.
71
+
72
+ Check if a preference is available:
73
+
74
+ ```ruby
75
+ user.has_preference? :sms_marketing
76
+ ```
77
+
78
+ ### Generic Methods
79
+
80
+ Each shortcut method is essentially a wrapper for the various generic methods shown below:
81
+
82
+ Query method:
83
+
84
+ ```ruby
85
+ user.prefers?(:sms_marketing) # => false
86
+ user.prefers?(:language) # => false
87
+ ```
88
+
89
+ Reader methods:
90
+
91
+ ```ruby
92
+ user.preferred(:sms_marketing) # => false
93
+ user.preferred(:language) # => "English"
94
+ ```
95
+
96
+ ```ruby
97
+ user.get_preference :sms_marketing
98
+ user.get_preference :language
99
+ ```
100
+
101
+ Writer method:
102
+
103
+ ```ruby
104
+ user.set_preference(:sms_marketing, false) # => false
105
+ user.set_preference(:language, "English") # => "English"
106
+ ```
107
+
108
+ ### Accessing All Preferences
109
+
110
+ You can get a hash of all stored preferences by accessing the `preferences` helper:
111
+
112
+ ```ruby
113
+ user.preferences # => {"language"=>"English", "sms_marketing"=>false}
114
+ ```
115
+
116
+ This hash will contain the value for every preference that has been defined for the model instance, whether the value is the default or one that has been previously stored.
117
+
118
+ ## Models with preferences
119
+
120
+ The following Spree models already have preferences defined:
121
+
122
+ * `Spree::Calculator`
123
+ * `Spree::Gateway`
124
+ * `Spree::PageBlock`
125
+ * `Spree::PageSection`
126
+ * `Spree::Page`
127
+ * `Spree::PaymentMethod`
128
+ * `Spree::PromotionRule`
129
+ * `Spree::Store`
130
+ * `Spree::Theme`
@@ -0,0 +1,265 @@
1
+ ---
2
+ title: Permissions
3
+ ---
4
+
5
+ Spree uses [CanCanCan](https://github.com/CanCanCommunity/cancancan) for authorization. The permission system allows you to define granular access control for different user roles.
6
+
7
+ ## Permission Sets (Recommended)
8
+
9
+ Permission Sets provide a clean, modular way to manage permissions. Each permission set is a reusable group of permissions that can be assigned to roles.
10
+
11
+ ### How It Works
12
+
13
+ 1. **Roles** - Determine which permission sets govern a user's access (e.g., `admin`, `customer_service`)
14
+ 2. **Permission Sets** - Contain the logic defining what actions users can perform on resources
15
+ 3. **Role Configuration** - Associates roles with their corresponding permission sets
16
+
17
+ ### Configuring Roles
18
+
19
+ In your `config/initializers/spree.rb`, configure which permission sets are assigned to each role:
20
+
21
+ ```ruby
22
+ Rails.application.config.after_initialize do
23
+ # Default permissions for all users (guests and logged-in customers)
24
+ Spree.permissions.assign(:default, [Spree::PermissionSets::DefaultCustomer])
25
+
26
+ # Full admin access
27
+ Spree.permissions.assign(:admin, [Spree::PermissionSets::SuperUser])
28
+
29
+ # Custom role with specific permissions
30
+ Spree.permissions.assign(:customer_service, [
31
+ Spree::PermissionSets::DashboardDisplay,
32
+ Spree::PermissionSets::OrderManagement,
33
+ Spree::PermissionSets::UserDisplay
34
+ ])
35
+
36
+ # Merchandiser role for product management
37
+ Spree.permissions.assign(:merchandiser, [
38
+ Spree::PermissionSets::DashboardDisplay,
39
+ Spree::PermissionSets::ProductManagement,
40
+ Spree::PermissionSets::StockManagement
41
+ ])
42
+ end
43
+ ```
44
+
45
+ ### Built-in Permission Sets
46
+
47
+ | Permission Set | Description |
48
+ |---------------|-------------|
49
+ | `SuperUser` | Full admin access with safety restrictions |
50
+ | `DefaultCustomer` | Basic storefront permissions (browse, checkout, manage own account) |
51
+ | `DashboardDisplay` | View admin dashboard |
52
+ | `OrderDisplay` | Read-only access to orders |
53
+ | `OrderManagement` | Full order management (view, edit, refund, etc.) |
54
+ | `ProductDisplay` | Read-only access to products and catalog |
55
+ | `ProductManagement` | Full catalog management (products, variants, taxonomies) |
56
+ | `UserDisplay` | Read-only access to users |
57
+ | `UserManagement` | Full user management |
58
+ | `StockDisplay` | Read-only access to inventory |
59
+ | `StockManagement` | Full inventory management |
60
+ | `PromotionManagement` | Manage promotions and coupon codes |
61
+ | `ConfigurationManagement` | Manage store settings, shipping, taxes, etc. |
62
+ | `RoleManagement` | Manage roles (except the protected admin role) |
63
+
64
+ ### Creating Custom Permission Sets
65
+
66
+ Create a new permission set in `app/models/spree/permission_sets/`:
67
+
68
+ ```ruby
69
+ # app/models/spree/permission_sets/warehouse_management.rb
70
+ module Spree
71
+ module PermissionSets
72
+ class WarehouseManagement < Base
73
+ def activate!
74
+ can :manage, Spree::StockItem
75
+ can :manage, Spree::StockLocation
76
+ can :manage, Spree::StockMovement
77
+ can :manage, Spree::Shipment
78
+ can [:read, :admin], Spree::Order
79
+ end
80
+ end
81
+ end
82
+ end
83
+ ```
84
+
85
+ Then assign it to a role:
86
+
87
+ ```ruby
88
+ Spree.permissions.assign(:warehouse_staff, [
89
+ Spree::PermissionSets::DashboardDisplay,
90
+ Spree::PermissionSets::WarehouseManagement
91
+ ])
92
+ ```
93
+
94
+ ### Permission Set API
95
+
96
+ Within a permission set, you have access to:
97
+
98
+ - `can(action, subject, conditions = {})` - Grant permission
99
+ - `cannot(action, subject, conditions = {})` - Deny permission
100
+ - `can?(action, subject)` - Check if permission exists
101
+ - `user` - The current user
102
+ - `store` - The current store (for multi-store setups)
103
+
104
+ ```ruby
105
+ module Spree
106
+ module PermissionSets
107
+ class OrderManagementForOwnOrders < Base
108
+ def activate!
109
+ # Users can only manage orders they created
110
+ can :manage, Spree::Order, created_by_id: user.id
111
+
112
+ # But cannot cancel any order
113
+ cannot :cancel, Spree::Order
114
+
115
+ # Unless it's cancellable
116
+ can :cancel, Spree::Order, &:allow_cancel?
117
+ end
118
+ end
119
+ end
120
+ end
121
+ ```
122
+
123
+ ### Managing Permission Configuration
124
+
125
+ ```ruby
126
+ # Assign permission sets to a role
127
+ Spree.permissions.assign(:customer_service, [
128
+ Spree::PermissionSets::OrderDisplay,
129
+ Spree::PermissionSets::UserManagement
130
+ ])
131
+
132
+ # Add more permission sets to an existing role
133
+ Spree.permissions.assign(:customer_service, [
134
+ Spree::PermissionSets::StockDisplay
135
+ ])
136
+
137
+ # Clear all permission sets from a role
138
+ Spree.permissions.clear(:customer_service)
139
+
140
+ # Check what permission sets a role has
141
+ Spree.permissions.permission_sets_for(:customer_service)
142
+ # => [Spree::PermissionSets::OrderDisplay, ...]
143
+
144
+ # Check if a role is configured
145
+ Spree.permissions.role_configured?(:customer_service)
146
+ # => true
147
+ ```
148
+
149
+ ## Users and Roles
150
+
151
+ Spree comes with an `admin` role by default. You can create more roles in the Admin Panel or via Rails console:
152
+
153
+ ```ruby
154
+ Spree::Role.find_or_create_by(name: 'customer_service')
155
+ Spree::Role.find_or_create_by(name: 'merchandiser')
156
+ Spree::Role.find_or_create_by(name: 'warehouse_staff')
157
+ ```
158
+
159
+ Assign a role to a user:
160
+
161
+ ```ruby
162
+ user = Spree.user_class.find_by(email: 'john@example.com')
163
+ role = Spree::Role.find_by(name: 'customer_service')
164
+ user.spree_roles << role
165
+ ```
166
+
167
+ ### Default Role Behavior
168
+
169
+ - Users with **no roles assigned** automatically get the `:default` role permissions
170
+ - No `RoleUser` records are created for regular customers
171
+ - Only users with special permissions need explicit role assignments
172
+
173
+ ## Legacy Approach: Custom Ability Classes
174
+
175
+ > **NOTE:** The permission sets approach above is recommended for new projects. The legacy approach below is supported for backward compatibility.
176
+
177
+ ### Adding Custom Permissions via Decorator
178
+
179
+ Create a new ability class in `app/models/customer_service_ability.rb`:
180
+
181
+ ```ruby
182
+ class CustomerServiceAbility
183
+ include CanCan::Ability
184
+
185
+ def initialize(user)
186
+ if user.respond_to?(:has_spree_role?) && user.has_spree_role?('customer_service')
187
+ can :manage, Spree::Order
188
+ end
189
+ end
190
+ end
191
+ ```
192
+
193
+ Register it via a decorator in `app/models/spree/ability_decorator.rb`:
194
+
195
+ ```ruby
196
+ module Spree
197
+ module AbilityDecorator
198
+ def abilities_to_register
199
+ [CustomerServiceAbility]
200
+ end
201
+ end
202
+
203
+ Ability.prepend(AbilityDecorator)
204
+ end
205
+ ```
206
+
207
+ ### Replacing the Ability Class
208
+
209
+ You can replace the entire ability class via [Dependencies](/developer/customization/dependencies):
210
+
211
+ ```ruby
212
+ # config/initializers/spree.rb
213
+ Spree::Dependencies.ability_class = 'CustomAbility'
214
+ ```
215
+
216
+ ```ruby
217
+ # app/models/custom_ability.rb
218
+ class CustomAbility < Spree::Ability
219
+ def initialize(user, options = {})
220
+ alias_cancan_delete_action
221
+
222
+ @user = user || Spree.user_class.new
223
+ @store = options[:store] || Spree::Current.store
224
+
225
+ if @user.respond_to?(:has_spree_role?) && @user.has_spree_role?('admin')
226
+ apply_admin_permissions(@user, options)
227
+ elsif @user.respond_to?(:has_spree_role?) && @user.has_spree_role?(:customer_service)
228
+ apply_customer_service_permissions(@user)
229
+ else
230
+ apply_user_permissions(@user, options)
231
+ end
232
+
233
+ protect_admin_role
234
+ end
235
+
236
+ protected
237
+
238
+ def apply_customer_service_permissions(user)
239
+ can :manage, Spree::Order
240
+ can [:read, :admin], Spree.user_class
241
+ end
242
+ end
243
+ ```
244
+
245
+ ## CanCanCan Reference
246
+
247
+ Spree's permission system is built on CanCanCan. Key concepts:
248
+
249
+ - `can :action, Subject` - Grant permission
250
+ - `can :manage, Subject` - Grant all actions (create, read, update, destroy)
251
+ - `cannot :action, Subject` - Explicitly deny permission
252
+ - `can :action, Subject, conditions` - Conditional permission
253
+
254
+ ```ruby
255
+ # Examples
256
+ can :read, Spree::Product # Can read any product
257
+ can :manage, Spree::Order, user_id: user.id # Can manage own orders
258
+ can :update, Spree::Order do |order| # Block conditions
259
+ order.user == user && !order.completed?
260
+ end
261
+ cannot :destroy, Spree::Order # Cannot destroy any order
262
+ can :destroy, Spree::Order, &:can_be_deleted? # Unless it's deletable
263
+ ```
264
+
265
+ See the [CanCanCan documentation](https://github.com/CanCanCommunity/cancancan) for more details.
@@ -0,0 +1,229 @@
1
+ ---
2
+ title: Quickstart
3
+ og:title: Spree Customization Quickstart
4
+ description: Learn how to customize every part of the Spree stack
5
+ ---
6
+
7
+ Spree is a flexible platform allowing you to customize every part of it to suit your business needs. This guide presents customization options **in order of recommendation** - start from the top and only move down if simpler options don't meet your needs.
8
+
9
+ ## Quick Reference
10
+
11
+ | What you want to do | Recommended approach |
12
+ |---------------------|---------------------|
13
+ | Change store settings (currency, zones, languages) | [Store Settings](#store-settings) |
14
+ | Tweak Spree behavior globally | [Configuration](#configuration) |
15
+ | React to model changes (sync, notifications) | [Events & Subscribers](#events-and-subscribers) |
16
+ | Notify external services | [Webhooks](#webhooks) |
17
+ | Swap core services (cart, checkout, etc.) | [Dependencies](#dependencies) |
18
+ | Add admin menu items | [Admin Navigation](#admin-extensions) |
19
+ | Add sections to admin forms | [Admin Partials](#admin-extensions) |
20
+ | Add searchable/filterable fields | [Ransack Configuration](#search-and-filtering) |
21
+ | Add associations/validations to models | [Decorators](#decorators) (last resort) |
22
+
23
+ **Best for:** Changing currency, shipping zones, languages, and other business settings.
24
+
25
+ There's a lot of Store settings you can change in the admin panel without touching the code.
26
+
27
+ Go to **Admin > Settings**
28
+
29
+ <img src="/images/spree_admin_store_settings.png" alt="Spree Admin Store Settings" />
30
+
31
+ <details>
32
+ <summary>Configuration</summary>
33
+
34
+ **Best for:** Tweaking Spree's behavior globally without modifying source code.
35
+
36
+ Global application configuration allows you to customize various aspects of Spree:
37
+
38
+ ```ruby config/initializers/spree.rb
39
+ Spree.config do |config|
40
+ config.allow_guest_checkout = false
41
+ config.products_per_page = 20
42
+ end
43
+ ```
44
+
45
+ Please see [Configuration](/developer/customization/configuration) section for more information.
46
+
47
+ </details>
48
+
49
+
50
+ <details>
51
+ <summary>Events and Subscribers</summary>
52
+
53
+ **Best for:** Reacting to model changes, syncing with external services, sending notifications, audit logging.
54
+
55
+ > **INFO:** Events are the **recommended way** to add behavior when something happens in Spree, replacing the need for decorator callbacks.
56
+
57
+ Spree's event system lets you subscribe to events like `order.completed`, `product.updated`, `payment.paid`, etc.:
58
+
59
+ ```ruby app/subscribers/my_app/order_completed_subscriber.rb
60
+ module MyApp
61
+ class OrderCompletedSubscriber < Spree::Subscriber
62
+ subscribes_to 'order.completed'
63
+
64
+ def handle(event)
65
+ order = Spree::Order.find_by(id: event.payload['id'])
66
+ return unless order
67
+
68
+ # Sync to external service, send notification, etc.
69
+ ExternalService.notify_order_placed(order)
70
+ end
71
+ end
72
+ end
73
+ ```
74
+
75
+ **Key benefits:**
76
+ - Loose coupling - your code doesn't depend on Spree internals
77
+ - Async by default - keeps requests fast
78
+ - Easier testing and upgrades
79
+
80
+ Please see [Events](/developer/core-concepts/events) section for more information.
81
+
82
+ </details>
83
+
84
+
85
+ <details>
86
+ <summary>Webhooks</summary>
87
+
88
+ **Best for:** Notifying external services (ERPs, CRMs, fulfillment systems) when events occur.
89
+
90
+ Webhooks send HTTP POST requests to external URLs when Spree events happen:
91
+
92
+ - Order completed → Notify fulfillment system
93
+ - Product updated → Sync with PIM
94
+ - Customer created → Add to CRM
95
+
96
+ Configure webhooks in **Admin > Developers > Webhooks** or via the API.
97
+
98
+ Please see [Webhooks](/developer/core-concepts/webhooks) section for more information.
99
+
100
+ </details>
101
+
102
+
103
+ <details>
104
+ <summary>Dependencies</summary>
105
+
106
+ **Best for:** Swapping core services, serializers, and abilities with your own implementations.
107
+
108
+ Spree allows you to replace core classes without modifying them:
109
+
110
+ ```ruby config/initializers/spree.rb
111
+ Spree::Dependencies.cart_add_item_service = "MyCartAddItemService"
112
+ Spree::Dependencies.cart_remove_item_service = "MyCartRemoveItemService"
113
+ ```
114
+
115
+ This is cleaner than decorating services because you provide a complete replacement rather than patching behavior.
116
+
117
+ Please see [Dependencies](dependencies) section for more information.
118
+
119
+ </details>
120
+
121
+
122
+ <details>
123
+ <summary>Admin Extensions</summary>
124
+
125
+ **Best for:** Adding menu items, form sections, dashboard widgets, and other UI elements to the admin panel.
126
+
127
+ Spree provides declarative APIs for extending the admin without decorators or view overrides:
128
+
129
+ **Navigation API** - Add menu items:
130
+ ```ruby config/initializers/spree.rb
131
+ Rails.application.config.after_initialize do
132
+ Spree.admin.navigation.sidebar.add :brands,
133
+ label: :brands,
134
+ url: :admin_brands_path,
135
+ icon: 'award',
136
+ position: 35
137
+ end
138
+ ```
139
+
140
+ **Partials API** - Add sections to forms:
141
+ ```ruby config/initializers/spree.rb
142
+ Spree.admin.partials.product_form << 'spree/admin/products/erp_section'
143
+ ```
144
+
145
+ Please see:
146
+ - [Admin Navigation](/developer/admin/navigation) - For adding menu items
147
+ - [Admin Partials](/developer/admin/extending-ui) - For extending UI
148
+ - [Admin Tables](/developer/admin/tables) - For customizing list views
149
+
150
+ </details>
151
+
152
+
153
+ <details>
154
+ <summary>Search and Filtering</summary>
155
+
156
+ **Best for:** Making custom fields searchable/sortable in the admin and API.
157
+
158
+ Instead of decorating models to add `ransackable_attributes`, use the Ransack configuration API:
159
+
160
+ ```ruby config/initializers/spree.rb
161
+ Spree.ransack.add_attribute :product, :erp_id
162
+ Spree.ransack.add_association :product, :brand
163
+ ```
164
+
165
+ Please see [Search & Filtering](/developer/core-concepts/search-filtering#extending-ransackable-configuration) section for more information.
166
+
167
+ </details>
168
+
169
+
170
+ <details>
171
+ <summary>Authentication</summary>
172
+
173
+ **Best for:** Using your own user model or authentication system.
174
+
175
+ Spree allows you to use your own authentication system instead of the default Devise-based one.
176
+
177
+ You can find more information in the [Authentication](authentication) section.
178
+
179
+ </details>
180
+
181
+
182
+ <details>
183
+ <summary>Checkout flow</summary>
184
+
185
+ **Best for:** Customizing checkout steps and flow.
186
+
187
+ With Spree you can change the checkout flow to fit your business needs - add steps, remove steps, or change the order.
188
+
189
+ Please see [Checkout flow customization section](checkout) for more information.
190
+
191
+ </details>
192
+
193
+
194
+ <details>
195
+ <summary>Decorators</summary>
196
+
197
+ **Best for:** Adding associations, validations, scopes, and methods to Spree models. Use as a last resort.
198
+
199
+ > **WARNING:** Decorators should be used **only when no other option works**. They tightly couple your code to Spree internals and can break during upgrades.
200
+ >
201
+ > **Do NOT use decorators for:**
202
+ > - After-save callbacks → Use [Events](/developer/core-concepts/events) instead
203
+ > - External service sync → Use [Webhooks](/developer/core-concepts/webhooks) instead
204
+ > - Custom service logic → Use [Dependencies](dependencies) instead
205
+ > - Admin UI changes → Use [Admin Extensions](#admin-extensions) instead
206
+
207
+ Decorators are still appropriate for structural changes:
208
+
209
+ ```ruby app/models/spree/product_decorator.rb
210
+ module Spree
211
+ module ProductDecorator
212
+ def self.prepended(base)
213
+ base.belongs_to :brand, class_name: 'MyApp::Brand', optional: true
214
+ base.validates :external_id, presence: true
215
+ base.scope :featured, -> { where(featured: true) }
216
+ end
217
+
218
+ def full_title
219
+ "#{brand&.name} #{name}"
220
+ end
221
+ end
222
+
223
+ Product.prepend(ProductDecorator)
224
+ end
225
+ ```
226
+
227
+ Please see [Decorators](decorators) section for more information.
228
+
229
+ </details>
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: Routes
3
+ description: Learn how to customize the routes in Spree
4
+ ---
5
+
6
+ ## Default configuration
7
+
8
+ By default Spree is mounted at the root of your domain, this code will be inserted into `config/routes.rb`:
9
+
10
+ ```ruby
11
+ mount Spree::Core::Engine, at: '/'
12
+ ```
13
+
14
+ This means that Spree will be available at the root of your domain, for example `http://localhost:3000`.
15
+
16
+ ## Customizing the mount point
17
+
18
+ You can customize this simply by changing the `:at` specification in `config/routes.rb` to be something else. For example, if you would like Spree to be mounted at `/shop`, you can write this:
19
+
20
+ ```ruby
21
+ mount Spree::Core::Engine, at: `/shop`
22
+ ```
23
+
24
+ The different parts of Spree (API, Admin) will be mounted there as well, eg. `http://localhost:3000/shop/products`.