Permalink
Browse files

Big refactor to gem:

* Use Rails 3 Railtie to properly integrate it in your app. No more hassling with plugins.
* Use proper namespacing of the code.
* Use configuration variables instead of YAML config file.
  • Loading branch information...
1 parent 7167173 commit cb260b83d1956b9225509e5e5bda539679b7178e @wvanbergen wvanbergen committed Feb 26, 2011
View
@@ -0,0 +1,7 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
+.DS_Store
+.yardoc
+doc/
View
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in shopify_app.gemspec
+gemspec
View
@@ -0,0 +1,58 @@
+= Shopify application generator for Rails 3
+
+== Description
+
+This plugin makes it easy to get a Rails 3 app up and running with the
+Shopify API.
+
+The generator creates a basic login controller for authenticating with your
+shop and a controller called "home" which displays basic information about
+your products, orders and articles.
+
+<i>Note: It's recommended to use this on a new Rails project, so that the
+generator won't overwrite/delete some of your files.</i>
+
+== Installation
+
+ # Add the gem shopify_app to your Gemfile
+ $ echo "gem 'shopify_app'" >> Gemfile
+ $ bundle install
+
+== Usage
+
+ $ rails generate shopify_app your_app_api_key your_app_secret
+
+If you don't have an API key yet, create a Shopify Partner account at
+http://shopify.com/partners and create an app. You can also create test shops
+once you're logged in as a partner.
+
+When you create your app in the Shopify Partner Account, set the return URL to
+<tt>http://localhost:3000/login/finalize</tt>
+
+You can also create a private application that only works for your shop by
+visiting https://YOUR-SHOP.myshopify.com/admin/api
+
+=== Example
+
+ $ rails generate shopify_app edffbb1bb793e2750686e6f4647a384a fed5bb18hde3e2750686e6f4647a781a
+
+This will create a LoginController and a HomeController with their own views.
+
+== After running the generator
+
+First, start your application:
+
+ $ rails server
+
+Now visit http://localhost:3000 and install your application in a Shopify store.
+
+After your application has been given read or read/write API permission by the
+shop, you're ready to start experimenting with the Shopify API.
+
+== Questions or problems?
+
+http://api.shopify.com <= Read up on the possible API calls!
+
+http://forums.shopify.com/categories/9 <= Talk to new friends!
+
+http://wiki.shopify.com/Shopify_App_Development <= Edit the docs!
View
@@ -1,75 +0,0 @@
-h2. Shopify application generator for Rails 3
-
-h3. Description:
-
-This plugin makes it easy to get a Rails 3 app up and running with the
-Shopify API.
-
-The generator creates a basic login controller for authenticating with your
-shop and a controller called "home" which displays basic information about
-your products, orders and articles.
-
-bq. _Note:_ It's recommended to use this on a new Rails project, so that the
-generator won't overwrite/delete some of your files.
-
-h3. Installation:
-
-<pre>
-<code>
- # Add @gem shopify_api@ to your Gemfile
- $ echo "gem 'shopify_api'" >> Gemfile
-
- $ bundle install
-
- $ rails plugin install git://github.com/Shopify/shopify_app.git
-</code>
-</pre>
-
-h3. Usage:
-
-<pre>
-<code>
- $ rails generate shopify_app your_app_api_key your_app_secret
-</code>
-</pre>
-
-If you don't have an API key yet, create a Shopify Partner account at
-http://shopify.com/partners and create an app. You can also create test shops
-once you're logged in as a partner.
-
-You can also create a private application that only works for your shop by
-visiting "https://YOUR-SHOP.myshopify.com/admin/api":https://YOUR-SHOP.myshopify.com/admin/api
-
-h4. Example:
-
-<pre>
-<code>
- $ rails generate shopify_app edffbb1bb793e2750686e6f4647a384a fed5bb18hde3e2750686e6f4647a781a
-</code>
-</pre>
-
-This will create a LoginController and a HomeController with their own views.
-
-h3. After running the generator
-
-First, start your application:
-
-<pre>
-<code>
- $ rails server
-</code>
-</pre>
-
-Now visit "http://localhost:3000":http://localhost:3000 and install your
-application in a Shopify store.
-
-After your application has been given read or read/write API permission by the
-shop, you're ready to start experimenting with the Shopify API.
-
-h3. Questions or problems?
-
-"API Reference":http://api.shopify.com <= Read up on the possible calls!
-
-"Developer Forums":http://forums.shopify.com/categories/9 <= Talk to new friends!
-
-"Developer Wiki":http://wiki.shopify.com/Shopify_App_Development <= Edit the docs!
View
@@ -1,44 +1,2 @@
-require 'rubygems'
-
-require 'rake'
-require 'rake/rdoctask'
-require 'rake/gempackagetask'
-require 'ftools'
-
-VERSION = '0.0.1'
-
-puts 'Starting to build a new Gem...'
-spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = "shopify_app_generator"
- s.version = VERSION
- s.author = "Jaded Pixel"
- s.email = "dennis@gmail.com"
- s.homepage = "http://github.com/Shopify/api"
- s.summary = "This Gem is used to get quickly started with the Shopify API."
- s.rubyforge_project = "shopify-api"
- s.description = "Creates a basic login controller for authenticating with your Shop and also a product controller which lets your edit your products easily."
- s.files = FileList['*.rb', 'lib/*.rb', 'templates/*', 'templates/stylesheets/*', 'templates/layouts/*', 'templates/dashboard/*', 'templates/dashboard/views/*', 'templates/login/*', 'templates/login/views/*'].to_a
- # s.executables = ['shopify']
- # s.test_files = Dir.glob('tests/*.rb')
- s.has_rdoc = false
- # s.extra_rdoc_files = ["README"]
- s.add_dependency 'activesupport'
- s.add_dependency 'activeresource'
-end
-
-Rake::GemPackageTask.new(spec) do |pkg|
- pkg.need_tar = false
-end
-
-task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
- puts "Generated latest version of Shopify API Gem: #{VERSION}"
-end
-
-desc "Publish the API documentation"
-task :update_api => "../shopify/app/services/shopify_api.rb" do
- puts "Updating shopify_api.rb with newest..."
- # TODO do this as a failover to pulling down straight from git
- File.copy('../shopify/app/services/shopify_api.rb', 'lib/shopify_api.rb')
- print "Done\n"
-end
+require 'bundler'
+Bundler::GemHelper.install_tasks
View
@@ -1,27 +0,0 @@
-require 'shopify_login_protection'
-begin
- require 'shopify_api'
-rescue MissingSourceFile
- STDERR.puts "[Shopify App] ERROR - This plugin requires the shopify_api gem. Run `gem install shopify_api`."
- exit(1)
-end
-
-if ENV['SHOPIFY_API_KEY'] && ENV['SHOPIFY_API_SECRET']
- Rails.logger.info "[Shopify App] Loading API credentials from environment"
-
- ShopifyAPI::Session.setup(:api_key => ENV['SHOPIFY_API_KEY'], :secret => ENV['SHOPIFY_API_SECRET'])
-else
- config = File.join(Rails.root, "config/shopify.yml")
-
- if File.exist?(config)
- Rails.logger.info "[Shopify App] Loading API credentials from config/shopify.yml"
-
- credentials = YAML.load(File.read(config))[Rails.env]
- ShopifyAPI::Session.setup(credentials)
- else
- Rails.logger.warn '[Shopify App] Shopify App plugin installed but no config/shopify.yml found.'
- end
-end
-
-ActionController::Base.send :include, ShopifyLoginProtection
-ActionController::Base.send :helper_method, :current_shop
@@ -20,4 +20,3 @@ Examples:
script/generate shopify_app edffbb1bb793e2750686e6f4647a384a abbcee050...
This will create a login controller and a home controller and views.
-
@@ -1,8 +1,8 @@
require 'rails/generators'
class ShopifyAppGenerator < Rails::Generators::Base
- argument :api_key, :type => :string, :required => true
- argument :secret, :type => :string, :required => true
+ argument :api_key, :type => :string, :required => false
+ argument :secret, :type => :string, :required => false
class_option :skip_routes, :type => :boolean, :default => false, :desc => 'pass true to skip route generation'
@@ -12,10 +12,26 @@ def self.source_root
def copy_files
directory 'app'
- directory 'config'
directory 'public'
end
+ def remove_static_index
+ remove_file 'public/index.html'
+ end
+
+ def add_config_variables
+
+ api_key_str = api_key.nil? ? "ENV['SHOPIFY_API_KEY']" : api_key.inspect
+ api_secret_str = secret.nil? ? "ENV['SHOPIFY_API_SECRET']" : secret.inspect
+
+ inject_into_file 'config/application.rb', <<-DATA, :after => "class Application < Rails::Application\n"
+
+ # Shopify API connection credentials:
+ config.shopify.api_key = #{api_key_str}
@redronin
redronin Mar 12, 2011 Contributor

