shopify_app 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/.gitignore +7 -0
  2. data/CHANGELOG +2 -0
  3. data/Gemfile +4 -0
  4. data/README.rdoc +58 -0
  5. data/Rakefile +2 -0
  6. data/install.rb +25 -0
  7. data/lib/generators/shopify_app/README +23 -0
  8. data/lib/generators/shopify_app/USAGE +22 -0
  9. data/lib/generators/shopify_app/shopify_app_generator.rb +50 -0
  10. data/lib/generators/shopify_app/templates/app/controllers/home_controller.rb +18 -0
  11. data/lib/generators/shopify_app/templates/app/controllers/login_controller.rb +50 -0
  12. data/lib/generators/shopify_app/templates/app/helpers/home_helper.rb +3 -0
  13. data/lib/generators/shopify_app/templates/app/helpers/login_helper.rb +3 -0
  14. data/lib/generators/shopify_app/templates/app/helpers/tabs_helper.rb +10 -0
  15. data/lib/generators/shopify_app/templates/app/views/home/design.html.erb +164 -0
  16. data/lib/generators/shopify_app/templates/app/views/home/index.html.erb +103 -0
  17. data/lib/generators/shopify_app/templates/app/views/home/welcome.html.erb +110 -0
  18. data/lib/generators/shopify_app/templates/app/views/layouts/application.html.erb +39 -0
  19. data/lib/generators/shopify_app/templates/app/views/login/index.html.erb +15 -0
  20. data/lib/generators/shopify_app/templates/public/images/box-bg2.gif +0 -0
  21. data/lib/generators/shopify_app/templates/public/images/info-bg.gif +0 -0
  22. data/lib/generators/shopify_app/templates/public/images/info.gif +0 -0
  23. data/lib/generators/shopify_app/templates/public/images/shopify-logo.png +0 -0
  24. data/lib/generators/shopify_app/templates/public/stylesheets/application.css +285 -0
  25. data/lib/shopify_app.rb +17 -0
  26. data/lib/shopify_app/configuration.rb +6 -0
  27. data/lib/shopify_app/login_protection.rb +21 -0
  28. data/lib/shopify_app/railtie.rb +17 -0
  29. data/lib/shopify_app/version.rb +3 -0
  30. data/shopify_app.gemspec +26 -0
  31. metadata +134 -0
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ .yardoc
7
+ doc/
@@ -0,0 +1,2 @@
1
+ * Require shopify_api gem
2
+ * Don't require shopify.yml when using environment variables [cody]
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in shopify_app.gemspec
4
+ gemspec
@@ -0,0 +1,58 @@
1
+ = Shopify application generator for Rails 3
2
+
3
+ == Description
4
+
5
+ This plugin makes it easy to get a Rails 3 app up and running with the
6
+ Shopify API.
7
+
8
+ The generator creates a basic login controller for authenticating with your
9
+ shop and a controller called "home" which displays basic information about
10
+ your products, orders and articles.
11
+
12
+ <i>Note: It's recommended to use this on a new Rails project, so that the
13
+ generator won't overwrite/delete some of your files.</i>
14
+
15
+ == Installation
16
+
17
+ # Add the gem shopify_app to your Gemfile
18
+ $ echo "gem 'shopify_app'" >> Gemfile
19
+ $ bundle install
20
+
21
+ == Usage
22
+
23
+ $ rails generate shopify_app your_app_api_key your_app_secret
24
+
25
+ If you don't have an API key yet, create a Shopify Partner account at
26
+ http://shopify.com/partners and create an app. You can also create test shops
27
+ once you're logged in as a partner.
28
+
29
+ When you create your app in the Shopify Partner Account, set the return URL to
30
+ <tt>http://localhost:3000/login/finalize</tt>
31
+
32
+ You can also create a private application that only works for your shop by
33
+ visiting https://YOUR-SHOP.myshopify.com/admin/api
34
+
35
+ === Example
36
+
37
+ $ rails generate shopify_app edffbb1bb793e2750686e6f4647a384a fed5bb18hde3e2750686e6f4647a781a
38
+
39
+ This will create a LoginController and a HomeController with their own views.
40
+
41
+ == After running the generator
42
+
43
+ First, start your application:
44
+
45
+ $ rails server
46
+
47
+ Now visit http://localhost:3000 and install your application in a Shopify store.
48
+
49
+ After your application has been given read or read/write API permission by the
50
+ shop, you're ready to start experimenting with the Shopify API.
51
+
52
+ == Questions or problems?
53
+
54
+ http://api.shopify.com <= Read up on the possible API calls!
55
+
56
+ http://forums.shopify.com/categories/9 <= Talk to new friends!
57
+
58
+ http://wiki.shopify.com/Shopify_App_Development <= Edit the docs!
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,25 @@
1
+ puts
2
+ puts "Shopify App Generator"
3
+ puts "---------------------"
4
+ puts
5
+ puts "To get started, first register your app as a Shopify Partner:"
6
+ puts
7
+ puts " * Go to http://www.shopify.com/partners and create or login to your Partner account."
8
+ puts
9
+ puts " * Jump over to the Apps tab and hit the 'Create a new app' button"
10
+ puts " (Make sure to set the Return URL to http://localhost:3000/login/finalize during development)"
11
+ puts
12
+ puts " * Install the Shopify API gem:
13
+
14
+ $ gem install shopify_api"
15
+ puts
16
+ puts " * Run
17
+
18
+ $ rails generate shopify_app your_app_api_key your_app_secret"
19
+ puts
20
+ puts " * Set up a test shop to install your app in (do this on the Partner site)"
21
+ puts
22
+ puts " * Run $ rails server"
23
+ puts
24
+ puts " * Visit http://localhost:3000 and use the test shop's URL to install this app"
25
+ puts
@@ -0,0 +1,23 @@
1
+
2
+
3
+ What's next?
4
+ ------------
5
+
6
+ Make sure to set the return URL of the application your Shopify partner account
7
+ to <tt>http://localhost:3000/login/finalize</tt>.
8
+
9
+ Then, start your application with:
10
+
11
+ $ rails server
12
+
13
+ Now visit http://localhost:3000 and install your application in a Shopify store.
14
+
15
+ After your application has been given read or read/write API permission by the
16
+ shop, you're ready to start experimenting with the Shopify API.
17
+
18
+ Questions or problems?
19
+ ----------------------
20
+
21
+ API Reference http://api.shopify.com
22
+ Developer Forums http://forums.shopify.com/categories/9
23
+ Developer Wiki http://wiki.shopify.com/Shopify_App_Development
@@ -0,0 +1,22 @@
1
+ Description:
2
+ This is a generator for creating a basic Shopify application to quickly get
3
+ you started. You can see some examples on how to use the Shopify API.
4
+
5
+ The generator creates a basic login controller for authenticating with your
6
+ Shop and a controller called "home" which displays basic information
7
+ about your products, orders and articles.
8
+
9
+ Note: It's recommended to use this on a new Rails project, so that the
10
+ generator won't overwrite/delete some of your files.
11
+
12
+ Usage:
13
+ Pass your API key and then your Secret, which the login controller
14
+ will need to authenticate with your shop.
15
+ If you don't have an API key yet, register your application in our
16
+ partner system at http://www.shopify.com/partners
17
+
18
+
19
+ Examples:
20
+ script/generate shopify_app edffbb1bb793e2750686e6f4647a384a abbcee050...
21
+
22
+ This will create a login controller and a home controller and views.
@@ -0,0 +1,50 @@
1
+ require 'rails/generators'
2
+
3
+ class ShopifyAppGenerator < Rails::Generators::Base
4
+ argument :api_key, :type => :string, :required => false
5
+ argument :secret, :type => :string, :required => false
6
+
7
+ class_option :skip_routes, :type => :boolean, :default => false, :desc => 'pass true to skip route generation'
8
+
9
+ def self.source_root
10
+ File.join(File.dirname(__FILE__), 'templates')
11
+ end
12
+
13
+ def copy_files
14
+ directory 'app'
15
+ directory 'public'
16
+ end
17
+
18
+ def remove_static_index
19
+ remove_file 'public/index.html'
20
+ end
21
+
22
+ def add_config_variables
23
+
24
+ api_key_str = api_key.nil? ? "ENV['SHOPIFY_API_KEY']" : api_key.inspect
25
+ api_secret_str = secret.nil? ? "ENV['SHOPIFY_API_SECRET']" : secret.inspect
26
+
27
+ inject_into_file 'config/application.rb', <<-DATA, :after => "class Application < Rails::Application\n"
28
+
29
+ # Shopify API connection credentials:
30
+ config.shopify.api_key = #{api_key_str}
31
+ config.shopify.secret = #{api_secret_str}
32
+ DATA
33
+ end
34
+
35
+ def add_routes
36
+ unless options[:skip_routes]
37
+ route "match 'login/logout' => 'login#logout'"
38
+ route "match 'login/finalize' => 'login#finalize'"
39
+ route "match 'login/authenticate' => 'login#authenticate'"
40
+ route "match 'login' => 'login#index'"
41
+ route "match 'design' => 'home#design'"
42
+ route "match 'welcome' => 'home#welcome'"
43
+ route "root :to => 'home#index'"
44
+ end
45
+ end
46
+
47
+ def display_readme
48
+ readme '../README'
49
+ end
50
+ end
@@ -0,0 +1,18 @@
1
+ class HomeController < ApplicationController
2
+
3
+ around_filter :shopify_session, :except => 'welcome'
4
+
5
+ def welcome
6
+ current_host = "#{request.host}#{':' + request.port.to_s if request.port != 80}"
7
+ @callback_url = "http://#{current_host}/login/finalize"
8
+ end
9
+
10
+ def index
11
+ # get 3 products
12
+ @products = ShopifyAPI::Product.find(:all, :params => {:limit => 3})
13
+
14
+ # get latest 3 orders
15
+ @orders = ShopifyAPI::Order.find(:all, :params => {:limit => 3, :order => "created_at DESC" })
16
+ end
17
+
18
+ end
@@ -0,0 +1,50 @@
1
+ class LoginController < ApplicationController
2
+ def index
3
+ # Ask user for their #{shop}.myshopify.com address
4
+
5
+ # If the #{shop}.myshopify.com address is already provided in the URL, just skip to #authenticate
6
+ if params[:shop].present?
7
+ redirect_to :controller => 'login', :action => "authenticate", :shop => params[:shop]
8
+ end
9
+ end
10
+
11
+ def authenticate
12
+ if params[:shop].present?
13
+ redirect_to ShopifyAPI::Session.new(params[:shop].to_s).create_permission_url
14
+ else
15
+ redirect_to return_address
16
+ end
17
+ end
18
+
19
+ # Shopify redirects the logged-in user back to this action along with
20
+ # the authorization token t.
21
+ #
22
+ # This token is later combined with the developer's shared secret to form
23
+ # the password used to call API methods.
24
+ def finalize
25
+ shopify_session = ShopifyAPI::Session.new(params[:shop], params[:t], params)
26
+ if shopify_session.valid?
27
+ session[:shopify] = shopify_session
28
+ flash[:notice] = "Logged in to shopify store."
29
+
30
+ redirect_to return_address
31
+ session[:return_to] = nil
32
+ else
33
+ flash[:error] = "Could not log in to Shopify store."
34
+ redirect_to :action => 'index'
35
+ end
36
+ end
37
+
38
+ def logout
39
+ session[:shopify] = nil
40
+ flash[:notice] = "Successfully logged out."
41
+
42
+ redirect_to :action => 'index'
43
+ end
44
+
45
+ protected
46
+
47
+ def return_address
48
+ session[:return_to] || root_url
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ module TabsHelper
2
+ # Create a tab as <li> and give it the id "current" if the current action matches that tab
3
+ def tab(name, url, options = {})
4
+ if controller.action_name =~ (options[:highlight] = /#{name}/i)
5
+ content_tag :li, link_to(options[:label] || name.to_s.capitalize, url, {:id => "current"})
6
+ else
7
+ content_tag :li, link_to(options[:label] || name.to_s.capitalize, url)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,164 @@
1
+ <h1 class="blue">Overview of the styles used</h1>
2
+
3
+ <div class="info">
4
+ <%= image_tag '/images/info.gif', :style => "float:left" %>
5
+ <p>You are free to use this demo application as a base to create new applications that use the Shopify API.</p>
6
+ </div>
7
+
8
+ <table id="style-table">
9
+ <tr>
10
+ <td style="width: 33%">
11
+ <pre><code>&lt;h1&gt;Lorem ipsum&lt;/h1&gt;</code></pre>
12
+ </td>
13
+
14
+ <td style="width: 66%">
15
+ <h1>Lorem ipsum</h1>
16
+ </td>
17
+ </tr>
18
+ <tr>
19
+ <td>
20
+ <pre><code>&lt;h2&gt;Lorem ipsum&lt;/h2&gt;</code></pre>
21
+ </td>
22
+
23
+ <td>
24
+ <h2>Lorem ipsum</h2>
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <td>
29
+ <pre><code>&lt;h3&gt;Lorem ipsum&lt;/h3&gt;</code></pre>
30
+ </td>
31
+
32
+ <td>
33
+ <h3>Lorem ipsum</h3>
34
+ </td>
35
+ </tr>
36
+ <tr>
37
+ <td>
38
+ <pre><code>&lt;h4&gt;Lorem ipsum&lt;/h4&gt;</code></pre>
39
+ </td>
40
+
41
+ <td>
42
+ <h4>Lorem ipsum</h4>
43
+ </td>
44
+ </tr>
45
+
46
+ <tr>
47
+ <td>
48
+ <pre><code>&lt;p&gt;&hellip;&lt;/p&gt;</code></pre>
49
+ </td>
50
+
51
+ <td>
52
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
53
+ </td>
54
+ </tr>
55
+
56
+ <tr>
57
+ <td>
58
+ <pre><code>&lt;p class="note"&gt;&hellip;&lt;/p&gt;</code></pre>
59
+ </td>
60
+
61
+ <td>
62
+ <p class="note">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
63
+ </td>
64
+ </tr>
65
+
66
+ <tr>
67
+ <td>
68
+ <pre><code>&lt;span class="highlight"&gt;&hellip;&lt;/span&gt;</code></pre>
69
+ </td>
70
+
71
+ <td>
72
+ <span class="highlight">Lorem ipsum dolor sit amet</p>
73
+ </td>
74
+ </tr>
75
+
76
+ <tr>
77
+ <td>
78
+ <pre><code>&lt;h3 class="blue"&gt;&hellip;&lt;/h3&gt;</code></pre>
79
+ </td>
80
+
81
+ <td>
82
+ <h3 class="blue">Lorem ipsum</h3>
83
+ </td>
84
+ </tr>
85
+ <tr>
86
+ <td>
87
+ <pre><code>&lt;h3 class="green"&gt;&hellip;&lt;/h3&gt;</code></pre>
88
+ </td>
89
+
90
+ <td>
91
+ <h3 class="green">Lorem ipsum</h3>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td>
96
+ <pre><code>&lt;h3 class="orange"&gt;&hellip;&lt;/h3&gt;</code></pre>
97
+ </td>
98
+
99
+ <td>
100
+ <h3 class="orange">Lorem ipsum</h3>
101
+ </td>
102
+ </tr>
103
+
104
+ <tr>
105
+ <td>
106
+ <pre><code>&lt;p class="blue"&gt;&hellip;&lt;/p&gt;</code></pre>
107
+ </td>
108
+
109
+ <td>
110
+ <p class="blue">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <td>
115
+ <pre><code>&lt;p class="green"&gt;&hellip;&lt;/p&gt;</code></pre>
116
+ </td>
117
+
118
+ <td>
119
+ <p class="green">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
120
+ </td>
121
+ </tr>
122
+ <tr>
123
+ <td>
124
+ <pre><code>&lt;p class="orange"&gt;&hellip;&lt;/p&gt;</code></pre>
125
+ </td>
126
+
127
+ <td>
128
+ <p class="orange">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
129
+ </td>
130
+ </tr>
131
+
132
+ <tr>
133
+ <td>
134
+ <pre><code>&lt;div class="box"&gt;<br />&nbsp;&nbsp;&lt;div class="wrapper"&gt;&hellip;&lt;/div&gt;<br />&lt;/div&gt;</code></pre>
135
+ </td>
136
+
137
+ <td>
138
+ <div class="box"><div class="wrapper">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></div>
139
+ </td>
140
+ </tr>
141
+
142
+ <tr>
143
+ <td>
144
+ <pre><code>&lt;p class="dark"&gt;&hellip;&lt;/p&gt;</code></pre>
145
+ </td>
146
+
147
+ <td>
148
+ <p class="dark">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
149
+ </td>
150
+ </tr>
151
+
152
+ <tr>
153
+ <td>
154
+ <pre><code>&lt;p class="light"&gt;&hellip;&lt;/p&gt;</code></pre>
155
+ </td>
156
+
157
+ <td>
158
+ <p class="light">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
159
+ </td>
160
+ </tr>
161
+
162
+
163
+
164
+ </table>
@@ -0,0 +1,103 @@
1
+ <div id="sidebar">
2
+ <h3>Where to start</h3>
3
+ <h4>Check out the <code style="font-size: 140%">home_controller</code></h4>
4
+
5
+ <p class="description">
6
+ The controller in this demo application fetches the latest 3 orders and products and makes them available as instance variables <code style="color: #218BCE">@orders</code> and <code style="color: #218BCE">@products</code>.
7
+ </p>
8
+
9
+ <h4>Check out the <code>index</code> template</h4>
10
+
11
+ <p class="description">
12
+ This is the Ruby template you are currently looking at. It is located at:<br />
13
+ </p>
14
+
15
+ <p style="background: #fff; margin-left: 4px"><code>views/home/index.html.erb</code></p>
16
+
17
+ <p class="description">
18
+ Have a look at the markup and Ruby code to see how the Shopify API is being used.
19
+ </p>
20
+
21
+ <h3>Additional documentation</h3>
22
+
23
+ <p class="description">
24
+ Become an expert:
25
+ </p>
26
+
27
+ <ul>
28
+ <li>
29
+ <%= link_to 'API documentation', 'http://www.shopify.com/developers/api/' %>
30
+ <span class="note">The reference: what you can do with the Shopify API.</span>
31
+ </li>
32
+ <li>
33
+ <%= link_to 'Wiki', 'http://wiki.shopify.com/' %>
34
+ <span class="note">Get more information and share your knowledge.</span>
35
+ </li>
36
+ <li>
37
+ <%= link_to 'Forum', 'http://forums.shopify.com/community' %>
38
+ <span class="note">Ask questions and see what others already wanted to know.</span>
39
+ </li>
40
+ </ul>
41
+
42
+ <h3>Once you're ready</h3>
43
+
44
+ <p class="description">
45
+ We'd love to see what you create using the Shopify API.
46
+ Find out how to share your application with the world and read the latest information on the <%= link_to 'API Publishing Page', 'http://www.shopify.com/developers/publishing/' %>.
47
+ </p>
48
+ </div>
49
+
50
+
51
+ <div id="orders">
52
+ <h2>Your recent orders</h2>
53
+
54
+ <% if @orders.blank? %>
55
+
56
+ <em class="note">There are no orders in your store.</em>
57
+
58
+ <% else %>
59
+
60
+ <ul>
61
+ <% @orders.each do |order| %>
62
+ <li>
63
+ <div class="order box">
64
+ <div class="wrapper">
65
+ <strong><%= link_to order.name, "http://#{current_shop.url}/admin/orders/#{order.id}" %></strong>
66
+ <span class="price"><%= order.total_price %> <%= order.currency %></span>
67
+ <span class="highlight"><%= order.financial_status %></span>
68
+ by <span class="note"><%= order.billing_address.name %></span>
69
+ </div>
70
+ </div>
71
+ </li>
72
+ <% end %>
73
+ </ul>
74
+
75
+ <% end %>
76
+ </div>
77
+
78
+
79
+ <h2>Some of your products</h2>
80
+
81
+ <% if @products.blank? %>
82
+
83
+ <em class="note">There are no products in your store.</em>
84
+
85
+ <% else %>
86
+
87
+ <% @products.each do |product| %>
88
+ <div class="product box">
89
+ <div class="wrapper">
90
+ <%= image_tag product.images.first.small rescue '' %>
91
+
92
+ <h4><%= link_to product.title, "http://#{current_shop.url}/admin/products/#{product.id}" %></h4>
93
+
94
+ <p class="price"><%= product.price_range %> <%= current_shop.shop.currency %></p>
95
+ <p style="margin-bottom: 0"><%= product.product_type %> <span class="note">type</span></p>
96
+ <p style="margin: 0"><%= product.vendor %> <span class="note">vendor</span></p>
97
+
98
+ <div style="clear:left"></div>
99
+ </div>
100
+ </div>
101
+ <% end %>
102
+
103
+ <% end %>
@@ -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>finalize</code> action of your <code>LoginController</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>finalize</code> action of your <code>LoginController</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,39 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Shopify Application</title>
5
+ <%= stylesheet_link_tag :all %>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= csrf_meta_tag %>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="header">
12
+ <h1><%= link_to 'Shopify Demo Application', '/' %></h1>
13
+
14
+ <p id="login-link">
15
+ <% if current_shop %>
16
+ <span class="note">current shop</span> <%= link_to current_shop.url, "http://#{current_shop.url}", :class => 'shop_name' %> <span class="note">|</span>
17
+ <%= link_to 'logout', :controller => "login", :action => 'logout' %>
18
+ <% end %>
19
+ </p>
20
+ </div>
21
+
22
+ <div id="container" class="clearfix">
23
+ <ul id="tabs">
24
+ <%= tab :index, {:controller => 'home'}, :label => 'Home' %>
25
+ <%= tab :design, {:controller => 'home', :action => 'design'}, :label => 'Design Help' %>
26
+ </ul>
27
+
28
+ <!-- Flash error & notice-->
29
+ <% if flash[:error] %> <div id="flasherrors"><%= flash[:error] %></div><% end %>
30
+ <% if flash[:notice] %><div id="flashnotices"><%= flash[:notice] %></div><% end %>
31
+
32
+ <!-- begin div.main-->
33
+ <div id="main">
34
+ <%= yield %>
35
+ </div>
36
+ <!-- end div.main -->
37
+ </div>
38
+ </body>
39
+ </html>
@@ -0,0 +1,15 @@
1
+ <h1>Install</h1>
2
+
3
+ <p>Install this app in a shop to get access to its private admin data.</p>
4
+
5
+ <p style="padding-bottom: 1em"><span class="hint">Don&rsquo;t have a shop to install your app in handy? <a href="https://app.shopify.com/services/partners/api_clients/test_shops">Create a test shop.</a></span></p>
6
+
7
+ <%= form_tag '/login/authenticate' do %>
8
+ <label for='shop'><strong>The URL of the Shop</strong>
9
+ <span class="hint">(or just the subdomain if it&rsquo;s at myshopify.com)</span>
10
+ </label>
11
+ <p>
12
+ <%= text_field_tag 'shop', nil, {:size => 45} %>
13
+ <%= submit_tag 'Install' %>
14
+ </p>
15
+ <% end %>
@@ -0,0 +1,285 @@
1
+ body {
2
+ margin: 0;
3
+ font: 0.8em/1.3em "Lucida Grande", Arial, Arial, sans-serif;
4
+ background: #ededed;
5
+ }
6
+
7
+ h1 { font-weight: normal; font-size: 24px; }
8
+ h1 a { color: #FFFAD5; text-decoration: none; }
9
+ h2 { font-weight: normal; margin-top: 24px; }
10
+ h3 { margin-top: 24px; }
11
+
12
+ #header {
13
+ background: #2d3337 url('../images/shopify-logo.png') 20px 50% no-repeat;
14
+ padding: 25px 25px 25px 70px;
15
+ border-top: 5px solid #1f2326;
16
+ border-bottom: 1px solid #252a2e;
17
+ }
18
+
19
+ #header h1 { color: #fffad5; }
20
+
21
+ #login-link {
22
+ float: right;
23
+ position: relative;
24
+ bottom: 43px;
25
+ right: 15px;
26
+ color: #ededed;
27
+ }
28
+
29
+ #login-link a { color: #ebff7c; }
30
+ #login-link a:hover { text-decoration: underline; }
31
+ #login-link a.shop_name { color: inherit; text-decoration: none; }
32
+ #login-link a.shop_name:hover { text-decoration: underline; }
33
+
34
+ #container {
35
+ width: 90%;
36
+ min-width: 800px;
37
+ margin: 40px auto;
38
+ background: #fff;
39
+ border-right: 1px solid #e5e5e5;
40
+ border-bottom: 1px solid #e5e5e5;
41
+ }
42
+
43
+ #container h1 { margin: 18px 0 27px 0; }
44
+
45
+ #main { padding: 18px; }
46
+
47
+ #tabs {
48
+ margin: 0;
49
+ padding: 0;
50
+ height: 20px;
51
+ position: absolute;
52
+ top: 123px;
53
+ }
54
+
55
+ #tabs li {
56
+ margin: 0;
57
+ padding: 0;
58
+ display: inline;
59
+ list-style-type: none;
60
+ }
61
+
62
+ #tabs a:link, #tabs a:visited {
63
+ float: left;
64
+ padding: 3px 8px ;
65
+ margin: 0 10px 4px 0px;
66
+ text-decoration: none;
67
+ color: #888;
68
+ background: #ddd;
69
+ }
70
+
71
+ #tabs a:link#current, #tabs a:visited#current, #tabs a:hover { color: #000 !important; }
72
+ #tabs a:link#current, #tabs a:visited#current { font-weight: bold; background: #fff; }
73
+
74
+ a { color: #22658b; }
75
+ a:hover { color: #359cd7; }
76
+
77
+ dl { margin: 10px 15px; }
78
+ dt { margin: 10px 0; }
79
+ dd { margin: 5px 0 15px 0; }
80
+ dl input { margin: 0 !important; }
81
+
82
+ code { font-size: 140%; }
83
+
84
+ /* UTILITY CLASSES */
85
+
86
+ .clearfix:after {
87
+ content: ".";
88
+ display: block;
89
+ height: 0;
90
+ clear: both;
91
+ visibility: hidden;
92
+ }
93
+
94
+ .clearfix {display: inline-table;}
95
+
96
+ /* Hides from IE-mac \*/
97
+ * html .clearfix {height: 1%;}
98
+ .clearfix {display: block;}
99
+ /* End hide from IE-mac */
100
+
101
+ .ta-left { text-align: left; }
102
+ .ta-right { text-align: right; }
103
+ .ta-center { text-align: center; }
104
+ .pl { padding-left: 10px !important; }
105
+ .note { color: #777; font-size: 85%; }
106
+ .highlight { background: #ffc; }
107
+
108
+ /*
109
+ * LOGIN / WELCOME
110
+ */
111
+
112
+ #left, #right {
113
+ width: 40%;
114
+ float: left;
115
+ margin: 0 2% 30px 2%;
116
+ }
117
+
118
+ #left { min-width: 390px; }
119
+
120
+ #logout { float: right; margin: 10px; }
121
+ #logout a { color: #330; }
122
+
123
+ /*
124
+ * DASHBOARD
125
+ */
126
+
127
+ .order, .product { width: 55%; }
128
+ .product { margin: 10px; }
129
+
130
+ .product img {
131
+ margin: 0 10px 0 0;
132
+ float: left;
133
+ }
134
+
135
+ .product h4 {
136
+ margin: 0 0 12px 0;
137
+ font-size: 14px;
138
+ }
139
+
140
+ .price {
141
+ color: #666;
142
+ font-size: 15px;
143
+ font-family: Times, "Times New Roman";
144
+ font-style: italic;
145
+ }
146
+
147
+ #orders ul {
148
+ list-style-type: none;
149
+ padding: 0 0 0 7px;
150
+ }
151
+
152
+ #orders li { padding: 3px; }
153
+
154
+ #sidebar {
155
+ float: right;
156
+ width: 280px;
157
+ background: #f5fbfe;
158
+ border-left: 1px solid #D7E4EA;
159
+ color: #003366;
160
+ padding: 0 20px 20px 20px;
161
+ margin-bottom: 18px;
162
+ }
163
+
164
+ #sidebar ul {
165
+ padding-left: 20px;
166
+ list-style-type: square;
167
+ }
168
+
169
+ #sidebar li { margin: 8px 0; }
170
+
171
+ /* STYLE OVERVIEW */
172
+
173
+ #style-table { margin: 20px 0; }
174
+ #style-table td * { margin: 0; }
175
+ #style-table td { padding: 10px; border-bottom: 1px dotted #e5e5e5; }
176
+ #style-table td:first-child {
177
+ background:#Fefefe url('../images/box-bg2.gif') repeat-x scroll left bottom;
178
+ }
179
+ /* Flash */
180
+
181
+ #flasherrors, #flashnotices {
182
+ background: #faf7ea;
183
+ border-bottom: 1px solid #e8e6d9;
184
+ padding: 10px;
185
+ font-weight: bold;
186
+ text-align:center;
187
+ }
188
+
189
+ #flasherrors { color: #6e290b; }
190
+ #flashnotices { color: #549d19; }
191
+
192
+ /* CLASSES */
193
+
194
+ .description {
195
+ margin: 0px 0px 0px 4px;
196
+ font-weight: normal;
197
+ }
198
+
199
+ .box {
200
+ padding: 0;
201
+ background:#FAFAFA url('../images/box-bg2.gif') repeat-x scroll left top;
202
+ border:1px solid #CCCCCC;
203
+ }
204
+
205
+ .wrapper {
206
+ border:1px solid #FFFFFF;
207
+ padding: 10px;
208
+ }
209
+
210
+ .info {
211
+ padding: 0;
212
+ margin: 8px auto;
213
+ background: #009ad6 url('../images/info-bg.gif') top left repeat-x;
214
+ border: 1px solid #61abda;
215
+ font: 1.2em/1.7em "Comic Sans MS";
216
+ color: #fff;
217
+ height: 85px;
218
+ }
219
+
220
+ .info code {
221
+ font-size: 14px;
222
+ background: none;
223
+ }
224
+
225
+ .info a { color: #fff; }
226
+ .info a:hover { color: #dcfaff; }
227
+
228
+ .grey {
229
+ background: #eee;
230
+ border: 1px solid #ccc;
231
+ }
232
+
233
+ .green, .orange, .blue { padding: 10px; }
234
+ h1.green, h2.green, h3.green, h1.orange, h2.orange, h3.orange, h1.blue, h2.blue, h3.blue { padding: 0; }
235
+
236
+ .green {
237
+ background: #61b41e;
238
+ border: 1px solid #60b31d;
239
+ color: #ddecd0;
240
+ }
241
+
242
+ h1.green, h2.green, h3.green {
243
+ color: #6ece21;
244
+ background: none;
245
+ border: none;
246
+ }
247
+
248
+ .orange {
249
+ background: #ce6e21;
250
+ border: 1px solid #bc641e;
251
+ color: #fce0ca;
252
+ padding: 10px;
253
+ }
254
+
255
+ h1.orange, h2.orange, h3.orange {
256
+ color: #ce6e21;
257
+ background: none;
258
+ border: none;
259
+ }
260
+
261
+ .blue {
262
+ background: #218bce;
263
+ border: 1px solid #1e80be;
264
+ color: #d9ecf8;
265
+ padding: 10px;
266
+ }
267
+
268
+ h1.blue, h2.blue, h3.blue {
269
+ color: #218bce;
270
+ background: none;
271
+ border: none;
272
+ }
273
+
274
+ .light {
275
+ background: #faf7ea;
276
+ border: 1px solid #e8e6d9;
277
+ padding: 18px;
278
+ }
279
+
280
+ .dark {
281
+ background: #333;
282
+ border: 1px solid #000;
283
+ color: #fff;
284
+ padding: 10px;
285
+ }
@@ -0,0 +1,17 @@
1
+ require 'shopify_api'
2
+
3
+ module ShopifyApp
4
+
5
+ def self.configuration
6
+ @configuration ||= ShopifyApp::Configuration.new
7
+ end
8
+
9
+ def self.setup_session
10
+ ShopifyAPI::Session.setup(:api_key => ShopifyApp.configuration.api_key, :secret => ShopifyApp.configuration.secret)
11
+ end
12
+ end
13
+
14
+ require 'shopify_app/login_protection'
15
+ require 'shopify_app/configuration'
16
+ require 'shopify_app/railtie'
17
+ require 'shopify_app/version'
@@ -0,0 +1,6 @@
1
+ class ShopifyApp::Configuration
2
+
3
+ attr_accessor :api_key
4
+
5
+ attr_accessor :secret
6
+ end
@@ -0,0 +1,21 @@
1
+ module ShopifyApp::LoginProtection
2
+
3
+ def shopify_session
4
+ if session[:shopify]
5
+ begin
6
+ # session[:shopify] set in LoginController#finalize
7
+ ShopifyAPI::Base.site = session[:shopify].site
8
+ yield
9
+ ensure
10
+ ShopifyAPI::Base.site = nil
11
+ end
12
+ else
13
+ session[:return_to] = request.fullpath
14
+ redirect_to :controller => 'login'
15
+ end
16
+ end
17
+
18
+ def current_shop
19
+ session[:shopify]
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails'
2
+
3
+ class ShopifyApp::Railtie < ::Rails::Railtie
4
+
5
+ config.before_configuration do
6
+ config.shopify = ShopifyApp.configuration
7
+ end
8
+
9
+ initializer "shopify_app.action_controller_integration" do
10
+ ActionController::Base.send :include, ShopifyApp::LoginProtection
11
+ ActionController::Base.send :helper_method, :current_shop
12
+ end
13
+
14
+ initializer "shopify_app.setup_session" do
15
+ ShopifyApp.setup_session
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module ShopifyApp
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "shopify_app/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "shopify_app"
7
+ s.version = ShopifyApp::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.author = "Shopify"
10
+ s.email = ["edward@shopify.com", "jonathan@shopify.com", "willem@shopify.com"]
11
+ s.homepage = "http://www.shopify.com/developers"
12
+ s.summary = %q{This gem is used to get quickly started with the Shopify API}
13
+ s.description = %q{Creates a basic login controller for authenticating with your Shop and also a product controller which lets your edit your products easily.}
14
+
15
+ s.rubyforge_project = "shopify-api"
16
+
17
+ s.add_runtime_dependency('rails', '~> 3')
18
+ s.add_runtime_dependency('shopify_api')
19
+
20
+ s.add_development_dependency('rake')
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shopify_app
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Shopify
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-26 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 3
30
+ version: "3"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: shopify_api
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ description: Creates a basic login controller for authenticating with your Shop and also a product controller which lets your edit your products easily.
60
+ email:
61
+ - edward@shopify.com
62
+ - jonathan@shopify.com
63
+ - willem@shopify.com
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files: []
69
+
70
+ files:
71
+ - .gitignore
72
+ - CHANGELOG
73
+ - Gemfile
74
+ - README.rdoc
75
+ - Rakefile
76
+ - install.rb
77
+ - lib/generators/shopify_app/README
78
+ - lib/generators/shopify_app/USAGE
79
+ - lib/generators/shopify_app/shopify_app_generator.rb
80
+ - lib/generators/shopify_app/templates/app/controllers/home_controller.rb
81
+ - lib/generators/shopify_app/templates/app/controllers/login_controller.rb
82
+ - lib/generators/shopify_app/templates/app/helpers/home_helper.rb
83
+ - lib/generators/shopify_app/templates/app/helpers/login_helper.rb
84
+ - lib/generators/shopify_app/templates/app/helpers/tabs_helper.rb
85
+ - lib/generators/shopify_app/templates/app/views/home/design.html.erb
86
+ - lib/generators/shopify_app/templates/app/views/home/index.html.erb
87
+ - lib/generators/shopify_app/templates/app/views/home/welcome.html.erb
88
+ - lib/generators/shopify_app/templates/app/views/layouts/application.html.erb
89
+ - lib/generators/shopify_app/templates/app/views/login/index.html.erb
90
+ - lib/generators/shopify_app/templates/public/images/box-bg2.gif
91
+ - lib/generators/shopify_app/templates/public/images/info-bg.gif
92
+ - lib/generators/shopify_app/templates/public/images/info.gif
93
+ - lib/generators/shopify_app/templates/public/images/shopify-logo.png
94
+ - lib/generators/shopify_app/templates/public/stylesheets/application.css
95
+ - lib/shopify_app.rb
96
+ - lib/shopify_app/configuration.rb
97
+ - lib/shopify_app/login_protection.rb
98
+ - lib/shopify_app/railtie.rb
99
+ - lib/shopify_app/version.rb
100
+ - shopify_app.gemspec
101
+ has_rdoc: true
102
+ homepage: http://www.shopify.com/developers
103
+ licenses: []
104
+
105
+ post_install_message:
106
+ rdoc_options: []
107
+
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project: shopify-api
129
+ rubygems_version: 1.3.7
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: This gem is used to get quickly started with the Shopify API
133
+ test_files: []
134
+