spree_google_analytics 1.0.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.
- checksums.yaml +7 -0
- data/LICENSE.md +14 -0
- data/README.md +61 -0
- data/Rakefile +21 -0
- data/app/assets/config/spree_google_analytics_manifest.js +1 -0
- data/app/assets/images/integration_icons/google-analytics-logo.png +0 -0
- data/app/controllers/spree_google_analytics/store_controller_decorator.rb +9 -0
- data/app/helpers/spree_google_analytics/base_helper.rb +81 -0
- data/app/models/spree/integrations/google_analytics.rb +17 -0
- data/app/presenters/spree_google_analytics/checkout_presenter.rb +12 -0
- data/app/presenters/spree_google_analytics/order_presenter.rb +59 -0
- data/app/presenters/spree_google_analytics/payment_presenter.rb +7 -0
- data/app/presenters/spree_google_analytics/product_presenter.rb +54 -0
- data/app/views/spree/admin/integrations/forms/_google_analytics.html.erb +16 -0
- data/app/views/spree_google_analytics/_add_to_cart.html.erb +9 -0
- data/app/views/spree_google_analytics/_add_to_wishlist.erb +9 -0
- data/app/views/spree_google_analytics/_body_end.html.erb +27 -0
- data/app/views/spree_google_analytics/_cart.html.erb +11 -0
- data/app/views/spree_google_analytics/_checkout_complete.html.erb +15 -0
- data/app/views/spree_google_analytics/_head.html.erb +34 -0
- data/app/views/spree_google_analytics/_product.html.erb +7 -0
- data/app/views/spree_google_analytics/_remove_from_cart.html.erb +9 -0
- data/config/initializers/spree.rb +17 -0
- data/config/locales/en.yml +10 -0
- data/config/routes.rb +3 -0
- data/lib/generators/spree_google_analytics/install/install_generator.rb +20 -0
- data/lib/spree_google_analytics/configuration.rb +13 -0
- data/lib/spree_google_analytics/engine.rb +28 -0
- data/lib/spree_google_analytics/factories.rb +3 -0
- data/lib/spree_google_analytics/testing_support/factories/google_analytics_integration.rb +7 -0
- data/lib/spree_google_analytics/version.rb +7 -0
- data/lib/spree_google_analytics.rb +5 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6c60f82dafa6c0ddced33284212aab54aaee082b7f2099cfd864e709774b3a54
|
4
|
+
data.tar.gz: a0fa0447fa1a82e9ddf06c4b1eb9153bc72e92206dd5a085c2d6f3f1334320c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4e7f62f44a99df591d50f0f77fec46088f47bc64e598567beb94a661949527d2c8a839c5311635d8a2bffbd70a47be02e4223bb3baf0643de25710abffc1a151
|
7
|
+
data.tar.gz: 84ed673c296694e8cfe422fcd99413ce4547db6d62a0ba7853f988a473b94ff270be41b173b943f0ce5a63923caac14dca73f32beb67482be2e20a7c02f119e3
|
data/LICENSE.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# LICENSE
|
2
|
+
|
3
|
+
Copyright (c) 2025 Vendo Connect Inc.
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU Affero General Public License for more details.
|
12
|
+
|
13
|
+
You should have received a copy of the GNU Affero General Public License
|
14
|
+
along with this program. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Spree Google analytics
|
2
|
+
|
3
|
+
This is a Google analytics extension for [Spree Commerce](https://spreecommerce.org), an open source e-commerce platform built with Ruby on Rails.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
1. Add this extension to your Gemfile with this line:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
bundle add spree_google_analytics
|
11
|
+
```
|
12
|
+
|
13
|
+
2. Run the install generator
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
bundle exec rails g spree_google_analytics:install
|
17
|
+
```
|
18
|
+
|
19
|
+
3. Restart your server
|
20
|
+
|
21
|
+
If your server was running, restart it so that it can find the assets properly.
|
22
|
+
|
23
|
+
## Developing
|
24
|
+
|
25
|
+
1. Create a dummy app
|
26
|
+
|
27
|
+
```bash
|
28
|
+
bundle update
|
29
|
+
bundle exec rake test_app
|
30
|
+
```
|
31
|
+
|
32
|
+
2. Add your new code
|
33
|
+
3. Run tests
|
34
|
+
|
35
|
+
```bash
|
36
|
+
bundle exec rspec
|
37
|
+
```
|
38
|
+
|
39
|
+
When testing your applications integration with this extension you may use it's factories.
|
40
|
+
Simply add this require statement to your spec_helper:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
require 'spree_google_analytics/factories'
|
44
|
+
```
|
45
|
+
|
46
|
+
## Releasing a new version
|
47
|
+
|
48
|
+
```shell
|
49
|
+
bundle exec gem bump -p -t
|
50
|
+
bundle exec gem release
|
51
|
+
```
|
52
|
+
|
53
|
+
For more options please see [gem-release README](https://github.com/svenfuchs/gem-release)
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
If you'd like to contribute, please take a look at the
|
58
|
+
[instructions](CONTRIBUTING.md) for installing dependencies and crafting a good
|
59
|
+
pull request.
|
60
|
+
|
61
|
+
Copyright (c) 2025 [name of extension creator], released under the New BSD License
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default do
|
10
|
+
if Dir['spec/dummy'].empty?
|
11
|
+
Rake::Task[:test_app].invoke
|
12
|
+
Dir.chdir('../../')
|
13
|
+
end
|
14
|
+
Rake::Task[:spec].invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generates a dummy app for testing'
|
18
|
+
task :test_app do
|
19
|
+
ENV['LIB_NAME'] = 'spree_google_analytics'
|
20
|
+
Rake::Task['extension:test_app'].invoke
|
21
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= link_tree ../images
|
Binary file
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
module StoreControllerDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.helper SpreeGoogleAnalytics::BaseHelper
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Spree::StoreController.prepend(SpreeGoogleAnalytics::StoreControllerDecorator) if defined?(Spree::StoreController)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
module BaseHelper
|
3
|
+
def google_analytics_checkout_json
|
4
|
+
return unless @order.present?
|
5
|
+
|
6
|
+
@google_analytics_checkout_json ||= SpreeGoogleAnalytics::CheckoutPresenter.new(order: @order).call.to_json.html_safe
|
7
|
+
end
|
8
|
+
|
9
|
+
def google_analytics_add_shipping_info_json(shipment)
|
10
|
+
SpreeGoogleAnalytics::CheckoutPresenter.new(order: shipment.order).call.merge({ shipping_tier: shipment.shipping_method&.name }).to_json.html_safe
|
11
|
+
end
|
12
|
+
|
13
|
+
def google_analytics_user_properties_json(user)
|
14
|
+
return unless user.present?
|
15
|
+
|
16
|
+
{
|
17
|
+
sign_in_count: user.sign_in_count,
|
18
|
+
created_at: user.created_at&.iso8601.to_s,
|
19
|
+
completed_orders_count: user.orders.complete.count,
|
20
|
+
completed_orders_total: user.orders.complete.sum(:total).to_f
|
21
|
+
}.to_json.html_safe
|
22
|
+
end
|
23
|
+
|
24
|
+
def google_analytics_payment_json
|
25
|
+
return unless @order.present?
|
26
|
+
|
27
|
+
@google_analytics_payment_json ||= SpreeGoogleAnalytics::PaymentPresenter.new(order: @order).call.to_json.html_safe
|
28
|
+
end
|
29
|
+
|
30
|
+
def google_analytics_purchase_json
|
31
|
+
return unless @order.present?
|
32
|
+
|
33
|
+
@google_analytics_purchase_json ||= SpreeGoogleAnalytics::OrderPresenter.new(order: @order).call.to_json.html_safe
|
34
|
+
end
|
35
|
+
|
36
|
+
def google_analytics_view_item_json(variant = nil)
|
37
|
+
variant ||= @selected_variant || @variant_from_options || @product&.default_variant
|
38
|
+
return unless variant.present?
|
39
|
+
|
40
|
+
{
|
41
|
+
currency: current_currency,
|
42
|
+
value: variant.amount_in(current_currency).to_f,
|
43
|
+
items: [
|
44
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
45
|
+
store_name: current_store.name,
|
46
|
+
resource: variant,
|
47
|
+
quantity: 1
|
48
|
+
).call
|
49
|
+
]
|
50
|
+
}.to_json.html_safe
|
51
|
+
end
|
52
|
+
|
53
|
+
def google_analytics_cart_event_json(line_item, quantity, position)
|
54
|
+
{
|
55
|
+
currency: line_item.currency,
|
56
|
+
value: line_item.amount.to_f,
|
57
|
+
items: [
|
58
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
59
|
+
resource: line_item,
|
60
|
+
quantity: quantity,
|
61
|
+
position: position
|
62
|
+
).call
|
63
|
+
]
|
64
|
+
}.to_json.html_safe
|
65
|
+
end
|
66
|
+
|
67
|
+
def google_analytics_add_to_wishlist_event_json(variant)
|
68
|
+
{
|
69
|
+
currency: current_currency,
|
70
|
+
value: variant.amount_in(current_currency),
|
71
|
+
items: [
|
72
|
+
SpreeGoogleAnalytics::ProductPresenter.new(
|
73
|
+
store_name: current_store.name,
|
74
|
+
resource: variant,
|
75
|
+
quantity: 1
|
76
|
+
).call
|
77
|
+
]
|
78
|
+
}.to_json.html_safe
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spree
|
2
|
+
module Integrations
|
3
|
+
class GoogleAnalytics < Spree::Integration
|
4
|
+
preference :measurement_id, :string
|
5
|
+
|
6
|
+
validates :preferred_measurement_id, presence: true
|
7
|
+
|
8
|
+
def self.integration_group
|
9
|
+
'analytics'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.icon_path
|
13
|
+
'integration_icons/google-analytics-logo.png'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
class OrderPresenter
|
3
|
+
include Spree::BaseHelper
|
4
|
+
|
5
|
+
def initialize(order:)
|
6
|
+
@order = order
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
{
|
11
|
+
currency: @order.currency,
|
12
|
+
transaction_id: @order.number,
|
13
|
+
value: @order.analytics_subtotal,
|
14
|
+
coupon: try_coupon_code,
|
15
|
+
shipping: @order.shipment_total.to_f,
|
16
|
+
tax: @order.additional_tax_total.to_f,
|
17
|
+
items: products(@order)
|
18
|
+
}.merge(try_debug_mode)
|
19
|
+
.merge(gift_card_attributes)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def products(order)
|
25
|
+
return [] if order.line_items.empty?
|
26
|
+
|
27
|
+
product_includes = %i[taxons]
|
28
|
+
product_includes << :vendor if defined?(Spree::Vendor)
|
29
|
+
|
30
|
+
@products ||= order.line_items.includes(variant: { product: product_includes }).map.with_index do |line_item, index|
|
31
|
+
ProductPresenter.new(
|
32
|
+
resource: line_item,
|
33
|
+
quantity: line_item.quantity,
|
34
|
+
position: index + 1
|
35
|
+
).call
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def try_debug_mode
|
40
|
+
ENV['GA_DEBUG_MODE'].present? ? { debug_mode: 1 } : {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def try_coupon_code
|
44
|
+
(@order.coupon_code || @order.try(:gift_card).try(:code)).to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def gift_card_attributes
|
48
|
+
return {} unless defined?(Spree::GiftCard)
|
49
|
+
return {} unless @order.gift_card.present?
|
50
|
+
|
51
|
+
{
|
52
|
+
gift_card_code: @order.gift_card&.code.to_s.upcase,
|
53
|
+
gift_card_amount: @order.gift_card_total.to_f,
|
54
|
+
gift_card_balance: @order.gift_card&.amount_remaining.to_f,
|
55
|
+
total_minus_store_credits: @order.total_minus_store_credits.to_f
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
class ProductPresenter
|
3
|
+
include Spree::BaseHelper
|
4
|
+
include Spree::ProductsHelper
|
5
|
+
|
6
|
+
# @param resource [Spree::LineItem, Spree::Variant]
|
7
|
+
# @param quantity [Integer]
|
8
|
+
# @param position [Integer]
|
9
|
+
# @param store_name [String]
|
10
|
+
def initialize(resource:, quantity:, position: nil, store_name: nil)
|
11
|
+
@resource = resource
|
12
|
+
@quantity = quantity
|
13
|
+
@position = position
|
14
|
+
@store_name = store_name
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash]
|
18
|
+
def call
|
19
|
+
{
|
20
|
+
item_id: @resource.sku.presence || @resource.product_id,
|
21
|
+
item_name: @resource.name,
|
22
|
+
affiliation: @resource.respond_to?(:order) && @resource.order&.store.present? ? @resource.order.store.name : @store_name,
|
23
|
+
discount: 0.00,
|
24
|
+
index: @position.to_s,
|
25
|
+
item_brand: @resource.product.present? ? @resource.product.brand_name.to_s : '',
|
26
|
+
item_category: taxons[0].to_s,
|
27
|
+
item_category2: taxons[1].to_s,
|
28
|
+
item_category3: taxons[2].to_s,
|
29
|
+
item_category4: taxons[3].to_s,
|
30
|
+
item_category5: taxons[4].to_s,
|
31
|
+
item_list_id: '',
|
32
|
+
item_list_name: '',
|
33
|
+
item_variant: @resource.try(:options_text),
|
34
|
+
location_id: '',
|
35
|
+
price: @resource.price.to_f,
|
36
|
+
quantity: @quantity
|
37
|
+
}.merge(try_promotion_codes_applied_to_line_item)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def try_promotion_codes_applied_to_line_item
|
43
|
+
return {} if @resource.class != Spree::LineItem
|
44
|
+
|
45
|
+
{ coupon: @resource.adjustments.promotion.map do |adjustment|
|
46
|
+
adjustment.source.promotion.code
|
47
|
+
end.compact.uniq.join(',') }
|
48
|
+
end
|
49
|
+
|
50
|
+
def taxons
|
51
|
+
@taxons ||= @resource.product.main_taxon&.pretty_name.to_s.split('->').map(&:strip)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="col-12 col-md-6 p-0">
|
2
|
+
<div class="card mb-4">
|
3
|
+
<div class="card-body">
|
4
|
+
<% if @integration.persisted? %>
|
5
|
+
<div class="alert alert-warning">
|
6
|
+
<%= Spree.t('admin.integrations.google_analytics.reports_warning') %>
|
7
|
+
</div>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= preference_field(@integration, form, 'measurement_id', i18n_scope: 'admin.integrations.google_analytics') %>
|
11
|
+
<p class="mb-0 mt-2">
|
12
|
+
<%= external_link_to 'Where to find my Measurement ID?', 'https://support.google.com/analytics/answer/12270356' %>
|
13
|
+
</p>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? %>
|
2
|
+
<script>
|
3
|
+
if (window.gtag) {
|
4
|
+
<% safely do %>
|
5
|
+
gtag('event', 'add_to_cart', <%= google_analytics_cart_event_json(@line_item, @line_item.quantity, @order.line_items.pluck(:id).index(@line_item.id) + 1) %>);
|
6
|
+
<% end %>
|
7
|
+
}
|
8
|
+
</script>
|
9
|
+
<% end %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? && @wished_item&.variant.present? %>
|
2
|
+
<script>
|
3
|
+
if (window.gtag) {
|
4
|
+
<% safely do %>
|
5
|
+
gtag('event', 'add_to_wishlist', <%= google_analytics_add_to_wishlist_event_json(@wished_item.variant) %>);
|
6
|
+
<% end %>
|
7
|
+
}
|
8
|
+
</script>
|
9
|
+
<% end %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? %>
|
2
|
+
<script>
|
3
|
+
if (window.gtag) {
|
4
|
+
<% if controller_name == 'checkout' %>
|
5
|
+
<% if @order && session[:checkout_started] %>
|
6
|
+
<% safely do %>
|
7
|
+
gtag('event', 'begin_checkout', <%= google_analytics_checkout_json %>);
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% if @order && session[:checkout_step_completed] == 'delivery' %>
|
12
|
+
<% safely do %>
|
13
|
+
<% @order.shipments.each do |shipment| %>
|
14
|
+
gtag('event', 'add_shipping_info', <%= google_analytics_add_shipping_info_json(shipment) %>);
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% if controller_name == 'search' && action_name == 'show' && query.present? %>
|
21
|
+
<% safely do %>
|
22
|
+
gtag('event', 'search', <%= raw({ search_term: ERB::Util.html_escape(query) }.to_json) %>);
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
}
|
26
|
+
</script>
|
27
|
+
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? %>
|
2
|
+
<script>
|
3
|
+
if (window.gtag) {
|
4
|
+
<% if @order.present? && @line_items.any? %>
|
5
|
+
window.addEventListener('slideover:open', () => {
|
6
|
+
gtag('event', 'view_cart', <%= google_analytics_checkout_json %>);
|
7
|
+
})
|
8
|
+
<% end %>
|
9
|
+
}
|
10
|
+
</script>
|
11
|
+
<% end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? %>
|
2
|
+
<script>
|
3
|
+
if (window.gtag) {
|
4
|
+
<% safely do %>
|
5
|
+
<% if @order.user.present? %>
|
6
|
+
gtag('set', 'user_id', "<%= @order.reload.user_id %>");
|
7
|
+
gtag('set', 'user_properties', <%= google_analytics_user_properties_json(@order.user) %>);
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
gtag('event', 'add_payment_info', <%= google_analytics_payment_json %>);
|
11
|
+
gtag('event', 'purchase', <%= google_analytics_purchase_json %>);
|
12
|
+
<% end %>
|
13
|
+
}
|
14
|
+
</script>
|
15
|
+
<% end %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% if store_integration('google_analytics').present? %>
|
2
|
+
<!-- Google tag (gtag.js) -->
|
3
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= store_integration('google_analytics').preferred_measurement_id %>"></script>
|
4
|
+
<script>
|
5
|
+
window.dataLayer = window.dataLayer || [];
|
6
|
+
function gtag(){dataLayer.push(arguments);}
|
7
|
+
|
8
|
+
<% if defined?(store_integration('cookie_first')) && store_integration('cookie_first').present? %>
|
9
|
+
gtag('consent', 'default', {
|
10
|
+
'ad_storage': 'denied',
|
11
|
+
'ad_user_data': 'denied',
|
12
|
+
'ad_personalization': 'denied',
|
13
|
+
'analytics_storage': 'denied',
|
14
|
+
'functionality_storage': 'denied',
|
15
|
+
'security_storage': 'granted',
|
16
|
+
'wait_for_update': 2000
|
17
|
+
});
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
gtag('js', new Date());
|
21
|
+
GA_MEASUREMENT_ID = "<%= store_integration('google_analytics').preferred_measurement_id %>";
|
22
|
+
|
23
|
+
<% if ENV['GA_DEBUG_MODE'].present? %>
|
24
|
+
gtag('config', GA_MEASUREMENT_ID, { "debug_mode": true });
|
25
|
+
<% else %>
|
26
|
+
gtag('config', GA_MEASUREMENT_ID);
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<% if try_spree_current_user %>
|
30
|
+
gtag('set', 'user_id', "<%= try_spree_current_user.id %>");
|
31
|
+
gtag('set', 'user_properties', <%= google_analytics_user_properties_json(try_spree_current_user) %>);
|
32
|
+
<% end %>
|
33
|
+
</script>
|
34
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Rails.application.config.after_initialize do
|
2
|
+
Rails.application.config.spree.integrations << Spree::Integrations::GoogleAnalytics
|
3
|
+
|
4
|
+
if Rails.application.config.respond_to?(:spree_storefront)
|
5
|
+
Rails.application.config.spree_storefront.head_partials << 'spree_google_analytics/head'
|
6
|
+
Rails.application.config.spree_storefront.body_end_partials << 'spree_google_analytics/body_end'
|
7
|
+
|
8
|
+
Rails.application.config.spree_storefront.cart_partials << 'spree_google_analytics/cart'
|
9
|
+
Rails.application.config.spree_storefront.add_to_cart_partials << 'spree_google_analytics/add_to_cart'
|
10
|
+
Rails.application.config.spree_storefront.remove_from_cart_partials << 'spree_google_analytics/remove_from_cart'
|
11
|
+
|
12
|
+
Rails.application.config.spree_storefront.checkout_complete_partials << 'spree_google_analytics/checkout_complete'
|
13
|
+
|
14
|
+
Rails.application.config.spree_storefront.product_partials << 'spree_google_analytics/product'
|
15
|
+
Rails.application.config.spree_storefront.add_to_wishlist_partials << 'spree_google_analytics/add_to_wishlist'
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
spree:
|
4
|
+
admin:
|
5
|
+
integrations:
|
6
|
+
google_analytics:
|
7
|
+
description: Google Analytics 4 is a powerful tool that helps businesses understand and analyze their website and app data.
|
8
|
+
reports_warning: It can take up to 48 hours for the data to appear in standard reports
|
9
|
+
measurement_id: Measurement ID
|
10
|
+
api_secret: API Secret
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
class_option :migrate, type: :boolean, default: true
|
5
|
+
|
6
|
+
def add_migrations
|
7
|
+
run 'bundle exec rake railties:install:migrations FROM=spree_google_analytics'
|
8
|
+
end
|
9
|
+
|
10
|
+
def run_migrations
|
11
|
+
run_migrations = options[:migrate] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
|
12
|
+
if run_migrations
|
13
|
+
run 'bin/rails db:migrate'
|
14
|
+
else
|
15
|
+
puts 'Skipping rails db:migrate, don\'t forget to run it!'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
class Configuration < Spree::Preferences::Configuration
|
3
|
+
|
4
|
+
# Some example preferences are shown below, for more information visit:
|
5
|
+
# https://docs.spreecommerce.org/developer/contributing/creating-an-extension
|
6
|
+
|
7
|
+
# preference :enabled, :boolean, default: true
|
8
|
+
# preference :dark_chocolate, :boolean, default: true
|
9
|
+
# preference :color, :string, default: 'Red'
|
10
|
+
# preference :favorite_number, :integer
|
11
|
+
# preference :supported_locales, :array, default: [:en]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SpreeGoogleAnalytics
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
require 'spree/core'
|
4
|
+
isolate_namespace Spree
|
5
|
+
engine_name 'spree_google_analytics'
|
6
|
+
|
7
|
+
# use rspec for tests
|
8
|
+
config.generators do |g|
|
9
|
+
g.test_framework :rspec
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer 'spree_google_analytics.environment', before: :load_config_initializers do |_app|
|
13
|
+
SpreeGoogleAnalytics::Config = SpreeGoogleAnalytics::Configuration.new
|
14
|
+
end
|
15
|
+
|
16
|
+
initializer 'spree_google_analytics.assets' do |app|
|
17
|
+
app.config.assets.precompile += %w[spree_google_analytics_manifest]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.activate
|
21
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
|
22
|
+
Rails.configuration.cache_classes ? require(c) : load(c)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
config.to_prepare(&method(:activate).to_proc)
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spree_google_analytics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vendo Connect Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: spree
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.0.beta
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.0.beta
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: spree_storefront
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.1.0.beta
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 5.1.0.beta
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: spree_admin
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.1.0.beta
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.1.0.beta
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: spree_extension
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email: hello@spreecommerce.org
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- LICENSE.md
|
76
|
+
- README.md
|
77
|
+
- Rakefile
|
78
|
+
- app/assets/config/spree_google_analytics_manifest.js
|
79
|
+
- app/assets/images/integration_icons/google-analytics-logo.png
|
80
|
+
- app/controllers/spree_google_analytics/store_controller_decorator.rb
|
81
|
+
- app/helpers/spree_google_analytics/base_helper.rb
|
82
|
+
- app/models/spree/integrations/google_analytics.rb
|
83
|
+
- app/presenters/spree_google_analytics/checkout_presenter.rb
|
84
|
+
- app/presenters/spree_google_analytics/order_presenter.rb
|
85
|
+
- app/presenters/spree_google_analytics/payment_presenter.rb
|
86
|
+
- app/presenters/spree_google_analytics/product_presenter.rb
|
87
|
+
- app/views/spree/admin/integrations/forms/_google_analytics.html.erb
|
88
|
+
- app/views/spree_google_analytics/_add_to_cart.html.erb
|
89
|
+
- app/views/spree_google_analytics/_add_to_wishlist.erb
|
90
|
+
- app/views/spree_google_analytics/_body_end.html.erb
|
91
|
+
- app/views/spree_google_analytics/_cart.html.erb
|
92
|
+
- app/views/spree_google_analytics/_checkout_complete.html.erb
|
93
|
+
- app/views/spree_google_analytics/_head.html.erb
|
94
|
+
- app/views/spree_google_analytics/_product.html.erb
|
95
|
+
- app/views/spree_google_analytics/_remove_from_cart.html.erb
|
96
|
+
- config/initializers/spree.rb
|
97
|
+
- config/locales/en.yml
|
98
|
+
- config/routes.rb
|
99
|
+
- lib/generators/spree_google_analytics/install/install_generator.rb
|
100
|
+
- lib/spree_google_analytics.rb
|
101
|
+
- lib/spree_google_analytics/configuration.rb
|
102
|
+
- lib/spree_google_analytics/engine.rb
|
103
|
+
- lib/spree_google_analytics/factories.rb
|
104
|
+
- lib/spree_google_analytics/testing_support/factories/google_analytics_integration.rb
|
105
|
+
- lib/spree_google_analytics/version.rb
|
106
|
+
homepage: https://github.com/spree/spree_google_analytics
|
107
|
+
licenses:
|
108
|
+
- AGPL-3.0-or-later
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements:
|
125
|
+
- none
|
126
|
+
rubygems_version: 3.5.3
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Spree Commerce Google analytics Extension
|
130
|
+
test_files: []
|