Why did we change from storing api keys in a shopify.yml file to writing it directly into the application.rb file?
When we wrote the keys to the shopify.yml you could just .gitignore this file and not commit it to your repo. Now you'll be committing your api creds to the source code.

The key file also handled having different keys for different environments (dev, staging, production).

@edward
edward Mar 12, 2011 Member

We deliberated about retaining shopify.yml but decided against it:

  1. Environment-specific configs in a Rails 3 app should go in config/environments, and if you don't have environment-specific configs by default, just stick it in application.rb

  2. Most shopify apps will never be public, so committing api keys isn't a big deal. If it is, keep them in environment vars or do whatever you need to.

Ideally, when you create an app, you should get multiple keys for production, development, and staging, but that's currently not straightforward with how the partners area is set up, nor is it intuitive for some developers, so that still needs to be thought out.

Reading this over, I do however think that we should up our major version number considering that this is an API-changing thing.

/me goes to release this gem as 1.0.0

@wvanbergen
wvanbergen Mar 12, 2011 Member

Also, the "best practice" on Heroku (which we point people to in the docs) is using ENV variables, so there is no clear cut best solution. That's why I think it's best to let the developer decide, and the config variable gives people the most flexibility (you could still use a shopify.yml file if you want to).
As a bonus, this cleans up the howto document nicely, because we could remove the sections about setting up the gitignore. Now, the documentation is only concerned with setting up a Shopify app instead of also a small .gitignore tutorial at the same time:)

