shopify_app_lrb3 5.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/CHANGELOG +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +19 -0
  6. data/README.md +182 -0
  7. data/RELEASING +16 -0
  8. data/Rakefile +11 -0
  9. data/install.rb +25 -0
  10. data/lib/generators/shopify_app/README +23 -0
  11. data/lib/generators/shopify_app/USAGE +22 -0
  12. data/lib/generators/shopify_app/shopify_app_generator.rb +69 -0
  13. data/lib/generators/shopify_app/templates/app/assets/images/favicon.png +0 -0
  14. data/lib/generators/shopify_app/templates/app/assets/images/grid-18px.png +0 -0
  15. data/lib/generators/shopify_app/templates/app/assets/images/shopify-114.png +0 -0
  16. data/lib/generators/shopify_app/templates/app/assets/images/shopify-57.png +0 -0
  17. data/lib/generators/shopify_app/templates/app/assets/images/shopify-72.png +0 -0
  18. data/lib/generators/shopify_app/templates/app/assets/images/shopify.png +0 -0
  19. data/lib/generators/shopify_app/templates/app/assets/javascripts/application.js +15 -0
  20. data/lib/generators/shopify_app/templates/app/assets/stylesheets/application.css +10 -0
  21. data/lib/generators/shopify_app/templates/app/assets/stylesheets/imports.css.less +5 -0
  22. data/lib/generators/shopify_app/templates/app/assets/stylesheets/shopify_app.css.scss +150 -0
  23. data/lib/generators/shopify_app/templates/app/assets/stylesheets/shopify_app_buttons.css.less +77 -0
  24. data/lib/generators/shopify_app/templates/app/controllers/application_controller.rb +13 -0
  25. data/lib/generators/shopify_app/templates/app/controllers/home_controller.rb +18 -0
  26. data/lib/generators/shopify_app/templates/app/controllers/sessions_controller.rb +52 -0
  27. data/lib/generators/shopify_app/templates/app/helpers/home_helper.rb +9 -0
  28. data/lib/generators/shopify_app/templates/app/helpers/login_helper.rb +3 -0
  29. data/lib/generators/shopify_app/templates/app/helpers/tabs_helper.rb +11 -0
  30. data/lib/generators/shopify_app/templates/app/views/home/design.html.erb +3542 -0
  31. data/lib/generators/shopify_app/templates/app/views/home/index.html.erb +168 -0
  32. data/lib/generators/shopify_app/templates/app/views/home/welcome.html.erb +110 -0
  33. data/lib/generators/shopify_app/templates/app/views/layouts/application.html.erb +79 -0
  34. data/lib/generators/shopify_app/templates/app/views/sessions/new.html.erb +21 -0
  35. data/lib/generators/shopify_app/templates/config/initializers/omniauth.rb +14 -0
  36. data/lib/generators/shopify_app/templates/config/initializers/shopify_session_repository.rb +21 -0
  37. data/lib/generators/shopify_app/templates/public/404.html +40 -0
  38. data/lib/generators/shopify_app/templates/public/422.html +40 -0
  39. data/lib/generators/shopify_app/templates/public/500.html +40 -0
  40. data/lib/generators/shopify_app/templates/public/favicon.png +0 -0
  41. data/lib/generators/shopify_app/templates/public/shopify-114.png +0 -0
  42. data/lib/generators/shopify_app/templates/public/shopify-57.png +0 -0
  43. data/lib/generators/shopify_app/templates/public/shopify-72.png +0 -0
  44. data/lib/shopify_app.rb +20 -0
  45. data/lib/shopify_app/configuration.rb +46 -0
  46. data/lib/shopify_app/in_memory_session_store.rb +25 -0
  47. data/lib/shopify_app/login_protection.rb +39 -0
  48. data/lib/shopify_app/railtie.rb +17 -0
  49. data/lib/shopify_app/shopify_session_repository.rb +22 -0
  50. data/lib/shopify_app/version.rb +3 -0
  51. data/shipit.rubygems.yml +1 -0
  52. data/shopify_app.gemspec +30 -0
  53. data/test/config/development_config_file.yml +7 -0
  54. data/test/config/empty_config_file.yml +1 -0
  55. data/test/config/other_config_file.yml +3 -0
  56. data/test/config/shopify_app.yml +3 -0
  57. data/test/lib/shopify_app/configuration_test.rb +78 -0
  58. data/test/lib/shopify_app/in_memory_session_store_test.rb +35 -0
  59. data/test/lib/shopify_app/shopify_session_repository_test.rb +57 -0
  60. data/test/test_helper.rb +5 -0
  61. metadata +214 -0
