prerender_rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9131d6f39c2dc688b5255b910007e5a434fe85a5
4
- data.tar.gz: fd614761588694380e2abbb6ec3c6a32c64d42f8
3
+ metadata.gz: 4e710c94d4517957a7198a878b74edb3d2ce599a
4
+ data.tar.gz: 3d61079a206b75b6ebf47d2acd64ed1774fa1b25
5
5
  SHA512:
6
- metadata.gz: cd0a338c2026fa5c6abd80bc97410619df877ff94b2dc44e283b6f7c6119959aebb9b8dd307deec5f42f9a88d019ca3977c74f748175071ae3a28c771b2a1d15
7
- data.tar.gz: 4fd993cf3da044b7a2fa60da6e09be5d83cd51cdcceeb855c3f47edf58564d41d0e7b7e63a6ce58f08c3baa9daca80b84ea53ecf536901e68cbef6370d163d37
6
+ metadata.gz: e2f1fd70277c97905a06b2e674ca4e882aea82700c8abdc65eb65e6b4f2a016392f1bb97482bcd8e7fc87269f26ef51ced69b8cdfb2e937abff8b85c209c9abe
7
+ data.tar.gz: d5f453676bf4373c2c6634713684ccd938ca1761cea76518ec29aff5b2f3a5ce5567fc8083befa2df2d6afe31dd8ba78c7f6191f1319df06246d548d415373b4
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/README.md CHANGED
@@ -1,46 +1,68 @@
1
- Prerender Rails
1
+ Prerender Rails [![Build Status](https://travis-ci.org/collectiveip/prerender_rails.png)](https://travis-ci.org/collectiveip/prerender_rails)
2
2
  ===========================
3
3
 
4
- This gem installs middleware that prerenders a javascript-rendered page and sends the HTML to a search engine crawler for SEO. It checks the agent string on the requesting browser for a crawler, and continues on to your normal routes if the requester is not a crawler.
4
+ Are you using backbone, angular, emberjs, etc, but you're unsure about the SEO implications?
5
5
 
6
- ## How it works
7
- * Check to make sure the request is from a crawler and we aren't requesting a resource (js, css, etc...)
8
- * Make a `GET` request to the [prerender service](https://github.com/collectiveip/prerender) for the page's prerendered HTML
9
- * Return that HTML to the crawler
10
-
11
- ## Installation
6
+ Use this gem to install rails middleware that prerenders a javascript-rendered page and returns the HTML to the search engine crawler for SEO.
12
7
 
13
8
  Add this line to your application's Gemfile:
14
9
 
15
10
  gem 'prerender_rails'
16
11
 
17
- And then execute:
12
+ And in `config/environment/production.rb`, add this line:
13
+
14
+ ```ruby
15
+ config.middleware.use Rack::Prerender
16
+ ```
18
17
 
19
- $ bundle
18
+ ## How it works
19
+ 1. Check to make sure we should show a prerendered page
20
+ 1. Check if the request is from a crawler (agent string)
21
+ 2. Check to make sure we aren't requesting a resource (js, css, etc...)
22
+ 3. (optional) Check to make sure the url is in the whitelist
23
+ 4. (optional) Check to make sure the url isn't in the blacklist
24
+ 2. Make a `GET` request to the [prerender service](https://github.com/collectiveip/prerender)(phantomjs server) for the page's prerendered HTML
25
+ 3. Return that HTML to the crawler
20
26
 
21
- Or install it yourself as:
27
+ ## Customization
22
28
 
23
- $ gem install prerender_rails
29
+ ### Whitelist
24
30
 
25
- ## Usage
31
+ Whitelist a single url path or multiple url paths. If a whitelist is supplied, only url's containing a whitelist path will be prerendered.
32
+ ```ruby
33
+ config.middleware.use Rack::Prerender, whitelist: '/search/tto'
34
+ ```
35
+ ```ruby
36
+ config.middleware.use Rack::Prerender, whitelist: ['/search', '/profile']
37
+ ```
26
38
 
27
- In `config/environment/production.rb`, add this line:
39
+ ### Blacklist
28
40
 
41
+ Blacklist a single url path or multiple url paths. If a blacklist is supplied, all url's will be prerendered except ones containing a blacklist path.
29
42
  ```ruby
30
- config.middleware.use Rack::Prerender
43
+ config.middleware.use Rack::Prerender, blacklist: '/search/tto'
31
44
  ```
45
+ ```ruby
46
+ config.middleware.use Rack::Prerender, blacklist: ['/search', '/profile']
47
+ ```
48
+
49
+ ### Using your own prerender service
50
+
51
+ If you've deployed the prerender service on your own, set the `PRERENDER_SERVICE_URL` environment variable so that this package points there instead. Otherwise, it will default to the service already deployed at `http://prerender.herokuapp.com`
32
52
 
33
- If you've deployed the prerender service on your own, set the `PRERENDER_URL` environment variable so that this gem points there instead. Otherwise, it will default to the service already deployed at `http://prerender.herokuapp.com`
53
+ $ export PRERENDER_SERVICE_URL=<new url>
34
54
 
35
- $ export PRERENDER_URL=<new url>
55
+ ## Testing
36
56
 
37
- ## Contributing
57
+ If you want to make sure your pages are rendering correctly:
38
58
 
39
- 1. Fork it
40
- 2. Create your feature branch (`git checkout -b my-new-feature`)
41
- 3. Commit your changes (`git commit -am 'Add some feature'`)
42
- 4. Push to the branch (`git push origin my-new-feature`)
43
- 5. Create new Pull Request
59
+ 1. Open the Developer Tools in Chrome (Cmd + Atl + J)
60
+ 2. Click the Settings gear in the bottom right corner.
61
+ 3. Click "Overrides" on the left side of the settings panel.
62
+ 4. Check the "User Agent" checkbox.
63
+ 6. Choose "Other..." from the User Agent dropdown.
64
+ 7. Type `googlebot` into the input box.
65
+ 8. Refresh the page (make sure to keep the developer tools open).
44
66
 
45
67
  ## License
46
68
 
data/Rakefile CHANGED
@@ -1 +1,12 @@
1
+ #!/usr/bin/env rake
1
2
  require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib/prerender_rails'
8
+ t.test_files = FileList['test/lib/prerender_rails.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -1,10 +1,30 @@
1
- require "rack/version"
2
-
3
1
  module Rack
4
2
  class Prerender
5
3
  require 'net/http'
6
4
 
7
- def initialize(app)
5
+ def initialize(app, options={})
6
+ @crawler_user_agents = [
7
+ 'googlebot',
8
+ 'yahoo',
9
+ 'bingbot',
10
+ 'baiduspider'
11
+ ]
12
+
13
+ @extensions_to_ignore = [
14
+ '.js',
15
+ '.css',
16
+ '.less',
17
+ '.png',
18
+ '.jpg',
19
+ '.jpeg',
20
+ '.gif',
21
+ '.pdf',
22
+ '.doc'
23
+ ]
24
+
25
+ @options = options
26
+ @options[:whitelist] = [@options[:whitelist]] if @options[:whitelist].is_a? String
27
+ @options[:blacklist] = [@options[:blacklist]] if @options[:blacklist].is_a? String
8
28
  @app = app
9
29
  end
10
30
 
@@ -23,36 +43,53 @@ module Rack
23
43
  end
24
44
 
25
45
  def should_show_prerendered_page(env)
46
+ user_agent = env['HTTP_USER_AGENT']
47
+ return false if !user_agent
48
+
26
49
  request = Rack::Request.new(env)
27
- user_agent = env['HTTP_USER_AGENT'].downcase
28
50
 
29
- should_show_based_on_agent_string = user_agent == 'googlebot' ||
30
- user_agent == 'yahoo' ||
31
- user_agent == 'bingbot' ||
32
- user_agent == 'baiduspider'
51
+ #if it is not a bot...dont prerender
52
+ return false if !@crawler_user_agents.include?(user_agent.downcase)
53
+
54
+ #if it is a bot and is requesting a resource...dont prerender
55
+ return false if @extensions_to_ignore.any? { |extension| request.path.include? extension }
56
+
57
+ #if it is a bot and not requesting a resource and is not whitelisted...dont prerender
58
+ return false if @options[:whitelist].is_a?(Array) && @options[:whitelist].all? { |whitelisted| !request.path.include? whitelisted }
33
59
 
34
- return false if !should_show_based_on_agent_string #short circuit
60
+ #if it is a bot and not requesting a resource and is not blacklisted(url or referer)...dont prerender
61
+ if @options[:blacklist].is_a?(Array) && @options[:blacklist].any? { |blacklisted|
62
+ blacklistedUrl = false
63
+ blacklistedReferer = false
35
64
 
36
- should_show_based_on_extension = !request.path.include?('.js') &&
37
- !request.path.include?('.css') &&
38
- !request.path.include?('.less') &&
39
- !request.path.include?('.png') &&
40
- !request.path.include?('.jpg') &&
41
- !request.path.include?('.jpeg') &&
42
- !request.path.include?('.gif')
65
+ blacklistedUrl = request.path.include? blacklisted
66
+ blacklistedReferer = request.referer.include? blacklisted if request.referer
43
67
 
44
- should_show_based_on_agent_string && should_show_based_on_extension
68
+ blacklistedUrl || blacklistedReferer
69
+ }
70
+ return false
71
+ end
72
+
73
+ return true
45
74
  end
46
75
 
47
76
  def get_prerendered_page_response(env)
48
77
  begin
49
- url = Rack::Request.new(env).url
50
- prerender_url = ENV['PRERENDER_URL'] || 'http://prerender.herokuapp.com/'
51
- forward_slash = prerender_url[-1, 1] == '/' ? '' : '/'
52
- Net::HTTP.get_response(URI.parse("#{prerender_url}#{forward_slash}#{url}"))
78
+ Net::HTTP.get_response(URI.parse(build_api_url(env)))
53
79
  rescue
54
80
  nil
55
81
  end
56
82
  end
83
+
84
+ def build_api_url(env)
85
+ url = Rack::Request.new(env).url
86
+ prerender_url = get_prerender_service_url()
87
+ forward_slash = prerender_url[-1, 1] == '/' ? '' : '/'
88
+ "#{prerender_url}#{forward_slash}#{url}"
89
+ end
90
+
91
+ def get_prerender_service_url
92
+ ENV['PRERENDER_SERVICE_URL'] || 'http://prerender.herokuapp.com/'
93
+ end
57
94
  end
58
95
  end
@@ -1,13 +1,10 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rack/version'
5
2
 
6
3
  Gem::Specification.new do |spec|
7
4
  spec.name = "prerender_rails"
8
- spec.version = PrerenderRails::VERSION
5
+ spec.version = "0.0.3"
9
6
  spec.authors = ["Todd Hooper"]
10
- spec.email = ["thoop3@gmail.com"]
7
+ spec.email = ["todd@collectiveip.com"]
11
8
  spec.description = %q{Rails middleware to prerender your javascript heavy pages on the fly by a phantomjs service}
12
9
  spec.summary = %q{Prerender your backbone/angular/javascript rendered application on the fly when search engines crawl}
13
10
  spec.homepage = "https://github.com/collectiveip/prerender_rails"
@@ -18,6 +15,9 @@ Gem::Specification.new do |spec|
18
15
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
16
  spec.require_paths = ["lib"]
20
17
 
18
+ spec.add_dependency 'rack', '>= 0'
19
+
21
20
  spec.add_development_dependency "bundler", "~> 1.3"
22
21
  spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "webmock"
23
23
  end
@@ -0,0 +1,97 @@
1
+ require_relative '../test_helper'
2
+
3
+ describe Rack::Prerender do
4
+
5
+ bot = 'googlebot'
6
+ user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36'
7
+
8
+ before :each do
9
+ @app = lambda do |params|
10
+ [200, {}, ""]
11
+ end
12
+
13
+ @prerender = Rack::Prerender.new(@app)
14
+ end
15
+
16
+ it "should return a prerendered reponse for a crawler" do
17
+ request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
18
+ stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
19
+ response = Rack::Prerender.new(@app).call(request)
20
+
21
+ assert_equal response[2].body, ["<html></html>"]
22
+ end
23
+
24
+ it "should continue to app routes if user is not a bot by checking agent string" do
25
+ request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => user
26
+ response = Rack::Prerender.new(@app).call(request)
27
+
28
+ assert_equal response[2], ""
29
+ end
30
+
31
+ it "should continue to app routes if user is a bot, but the bot is requesting a resource file" do
32
+ request = Rack::MockRequest.env_for "/main.js?anyQueryParam=true", "HTTP_USER_AGENT" => bot
33
+ response = Rack::Prerender.new(@app).call(request)
34
+
35
+ assert_equal response[2], ""
36
+ end
37
+
38
+ it "should continue to app routes if the url is not part of the whitelist" do
39
+ request = Rack::MockRequest.env_for "/profile/blah", "HTTP_USER_AGENT" => bot
40
+ response = Rack::Prerender.new(@app, whitelist: ['/search', '/help']).call(request)
41
+
42
+ assert_equal response[2], ""
43
+ end
44
+
45
+ it "should return a prerendered response if the url is part of the whitelist" do
46
+ request = Rack::MockRequest.env_for "/search/things?query=blah", "HTTP_USER_AGENT" => bot
47
+ stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
48
+ response = Rack::Prerender.new(@app, whitelist: ['/search', '/help']).call(request)
49
+
50
+ assert_equal response[2].body, ["<html></html>"]
51
+ end
52
+
53
+ it "should continue to app routes if the url is part of the blacklist" do
54
+ request = Rack::MockRequest.env_for "/search/things?query=blah", "HTTP_USER_AGENT" => bot
55
+ response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
56
+
57
+ assert_equal response[2], ""
58
+ end
59
+
60
+ it "should return a prerendered response if the url is not part of the blacklist" do
61
+ request = Rack::MockRequest.env_for "/profile/blah", "HTTP_USER_AGENT" => bot
62
+ stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
63
+ response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
64
+
65
+ assert_equal response[2].body, ["<html></html>"]
66
+ end
67
+
68
+ it "should continue to app routes if the referer is part of the blacklist" do
69
+ request = Rack::MockRequest.env_for "/api/results", "HTTP_USER_AGENT" => bot, "HTTP_REFERER" => '/search'
70
+ response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
71
+
72
+ assert_equal response[2], ""
73
+ end
74
+
75
+ it "should return a prerendered response if the referer is not part of the blacklist" do
76
+ request = Rack::MockRequest.env_for "/api/results", "HTTP_USER_AGENT" => bot, "HTTP_REFERER" => '/search'
77
+ stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
78
+ response = Rack::Prerender.new(@app, blacklist: ['/profile', '/help']).call(request)
79
+
80
+ assert_equal response[2].body, ["<html></html>"]
81
+ end
82
+
83
+ describe '#buildApiUrl' do
84
+ it "should build the correct api url with the default url" do
85
+ request = Rack::MockRequest.env_for "https://google.com/search?q=javascript"
86
+ assert_equal @prerender.build_api_url(request), 'http://prerender.herokuapp.com/https://google.com/search?q=javascript'
87
+ end
88
+
89
+ it "should build the correct api url with an environment variable url" do
90
+ ENV['PRERENDER_SERVICE_URL'] = 'http://prerenderurl.com'
91
+ request = Rack::MockRequest.env_for "https://google.com/search?q=javascript"
92
+ assert_equal @prerender.build_api_url(request), 'http://prerenderurl.com/https://google.com/search?q=javascript'
93
+ ENV['PRERENDER_SERVICE_URL'] = nil
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'webmock/minitest'
3
+ require 'rack'
4
+ require File.expand_path('../../lib/prerender_rails.rb', __FILE__)
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prerender_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Hooper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-27 00:00:00.000000000 Z
11
+ date: 2013-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,22 +52,38 @@ dependencies:
38
52
  - - '>='
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  description: Rails middleware to prerender your javascript heavy pages on the fly
42
70
  by a phantomjs service
43
71
  email:
44
- - thoop3@gmail.com
72
+ - todd@collectiveip.com
45
73
  executables: []
46
74
  extensions: []
47
75
  extra_rdoc_files: []
48
76
  files:
49
77
  - .gitignore
78
+ - .travis.yml
50
79
  - Gemfile
51
80
  - LICENSE.txt
52
81
  - README.md
53
82
  - Rakefile
54
83
  - lib/prerender_rails.rb
55
- - lib/rack/version.rb
56
84
  - prerender_rails.gemspec
85
+ - test/lib/prerender_rails.rb
86
+ - test/test_helper.rb
57
87
  homepage: https://github.com/collectiveip/prerender_rails
58
88
  licenses:
59
89
  - MIT
@@ -79,4 +109,6 @@ signing_key:
79
109
  specification_version: 4
80
110
  summary: Prerender your backbone/angular/javascript rendered application on the fly
81
111
  when search engines crawl
82
- test_files: []
112
+ test_files:
113
+ - test/lib/prerender_rails.rb
114
+ - test/test_helper.rb
data/lib/rack/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module PrerenderRails
2
- VERSION = "0.0.2"
3
- end