@wvanbergen
wvanbergen Mar 12, 2011 Member

Edward: this plugin was never released before as gem, so a new major version was not necessary.

@redronin
redronin Mar 12, 2011 Contributor

Thanks guys,
For my situation I did this in application.rb:

SHOPIFY_KEYS = YAML.load(File.read(Rails.root.join('config/shopify.yml')))[Rails.env] rescue {}
config.shopify.api_key = SHOPIFY_KEYS['api_key'] || ENV['SHOPIFY_API_KEY']
config.shopify.secret = SHOPIFY_KEYS['secret'] || ENV['SHOPIFY_SECRET']    
@edward
edward Mar 12, 2011 Member

Willem: Yeah, but it was as good a time to go 1.0.0 as any. The software is production ready, so we might as well name it so.

The only reason you would want to upgrade your shopify_app plugin/gem dependency would be to keep the login protection controller magic going, but because the configuration stuff changed, you can't just drop it in - I'm calling this as another reason we need a new major version.

+ config.shopify.secret = #{api_secret_str}
+ DATA
+ end
+
def add_routes
unless options[:skip_routes]
route "match 'login/logout' => 'login#logout'"
@@ -9,7 +9,7 @@
<span class="hint">(or just the subdomain if it&rsquo;s at myshopify.com)</span>
</label>
<p>
- <%= text_field_tag 'shop', {}, {:size => 45} %>
+ <%= text_field_tag 'shop', nil, {:size => 45} %>
<%= submit_tag 'Install' %>
</p>
<% end %>
@@ -1,31 +0,0 @@
-# If you don't have an API key yet, register your application at:
-#
-# <YourShopURL>/admin/api (e.g. "http://shopname.myshopify.com/admin/api")
-#
-# Be sure to conceal these credentials if you make your application code public.
-# If you're using Git, put the following line in a file called .gitignore in your
-# repository root:
-#
-# config/shopify.yml
-#
-# If you're using SVN, you can run this command from the application root:
-#
-# svn propedit svn:ignore ./config/shopify.yml
-#
-# You can also load your API credentials from the environment variables
-# SHOPIFY_API_KEY and SHOPIFY_API_SECRET.
-#
-# If you are deploying to Heroku, you use config vars (http://docs.heroku.com/config-vars) for this purpose:
-#
-# heroku config:add SHOPIFY_API_KEY=<%= api_key %> SHOPIFY_API_SECRET=<%= secret %>
-development:
- api_key: <%= api_key %>
- secret: <%= secret %>
-
-test:
- api_key: <%= api_key %>
- secret: <%= secret %>
-
-production:
- api_key: <%= api_key %>
- secret: <%= secret %>
View
@@ -0,0 +1,17 @@
+require 'shopify_api'
+
+module ShopifyApp
+
+ def self.configuration
+ @configuration ||= ShopifyApp::Configuration.new
+ end
+
+ def self.setup_session
+ ShopifyAPI::Session.setup(:api_key => ShopifyApp.configuration.api_key, :secret => ShopifyApp.configuration.secret)
+ end
+end
+
+require 'shopify_app/login_protection'
+require 'shopify_app/configuration'
+require 'shopify_app/railtie'
+require 'shopify_app/version'
@@ -0,0 +1,6 @@
+class ShopifyApp::Configuration
+
+ attr_accessor :api_key
+
+ attr_accessor :secret
+end
@@ -1,4 +1,4 @@
-module ShopifyLoginProtection
+module ShopifyApp::LoginProtection
def shopify_session
if session[:shopify]
@@ -9,14 +9,13 @@ def shopify_session
ensure
ShopifyAPI::Base.site = nil
end
- else
+ else
session[:return_to] = request.fullpath
- redirect_to :controller => 'login'
+ redirect_to :controller => 'login'
end
end
def current_shop
session[:shopify]
end
-
end
@@ -0,0 +1,17 @@
+require 'rails'
+
+class ShopifyApp::Railtie < ::Rails::Railtie
+
+ config.before_configuration do
+ config.shopify = ShopifyApp.configuration
+ end
+
+ initializer "shopify_app.action_controller_integration" do
+ ActionController::Base.send :include, ShopifyApp::LoginProtection
+ ActionController::Base.send :helper_method, :current_shop
+ end
+
+ initializer "shopify_app.setup_session" do
+ ShopifyApp.setup_session
+ end
+end
@@ -0,0 +1,3 @@
+module ShopifyApp
+ VERSION = "0.1.0"
+end
Oops, something went wrong.

0 comments on commit cb260b8

Please sign in to comment.