@@ -0,0 +1,168 @@
1
+ <header class="jumbotron">
2
+ <div class="inner">
3
+ <div class="container">
4
+ <h1 style="letter-spacing:-3px; margin-bottom:20px;">Where do I start?</h1>
5
+ <p class="lead">An <strong>intro</strong> to using the Shopify App Template<br/>
6
+ including information on the <strong>Shopify API</strong> and <strong>Bootstrap,</strong><br/>
7
+ just to get the ball rolling.</p>
8
+ </div><!-- /container -->
9
+ </div>
10
+ </header>
11
+
12
+ <div class="row">
13
+ <div class="span3">
14
+ <div class="well">
15
+ <h3>Check out the <code>home_controller</code></h3>
16
+ <hr style="margin:2px 0 7px"/>
17
+ <p>The controller in this demo application fetches the newest 5 orders and products and makes them available as instance variables <code>@orders</code> and <code>@products</code></p>
18
+
19
+ <br/>
20
+
21
+ <h3>Take a look at <code>index.html.erb</code></h3>
22
+ <hr style="margin:2px 0 7px"/>
23
+ <p>Index is the Ruby template you are currently viewing. Have a look at the markup and Ruby code to see how the Shopify API is being used. It's located at <code>views/home/index.html.erb</code></p>
24
+ </div>
25
+
26
+ <h3>Additional Docs</h3>
27
+ <p>You can become an expert pretty quickly by reading up on these docs:</p>
28
+
29
+ <ul>
30
+ <li>
31
+ <%= link_to 'API documentation', 'http://www.shopify.com/developers/api/' %>
32
+ <span class="note">Learn what you can do with the Shopify API</span>
33
+ </li><br/>
34
+ <li>
35
+ <%= link_to 'Bootstrap documentation', 'http://twitter.github.com/bootstrap/' %>
36
+ <span class="note">Find out what you can do with Twitter Bootstrap</span>
37
+ </li><br/>
38
+ <li>
39
+ <%= link_to 'Wiki', 'http://wiki.shopify.com/' %>
40
+ <span class="note">Get more information and share your knowledge</span>
41
+ </li><br/>
42
+ <li>
43
+ <%= link_to 'Forum', 'http://forums.shopify.com/community' %>
44
+ <span class="note">Ask questions and see what others already wanted to know</span>
45
+ </li>
46
+ </ul>
47
+
48
+ <hr/>
49
+
50
+ <h3>Once you're ready</h3>
51
+
52
+ <p>We'd love to see what you create using the Shopify API. You can keep up to date on the latest and greatest via the <%= link_to 'Shopify API Twitter Account', 'http://www.twitter.com/shopifyapi' %>. You can also read the latest information on the <%= link_to 'API Publishing Page', 'http://www.shopify.com/developers/publishing/' %>.</p>
53
+
54
+ <br/>
55
+
56
+ <a href="https://twitter.com/shopifyapi" class="twitter-follow-button" data-show-count="false" data-size="large">Follow @shopifyapi</a>
57
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
58
+ </div> <!-- span3 / left-column -->
59
+
60
+
61
+ <div class="span8 offset1">
62
+ <h2>Recent orders</h2>
63
+
64
+ <% if @orders.blank? %>
65
+ <table class="table table-striped">
66
+ <tr>
67
+ <td><em>There are no orders in your store.</em></td>
68
+ </tr>
69
+ </table>
70
+
71
+ <% else %>
72
+
73
+ <table class="table table-striped">
74
+ <thead>
75
+ <tr>
76
+ <th>Order</th>
77
+ <th>Placed by</th>
78
+ <th>Paid</th>
79
+ <th>Fulfillment</th>
80
+ <th>Total</th>
81
+ </tr>
82
+ </thead>
83
+ <% @orders.each do |order| %>
84
+ <tr>
85
+ <td><%= link_to order.name, "https://#{shop_session.url}/admin/orders/#{order.id}", :target => 'blank' %></td>
86
+ <td><%= customer_name(order) %></td>
87
+ <td>
88
+ <span class="label <% if order.financial_status == 'paid' %>label-success<% end %> <% if order.financial_status == 'pending' %>label-warning<% end %> <% if order.financial_status == 'refunded' %>label-important<% end %>"><%= order.financial_status %>
89
+ </span>
90
+ </td>
91
+ <td>
92
+ <% if !order.fulfillment_status %>
93
+ <span class="label">Not Fulfilled</span>
94
+ <% else %>
95
+ <span class="label label-success">Fulfilled</span>
96
+ <% end %>
97
+ </td>
98
+ <td><%= order.total_price %> <%= order.currency %></td>
99
+ </tr>
100
+ <% end %>
101
+ </table>
102
+
103
+ <% end %>
104
+
105
+ <br/>
106
+
107
+ <h2>New Products</h2>
108
+
109
+ <div class="accordion" id="accordion">
110
+
111
+ <% if @products.blank? %>
112
+
113
+ <div class="accordion-group">
114
+ <div class="accordion-heading">
115
+ <em>There are no products in your store.</em>
116
+ </div>
117
+ </div>
118
+
119
+ <% else %>
120
+
121
+ <% @products.each_with_index do |product, index| %>
122
+ <div class="accordion-group">
123
+ <div class="accordion-heading">
124
+
125
+ <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#<%= product.id %>">
126
+ <%= product.title %> <span class="pull-right muted"><%= product.price_range %> <%= shop_session.shop.currency %></span>
127
+ </a>
128
+ </div>
129
+
130
+ <div id="<%= product.id %>" class="accordion-body collapse <% if index == 1 %>in<% end %>">
131
+ <div class="accordion-inner">
132
+
133
+ <% if !product.images.empty? %>
134
+ <div class="polaroid">
135
+ <%= link_to image_tag(product.images.first.medium), '#modal-'+product.id.to_s, :'data-toggle' => 'modal' %>
136
+ </div>
137
+ <% end %>
138
+
139
+ <p><strong>Type:</strong> <%= product.product_type %></p>
140
+ <p><strong>Vendor:</strong> <%= product.vendor %></p>
141
+ <p><%= raw(product.body_html) %></p><br/>
142
+ <% if product.published_at != nil %>
143
+ <p class="muted">Published at <%= Time.parse(product.published_at).strftime("%H:%M on %m/%d/%Y") %></p>
144
+ <% end %>
145
+ <p><%= link_to raw('View in your Shopify Admin <i class="icon-chevron-right" style="opacity:.25"></i>'), "https://#{shop_session.url}/admin/products/#{product.id}", :target => 'blank', :class => 'btn btn-primary' %></p>
146
+ </div>
147
+
148
+ </div>
149
+ </div>
150
+
151
+ <div class="modal hide fade" id="modal-<%= product.id %>" style="display:none;">
152
+ <div class="modal-header">
153
+ <a class="close" data-dismiss="modal">×</a>
154
+ <h3><%= product.title %></h3>
155
+ </div>
156
+ <div class="modal-body" >
157
+ <% if !product.images.empty? %>
158
+ <%= image_tag product.images.first.large %>
159
+ <% end %>
160
+ </div>
161
+ </div>
162
+ <% end %>
163
+
164
+ <% end %>
165
+
166
+ </div> <!-- accordion -->
167
+ </div> <!-- span8 / right-column -->
168
+ </div>
@@ -0,0 +1,110 @@
1
+ <h1 class="green">Welcome</h1>
2
+
3
+ <p>
4
+ This is an example Shopify application that shows what you can do with the Shopify API.
5
+ </p>
6
+
7
+ <div class="info" style="clear: both">
8
+ This will send the <strong>API-Key</strong> and <strong>Secret</strong> to a shop, and make sure that you have the rights to
9
+ access its private admin data.<br/>
10
+ After authenticating, you will be redirected to the <code>show</code> action of your <code>SessionsController</code>, which stores the session, and then redirects you to your example dashboard.<br/>
11
+ Your <code>HomeController</code> will get your recent <code>Orders</code> and <code>Articles</code> through the
12
+ Shopify <%= link_to 'REST', 'http://www.xfront.com/REST-Web-Services.html', :title => "Get more information about REST web services in general" %> API and list them with all of your <code>Products</code>.
13
+ You can click on a link of one of your objects and will then be taken to the corresponding admin area of your shop.<br/>
14
+
15
+ <p><strong>Note:</strong> There are no examples for <em>creating or editing</em> objects, but you are also able to do that with the Shopify API!</p>
16
+ </div>
17
+
18
+ <h3>1. Make sure you've entered a valid <em>API-Key</em> and <em>Secret</em></h3>
19
+
20
+ <ul style="list-style-type: lower-alpha;">
21
+ <li>
22
+ <p>
23
+ If you haven't registered your application yet, then enter your shop's <strong>URL</strong> or <strong>subdomain</strong> here:<br/>
24
+ </p>
25
+
26
+ <div class="box grey" style="width: 500px;text-align: center">
27
+ <script type="text/javascript" charset="utf-8">
28
+ function getApiUrl() {
29
+ var name = $('shop').value;
30
+ if (name.indexOf('.') == -1) {
31
+ var api_url = name + '.myshopify.com';
32
+ } else {
33
+ var api_url = name.replace(/^https?:\/\//, ''); // Remove the "http://"
34
+ }
35
+ api_url = api_url.replace(/\/$/, ''); // Trim trailing slashes
36
+ $('api-form').action = 'http://' + api_url + '/admin/api_clients/new';
37
+ }
38
+ </script>
39
+
40
+ <% form_tag '', :method => 'get', :id => 'api-form', :onsubmit => "getApiUrl(); return true;", :style => 'margin-left: 16px;' do %>
41
+ <%= text_field_tag 'shop', '', :size => 40 %>
42
+ <%= hidden_field_tag 'api_client[return_url]', @callback_url %>
43
+ <%= submit_tag 'Get API key' %>
44
+ <% end %>
45
+ </div>
46
+
47
+ <p>
48
+ After registering your application with Shopify, you need to edit the <code>config/shopify.yml</code> file,
49
+ and insert your <em>API-Key</em> and <em>Secret</em> there. Then restart this application.
50
+ </p>
51
+ </li>
52
+ <li>
53
+ <p><strong>If you've already supplied those to the generator</strong>, then move on to <%= link_to 'Step #2', '#callback-step' %>.</p>
54
+ </li>
55
+ </ul>
56
+
57
+ <h3 id="callback-step">2. Make sure your <em>callback URL</em> is correct</h3>
58
+
59
+ The URL should be <code><%= @callback_url %></code>,
60
+ with the host portion of the URL pointing to whichever domain is currently hosting this application. <br/>
61
+ The callback URL of your app can be changed in the API screen of your Shopify admin interface.
62
+
63
+ <h3>3. <%= link_to 'Login', '/login' %> to your shop</h3>
64
+
65
+ <div class="border-wrap">
66
+ <div class="info">
67
+ This will send the <strong>API-Key</strong> and <strong>Secret</strong> to a shop, and make sure that you have the rights to
68
+ access its private admin data.<br/>
69
+ After authenticating, you will be redirected to the <code>show</code> action of your <code>SessionsController</code>, which stores the session, and then redirects you to your example dashboard.<br/>
70
+ Your <code>HomeController</code> will get your recent <code>Orders</code> and <code>Articles</code> through the
71
+ Shopify <%= link_to 'REST', 'http://www.xfront.com/REST-Web-Services.html', :title => "Get more information about REST web services in general" %> API and list them with all of your <code>Products</code>.
72
+ You can click on a link of one of your objects and will then be taken to the corresponding admin area of your shop.<br/>
73
+
74
+ <p><strong>Note:</strong> There are no examples for <em>creating or editing</em> objects, but you are also able to do that with the Shopify API!</p>
75
+ </div>
76
+ </div>
77
+
78
+ <h3>4. Check out the source code of the <code>home_controller</code> and its <code>index</code> template</h3>
79
+
80
+ <p class="description">
81
+ You can analyze those files to see how the ShopifyAPI is used and get a glimpse of what's possible.
82
+ </p>
83
+
84
+ <h3>5. Read additional documentation</h3>
85
+
86
+ <p class="description">
87
+ Become an expert.
88
+ </p>
89
+
90
+ <ul>
91
+ <li>
92
+ <%= link_to 'API documentation', 'http://www.shopify.com/developers/api' %>
93
+ <span class="hint">(An overview of what you can do with the Shopify API.)
94
+ </li>
95
+ <li>
96
+ <%= link_to 'Wiki (needs its own API section)', 'http://wiki.shopify.com/' %>
97
+ <span class="hint">(Get more information and share your knowledge.)
98
+ </li>
99
+ <li>
100
+ <%= link_to 'Forum (needs its own API section)', 'http://forums.shopify.com/community' %>
101
+ <span class="hint">(Ask questions and see what others already wanted to know.)
102
+ </li>
103
+ </ul>
104
+
105
+ <h3>6. Publish your application</h3>
106
+
107
+ <p class="description">
108
+ This feature is not implemented yet, but it in the future it will allow you to register your application,
109
+ so that will be shown in a public directory with a description, so that more users will take notice of it.
110
+ </p>
@@ -0,0 +1,79 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Shopify Demo App</title>
5
+ <%= stylesheet_link_tag 'application' %>
6
+ <%= javascript_include_tag 'application' %>
7
+ <%= csrf_meta_tags %>
8
+
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
+ <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
11
+
12
+ <!-- icons -->
13
+ <link rel="shortcut icon" href="../assets/favicon.png">
14
+ <link rel="apple-touch-icon" href="../assets/shopify-57.png">
15
+ <link rel="apple-touch-icon" sizes="72x72" href="../assets/shopify-72.png">
16
+ <link rel="apple-touch-icon" sizes="114x114" href="../assets/shopify-114.png">
17
+
18
+ <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
19
+ <!--[if lt IE 9]>
20
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
21
+ <![endif]-->
22
+ </head>
23
+
24
+ <body>
25
+
26
+ <div class="navbar navbar-fixed-top">
27
+ <div class="navbar-inner">
28
+ <div class="container">
29
+
30
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
31
+ <span class="icon-bar"></span>
32
+ <span class="icon-bar"></span>
33
+ <span class="icon-bar"></span>
34
+ </a>
35
+
36
+ <%= link_to 'Shopify Demo App', '/', :class => 'brand' %>
37
+
38
+ <% if shop_session %>
39
+ <div class="nav-collapse">
40
+ <ul class="nav">
41
+ <li class='<%= active_nav_class('home', 'index') %>'><%= link_to 'Where to Start', '/' %></li>
42
+ <li class='<%= active_nav_class('home', 'design') %>'><%= link_to 'Bootstrap Info', '/design' %></li>
43
+ </ul>
44
+ </div>
45
+
46
+ <ul class="nav pull-right">
47
+ <li class="dropdown">
48
+ <%= link_to raw(shop_session.url+' <b class="caret"></b>'), "https://#{shop_session.url}", :class => 'shop_name dropdown-toggle', :'data-toggle' => 'dropdown', :'data-target' => '#' %>
49
+ <ul class="dropdown-menu">
50
+ <li><%= link_to raw('<i class="icon-home"></i> Storefront'), "http://"+shop_session.url, :target => 'blank' %></li>
51
+ <li><%= link_to raw('<i class="icon-cog"></i> Shopify Admin'), "http://"+shop_session.url+"/admin", :target => 'blank' %></li>
52
+ <li class="divider"></li>
53
+ <li><%= link_to raw('<i class="icon-off"></i> Logout'), logout_path, :method => :delete %></li>
54
+ </ul>
55
+ </li>
56
+ </ul>
57
+ <% end %>
58
+
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+
64
+ <div class="container">
65
+ <% flash.each do |type, message| %>
66
+ <div class="alert"><%= message %></div>
67
+ <% end %>
68
+
69
+ <div class="content">
70
+ <%= yield %>
71
+ </div>
72
+
73
+ <footer>
74
+ <p>A Shopify app by (company name here)</p>
75
+ </footer>
76
+
77
+ </div> <!-- /container -->
78
+ </body>
79
+ </html>
@@ -0,0 +1,21 @@
1
+ <div class="page-header" id="login-header">
2
+ <h1>Install This App</h1>
3
+ <h1><small>This app requires you to login to start using it.</small></h1>
4
+ </div>
5
+
6
+ <div style="width:340px; margin:0 auto;">
7
+ <%= form_tag login_path, :class => 'form-search' do %>
8
+ <%= text_field_tag 'shop', nil, :placeholder => 'Shop URL', :class => 'btn-large' %>
9
+ <%= submit_tag 'Install', :class => 'btn btn-primary btn-large' %>
10
+ <% end %>
11
+ </div>
12
+
13
+ <p align="center" style="margin-top:30px">
14
+ <%= image_tag 'shopify.png' %>
15
+ </p>
16
+
17
+ <br/>
18
+
19
+ <p align="center" class="muted">
20
+ Don't have a shop? <a href="https://app.shopify.com/services/partners/api_clients/test_shops">Create a Test Shop</a>
21
+ </p>
@@ -0,0 +1,14 @@
1
+ Rails.application.config.middleware.use OmniAuth::Builder do
2
+ provider :shopify,
3
+ ShopifyApp.configuration.api_key,
4
+ ShopifyApp.configuration.secret,
5
+
6
+ # Example permission scopes - see http://docs.shopify.com/api/tutorials/oauth for full listing
7
+ :scope => 'read_orders, read_products',
8
+
9
+ :setup => lambda {|env|
10
+ params = Rack::Utils.parse_query(env['QUERY_STRING'])
11
+ site_url = "https://#{params['shop']}"
12
+ env['omniauth.strategy'].options[:client_options][:site] = site_url
13
+ }
14
+ end
@@ -0,0 +1,21 @@
1
+ # You should replace InMemorySessionStore with what you will be using
2
+ # in Production
3
+ #
4
+ # Interface to implement are self.retrieve(id) and self.store(ShopifyAPI::Session)
5
+ #
6
+ # Here is how you would add these functions to an ActiveRecord:
7
+ #
8
+ # class Shop < ActiveRecord::Base
9
+ # def self.store(session)
10
+ # shop = Shop.new(domain: session.url, token: session.token)
11
+ # shop.save!
12
+ # shop.id
13
+ # end
14
+ #
15
+ # def self.retrieve(id)
16
+ # shop = Shop.find(id)
17
+ # ShopifyAPI::Session.new(shop.domain, shop.token)
18
+ # end
19
+ # end
20
+
21
+ ShopifySessionRepository.storage = InMemorySessionStore
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>404 Error: This page doesn't exist!</title>
5
+
6
+ <style>
7
+ .container { text-align:center;}
8
+ .navbar .brand { float:none;}
9
+ </style>
10
+ </head>
11
+
12
+ <body>
13
+ <div class="navbar navbar-fixed-top">
14
+ <div class="navbar-inner">
15
+ <div class="container">
16
+ <a href="/" class="brand">Shopify Demo App</a>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
21
+ <div class="container">
22
+ <div class="content">
23
+ <div class="page-header">
24
+ <h1>AH! 404!</h1>
25
+ </div>
26
+
27
+ <h3><i class="icon-warning-sign" style="margin-top:6px; opacity:.5;"></i> Well dang, looks like this page doesn't exist.</h3>
28
+ <p class="muted">Well, not this one, but the one you were looking for... at least there's a kitten!</p>
29
+ <br/>
30
+ <p><img src="http://gifs.gifbin.com/122009/1259928856_surprised_kitten.gif" style="border-radius:10px;"/></p>
31
+ <br/>
32
+ <p><button type="button" value ="back" onClick="window.history.back();" class='btn btn-primary'><i class="icon-chevron-left" style="opacity:.25"></i> Back to the app</button></p>
33
+ </div>
34
+
35
+ <footer>
36
+ <p>A Shopify app by (company name here)</p>
37
+ </footer>
38
+ </div> <!-- /container -->
39
+ </body>
40
+ </html>