mountain-goat 0.0.17 → 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +78 -44
- data/lib/mountain-goat/controllers/mountain_goat/mountain_goat_controller.rb +1 -0
- data/lib/mountain-goat/controllers/mountain_goat/mountain_goat_rallies_controller.rb +20 -0
- data/lib/mountain-goat/metric_tracking.rb +1 -0
- data/lib/mountain-goat/public/mg.js +33 -0
- data/lib/mountain-goat/version.rb +1 -1
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp__rallies.html.erb.83814~ +9 -0
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp__rally.html.erb.62757~ +9 -0
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp_index.html.erb.1823~ +22 -0
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/_rallies.html.erb +5 -0
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/_rally.html.erb +9 -0
- data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/index.html.erb +5 -7
- metadata +8 -3
data/README.md
CHANGED
@@ -2,88 +2,122 @@
|
|
2
2
|
|
3
3
|
Embed a high-quality analytics platform in your application in minutes. Gain important A/B test business insights, and view the results and analytics in real time.
|
4
4
|
|
5
|
+
Add simple hooks in your code to display a/b metrics
|
6
|
+
|
7
|
+
<%= metric_variant(:homescreen_text, :user_signup, "Welcome here") %>
|
8
|
+
|
9
|
+
This creates a database entry to a/b test "homescreen_text" against a goal "user signup". Visit "http://yourdomain.com/mg" and you can add / adjust options (variants) for this text. When a user converts on this goal, you run the following code.
|
10
|
+
|
11
|
+
def create
|
12
|
+
record_conversion(:user_signup)
|
13
|
+
...
|
14
|
+
end
|
15
|
+
|
16
|
+
This will track a conversion not only for the goal, but for the variant of "homescreen_text" (and any other associated metrics) that the user was served when he came to the home-page.
|
17
|
+
|
18
|
+
The best part? The mountain-goat admin console is located on your server and you can view and analyze your data in real time.
|
19
|
+
|
20
|
+
- See which metric variants are working and not working ("Cowabunga!" did 120% better than "Enter here", but 10% worse than "Do it rockapella!")
|
21
|
+
- Visually analyze the your metric variants; change them on the fly, adding new ones.
|
22
|
+
- Watch goal conversions in real-time with live-action console (grab the popcorn and watch how your users "sign up" and "view items" and ...)
|
23
|
+
- You can do more than change text, "switch variants" let you enter arbitrary ruby code, change the control of your site ("Do my users have to sign-in before commenting? Let's test!")
|
24
|
+
- Track goals with meta data (record_conversion(:user_signup, :referrer => request.env['HTTP_REFERER']))
|
25
|
+
* Mountain goat tracks as much arbitrary meta data as you want
|
26
|
+
* You are presented with charts for each goal, broken down by meta
|
27
|
+
* See what referrers are driving goals, or which of your blog posts are drawing an audience
|
28
|
+
- Much, much more, e.g. deliver views of this data to your consumers, streamline your site, customize it by user, it's all up to you.
|
29
|
+
|
5
30
|
## Install
|
6
31
|
|
7
32
|
### Mountain Goat gem
|
8
33
|
|
9
|
-
|
10
|
-
|
11
|
-
|
34
|
+
gem install mountain-goat
|
35
|
+
|
36
|
+
### Mountain Goat configration
|
37
|
+
|
38
|
+
Next run generator to create config file and necessary database migration (optionally pass in --password=my_mg_password)
|
39
|
+
|
40
|
+
./script/generate mg
|
41
|
+
|
42
|
+
This will generate
|
43
|
+
|
44
|
+
/config/mountain-goat.yml (for storing a password to access mountain-goat)
|
45
|
+
/db/migrate/xxx_create_mountain_goat_tables.rb (necessary databae migrations to store mg data)
|
12
46
|
|
13
47
|
## Usage
|
14
48
|
|
15
|
-
|
16
|
-
|
17
|
-
*) Conversions are what you want E.g. "user purchases coffee"
|
18
|
-
*) Metrics are how you draw people to convert E.g. "a banner on the store-front"
|
19
|
-
*) Metric variants are A/B tests for metrics E.g. "free coffee" "chuck norris is inside"
|
49
|
+
Mountain Goat hinges around three core concepts:
|
20
50
|
|
21
|
-
|
51
|
+
- Conversions are what you want E.g. "user purchases coffee"
|
52
|
+
- Metrics are how you draw people to convert E.g. "a banner on the store-front"
|
53
|
+
- Metric variants are A/B tests for metrics E.g. "free coffee" "chuck norris is inside"
|
22
54
|
|
23
|
-
|
55
|
+
After you set up your database with some mountain-goat tables, the code will handle populating these tables for you. In your code, you can start A/B testing immediately.
|
24
56
|
|
25
|
-
|
57
|
+
<h2><%= metric_variant(:banner_on_store_front, :user_purchases_coffee, "Now arsenic and gluten-free") %></h2>
|
26
58
|
|
27
|
-
|
59
|
+
The metric_variant function (or, mv for short) takes three parameters:
|
28
60
|
|
29
|
-
|
61
|
+
mv(metric_name, convert_name, default)
|
30
62
|
|
31
|
-
|
63
|
+
This will automatically create a metric and conversion and populate a metric variant with the default value. Easy, eh?
|
32
64
|
|
33
|
-
|
65
|
+
From here, you can go into the mountain-goat admin center and add new metric variants to fit your need. The other important code you'll need to implement is when a goal is achieved.
|
34
66
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
67
|
+
def purchase #coffees_controller.rb
|
68
|
+
record_conversion(:user_purchases_coffee)
|
69
|
+
...
|
70
|
+
end
|
39
71
|
|
40
|
-
|
72
|
+
This will go in and record a conversion ("rally") for a user purchasing coffee. Further, it will track a hit for any metric-variants served to that user that relate to this goal. For example "Chuck Norris works here" might get a point.
|
41
73
|
|
42
74
|
## Mountain Goat admin suite
|
43
75
|
|
44
|
-
|
76
|
+
Navigate to /mg in your application to reach the mountain-goat admin center. Here, you can analyze / adjust your A/B tests.
|
45
77
|
|
46
|
-
|
78
|
+
The front page gives you a breakdown of each of your Goals, and the efficacy of each metric and metric-variant. Select a given metric to drill into its variants. Once you are in a specific metric, you'll be able to add new metric-variants and see what works best for your clients.
|
47
79
|
|
48
80
|
## Advanced Features
|
49
81
|
|
50
|
-
|
82
|
+
### Meta data
|
51
83
|
|
52
|
-
|
84
|
+
You can track meta-data with any conversion. E.g.
|
53
85
|
|
54
|
-
|
86
|
+
rc(:user_visit, :referring_domain => request.env['HTTP_REFERER'], :user_id => session[:user_id])
|
55
87
|
|
56
|
-
|
88
|
+
These will be stored with the rally for the conversion and can get used for complex analytics down the line. (see Converts.meta)
|
57
89
|
|
58
|
-
|
90
|
+
### Switch variants
|
59
91
|
|
60
|
-
|
92
|
+
Instead of just serving text, you can also serve flow control in Mountain Goat, like so:
|
61
93
|
|
62
|
-
|
63
|
-
variant.ten_percent do
|
64
|
-
discount = 0.10
|
65
|
-
end
|
94
|
+
sv(:user_discount, :purchase_coffee) do |variant|
|
66
95
|
|
67
|
-
|
68
|
-
|
69
|
-
|
96
|
+
variant.ten_percent do # "ten_percent" is the variant-name
|
97
|
+
discount = 0.10
|
98
|
+
end
|
99
|
+
|
100
|
+
variant.big_winner do
|
101
|
+
discount = 0.90
|
102
|
+
end
|
70
103
|
|
71
|
-
|
72
|
-
|
104
|
+
variant.whomp_whomp(0.5) do #reduce priority to 0.5 (default 1.0)
|
105
|
+
discount = 0.0
|
106
|
+
end
|
73
107
|
end
|
74
|
-
end
|
75
108
|
|
76
|
-
|
109
|
+
Mountain goat will automatically break those down into three cases (:ten_percent, :big_winner, :whomp_whomp) and serve them out at random to the user (with whomp_whomp half as likely to be served as the others).
|
77
110
|
|
78
|
-
|
111
|
+
### Priorities
|
79
112
|
|
80
|
-
|
113
|
+
You may want to test certain items with a lower serve rate (bold new slogans). You can assign priorities to any metric variant. The change of a given metric variant being shown is
|
81
114
|
|
82
|
-
|
115
|
+
my priority / sum(all priorities for this metric)
|
83
116
|
|
84
117
|
## TODO
|
85
|
-
-
|
118
|
+
- Better documentation (rdocs)
|
119
|
+
- Add namespacing to avoid conflicts
|
86
120
|
|
87
121
|
## Copyright
|
88
122
|
|
89
|
-
Copyright (c) 2011 Geoffrey Hayes, drawn.to. See LICENSE for details.
|
123
|
+
Copyright (c) 2011 Geoffrey Hayes, drawn.to. Contact me, Geoff, <geoff@drawn.to> with any questions / ideas / enhacements. See LICENSE for details.
|
@@ -15,4 +15,24 @@ class MountainGoatRalliesController < MountainGoatController
|
|
15
15
|
format.html { }
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
def new_rallies
|
20
|
+
recent_rally = params[:recent_rally].to_i
|
21
|
+
convert = Convert.find(params[:convert_id].to_i) unless params[:convert_id].blank?
|
22
|
+
|
23
|
+
if convert
|
24
|
+
@rallies = convert.rallies.find(:all, :conditions => [ 'id > ?', recent_rally ], :order => "created_at DESC" )
|
25
|
+
else
|
26
|
+
@rallies = Rally.find(:all, :conditions => [ 'id > ?', recent_rally ], :order => "created_at DESC" )
|
27
|
+
end
|
28
|
+
|
29
|
+
if @rallies.count > 0
|
30
|
+
render :json => { :success => true,
|
31
|
+
:result => render_to_string(:partial => 'mountain_goat_rallies/rallies', :locals => { :rallies => @rallies } ),
|
32
|
+
:recent_rally_id => @rallies.first.id }
|
33
|
+
else
|
34
|
+
render :json => { :success => false }
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
18
38
|
end
|
@@ -17,6 +17,7 @@ module MetricTracking
|
|
17
17
|
map.resources :mountain_goat_converts, :has_many => [ :mountain_goat_metrics, :mountain_goat_rallies ]
|
18
18
|
map.resources :mountain_goat_metrics, :has_many => :mountain_goat_metric_variants
|
19
19
|
map.resources :mountain_goat_rallies
|
20
|
+
map.new_rallies '/mg/rallies/new', :controller => :mountain_goat_rallies, :action => :new_rallies
|
20
21
|
map.fresh_metrics '/fresh-metrics', :controller => :mountain_goat_metrics, :action => :fresh_metrics
|
21
22
|
map.connect '/mg/public/:file', :controller => :mountain_goat, :action => :fetch
|
22
23
|
end
|
@@ -11,5 +11,38 @@
|
|
11
11
|
$($(this).data('slider')).slideUp();
|
12
12
|
}
|
13
13
|
}).change();
|
14
|
+
|
15
|
+
if ($('.recent-rally[data-reload="true"]').size() > 0) {
|
16
|
+
setTimeout(function() { reloadRallies(); }, 3000);
|
17
|
+
}
|
18
|
+
|
19
|
+
$('.reload').click(function() { reloadRallies(); });
|
20
|
+
|
21
|
+
var reloadRallies = function() {
|
22
|
+
var rally_id = parseInt($('.recent-rally').data('rally-id'));
|
23
|
+
var convert_id = $('.recent-rally').data('convert-id');
|
24
|
+
if (rally_id) {
|
25
|
+
$.ajax({
|
26
|
+
url: '/mg/rallies/new',
|
27
|
+
data: { 'recent_rally': rally_id, 'convert_id': convert_id },
|
28
|
+
success: function(json) {
|
29
|
+
if (!json.success) {
|
30
|
+
console.log('No new events');
|
31
|
+
} else {
|
32
|
+
$('.recent-rally').data('rally-id', json.recent_rally_id);
|
33
|
+
$('.rally-list').prepend($(json.result));
|
34
|
+
|
35
|
+
$('.rally-list li:gt(100)').remove(); //only show 100 elements
|
36
|
+
}
|
37
|
+
|
38
|
+
if ($('.recent-rally[data-reload="true"]').size() > 0) {
|
39
|
+
setTimeout(function() { reloadRallies(); }, 3000);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
};
|
14
45
|
});
|
46
|
+
|
47
|
+
|
15
48
|
})();
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<div id="container-main" class="mt-rallies">
|
4
|
+
<div class="mountain-goat-panel">
|
5
|
+
<h1>Rallies <% if @convert %>for <%=h @convert.name %><% else %>for all Goals<% end %></h1>
|
6
|
+
|
7
|
+
<% if @rallies.count > 0 %>
|
8
|
+
<ul>
|
9
|
+
<% @rallies.each do |rally| %>
|
10
|
+
<li><%= rally.convert.name %> at <%= rally.created_at.to_s %></li>
|
11
|
+
(
|
12
|
+
<% rally.all_metas.each do |k,v| %>
|
13
|
+
<%= k %>: <%= v %>
|
14
|
+
<% end %>
|
15
|
+
)
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
18
|
+
<% else %>
|
19
|
+
<h2>No rallies for yet this goal.</h2>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
</div>
|
@@ -4,15 +4,13 @@
|
|
4
4
|
<div class="mountain-goat-panel">
|
5
5
|
<h1>Rallies <% if @convert %>for <%=h @convert.name %><% else %>for all Goals<% end %></h1>
|
6
6
|
|
7
|
+
<div class="recent-rally" data-reload="true" data-rally-id="<%= @rallies.first.id %>" data-convert-id="<%= @convert ? @convert.id : '' %>"></div>
|
8
|
+
<a href="javascript:void(0)" class="reload">Reload</a>
|
9
|
+
|
7
10
|
<% if @rallies.count > 0 %>
|
8
|
-
<ul>
|
11
|
+
<ul class="rally-list">
|
9
12
|
<% @rallies.each do |rally| %>
|
10
|
-
|
11
|
-
(
|
12
|
-
<% rally.all_metas.each do |k,v| %>
|
13
|
-
<%= k %>: <%= v %>
|
14
|
-
<% end %>
|
15
|
-
)
|
13
|
+
<%= render 'rally', :rally => rally %>
|
16
14
|
<% end %>
|
17
15
|
</ul>
|
18
16
|
<% else %>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mountain-goat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 59
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 18
|
10
|
+
version: 0.0.18
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoffrey Hayes
|
@@ -118,6 +118,11 @@ files:
|
|
118
118
|
- lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/index.html.erb
|
119
119
|
- lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/new.html.erb
|
120
120
|
- lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/show.html.erb
|
121
|
+
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp__rallies.html.erb.83814~
|
122
|
+
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp__rally.html.erb.62757~
|
123
|
+
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/.tmp_index.html.erb.1823~
|
124
|
+
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/_rallies.html.erb
|
125
|
+
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/_rally.html.erb
|
121
126
|
- lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/index.html.erb
|
122
127
|
- mountain-goat.gemspec
|
123
128
|
- test/fixtures/ci_metas.yml
|