render_static 0.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.
- data/Gemfile +12 -0
- data/Gemfile.lock +64 -0
- data/LICENSE.txt +22 -0
- data/README.txt +48 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/lib/render_static.rb +1 -0
- data/lib/render_static/middleware.rb +49 -0
- data/lib/render_static/rails/railtie.rb +9 -0
- data/lib/render_static/renderer.rb +16 -0
- data/render_static.gemspec +70 -0
- data/spec/middleware_spec.rb +69 -0
- data/spec/renderer_spec.rb +27 -0
- metadata +144 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.2.13)
|
5
|
+
i18n (= 0.6.1)
|
6
|
+
multi_json (~> 1.0)
|
7
|
+
addressable (2.3.3)
|
8
|
+
bourne (1.4.0)
|
9
|
+
mocha (~> 0.13.2)
|
10
|
+
childprocess (0.3.5)
|
11
|
+
ffi (~> 1.0, >= 1.0.6)
|
12
|
+
diff-lcs (1.1.3)
|
13
|
+
ffi (1.1.5)
|
14
|
+
git (1.2.5)
|
15
|
+
headless (1.0.1)
|
16
|
+
i18n (0.6.1)
|
17
|
+
jeweler (1.8.4)
|
18
|
+
bundler (~> 1.0)
|
19
|
+
git (>= 1.2.5)
|
20
|
+
rake
|
21
|
+
rdoc
|
22
|
+
json (1.7.7)
|
23
|
+
libwebsocket (0.1.5)
|
24
|
+
addressable
|
25
|
+
metaclass (0.0.1)
|
26
|
+
mocha (0.13.3)
|
27
|
+
metaclass (~> 0.0.1)
|
28
|
+
multi_json (1.7.2)
|
29
|
+
rake (10.0.4)
|
30
|
+
rdoc (3.12.2)
|
31
|
+
json (~> 1.4)
|
32
|
+
rspec (2.12.0)
|
33
|
+
rspec-core (~> 2.12.0)
|
34
|
+
rspec-expectations (~> 2.12.0)
|
35
|
+
rspec-mocks (~> 2.12.0)
|
36
|
+
rspec-core (2.12.2)
|
37
|
+
rspec-expectations (2.12.1)
|
38
|
+
diff-lcs (~> 1.1.3)
|
39
|
+
rspec-mocks (2.12.1)
|
40
|
+
rubyzip (0.9.9)
|
41
|
+
selenium-webdriver (2.25.0)
|
42
|
+
childprocess (>= 0.2.5)
|
43
|
+
libwebsocket (~> 0.1.3)
|
44
|
+
multi_json (~> 1.0)
|
45
|
+
rubyzip
|
46
|
+
shoulda (3.4.0)
|
47
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
48
|
+
shoulda-matchers (~> 1.0, >= 1.4.1)
|
49
|
+
shoulda-context (1.1.1)
|
50
|
+
shoulda-matchers (1.5.6)
|
51
|
+
activesupport (>= 3.0.0)
|
52
|
+
bourne (~> 1.3)
|
53
|
+
|
54
|
+
PLATFORMS
|
55
|
+
ruby
|
56
|
+
|
57
|
+
DEPENDENCIES
|
58
|
+
bundler
|
59
|
+
headless
|
60
|
+
jeweler (~> 1.8.4)
|
61
|
+
rdoc (~> 3.12)
|
62
|
+
rspec
|
63
|
+
selenium-webdriver
|
64
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Herval Freire
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.txt
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= render_static
|
2
|
+
|
3
|
+
* http://github.com/herval/render_static
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
render_static allows you to make your single-page apps (Backbone, Angular, etc) built on Rails SEO-friendly. It works by injecting a small rack middleware that will render pages as plain html, when the requester has one of the following user-agent headers:
|
8
|
+
|
9
|
+
Googlebot
|
10
|
+
Googlebot-Mobile
|
11
|
+
AdsBot-Google
|
12
|
+
Mozilla/5.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)
|
13
|
+
Baiduspider
|
14
|
+
Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
|
15
|
+
|
16
|
+
Please note that, in order for this to work, you need more than one thread/process of your webserver running, as the middleware will effectively make a second call back to your own app and render the content, streaming it back to the requester (crawler/bot).
|
17
|
+
|
18
|
+
|
19
|
+
== TO DO/PROBLEMS:
|
20
|
+
|
21
|
+
* Caching support
|
22
|
+
* Support for other drivers
|
23
|
+
* Log what's going on
|
24
|
+
|
25
|
+
== INSTALL:
|
26
|
+
|
27
|
+
Add the following to your Gemfile:
|
28
|
+
|
29
|
+
gem 'render_static'
|
30
|
+
|
31
|
+
In order to serve a set of routes as a single-page app, your routes.rb usually contains a catch-all route that will direct /* or /something/* to the same index.html file (the root of your js app). In order to allow the render_static middleware to intercept the right routes, you need to add this to your app initialization:
|
32
|
+
|
33
|
+
render_static.rb
|
34
|
+
RenderStatic::Middleware.base_path = "/" # replace / for whichever path matches your app's index.html
|
35
|
+
|
36
|
+
render_static will, by default, try to use Firefox as the driver to navigate to content. It will also try to run headlessly - if on a *nix box, you should install xvfb for that to work properly.
|
37
|
+
|
38
|
+
And you're done! The middleware will only try to static-render requests made by bots AND that would render application/html content.
|
39
|
+
|
40
|
+
You can test that everything is working as expected by CURLing:
|
41
|
+
|
42
|
+
# this will render the usual blank slate client-side apps serve
|
43
|
+
curl http://localhost:3000/some/backbone/route
|
44
|
+
|
45
|
+
# this will render a static representation of your page (just like it would look like in a browser)
|
46
|
+
curl -A "Googlebot" http://localhost:3000/some/backbone/route
|
47
|
+
|
48
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "render_static"
|
18
|
+
gem.homepage = "http://github.com/herval/render_static"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{ render_static allows you to make your single-page apps (Backbone, Angular, etc) built on Rails SEO-friendly. }
|
21
|
+
gem.description = %Q{ render_static allows you to make your single-page apps (Backbone, Angular, etc) built on Rails SEO-friendly. It works by injecting a small rack middleware that will render pages as plain html, when the requester is one of the most common crawlers/bots out there (Google, Yahoo Baidu and Bing) }
|
22
|
+
gem.email = "hervalfreire@gmail.com"
|
23
|
+
gem.authors = ["herval"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
|
30
|
+
RSpec::Core::RakeTask.new(:spec)
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
|
35
|
+
require 'rdoc/task'
|
36
|
+
Rake::RDocTask.new do |rdoc|
|
37
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
38
|
+
|
39
|
+
rdoc.rdoc_dir = 'rdoc'
|
40
|
+
rdoc.title = "render_static #{version}"
|
41
|
+
rdoc.rdoc_files.include('README*')
|
42
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
43
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'render_static/middleware'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'render_static/rails/railtie' if defined?(Rails)
|
2
|
+
require 'render_static/renderer'
|
3
|
+
|
4
|
+
module RenderStatic
|
5
|
+
class NotSeoFriendly < Exception
|
6
|
+
end
|
7
|
+
|
8
|
+
class Middleware
|
9
|
+
class << self
|
10
|
+
attr_accessor :base_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(app)
|
14
|
+
@app = app
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
if will_render?(env)
|
19
|
+
RenderStatic::Renderer.render(env)
|
20
|
+
else
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def will_render?(env)
|
28
|
+
is_bot?(env) && is_renderable?(env)
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_bot?(env)
|
32
|
+
[
|
33
|
+
"Googlebot",
|
34
|
+
"Googlebot-Mobile",
|
35
|
+
"AdsBot-Google",
|
36
|
+
"Mozilla/5.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)",
|
37
|
+
"Baiduspider",
|
38
|
+
"Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)",
|
39
|
+
].include?(env["HTTP_USER_AGENT"])
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_renderable?(env)
|
43
|
+
path = env["PATH_INFO"]
|
44
|
+
content_type = path.index(".") && path.split(".").last
|
45
|
+
|
46
|
+
path.start_with?(self.class.base_path) & [nil, "htm", "html"].include?(content_type) && env["REQUEST_METHOD"] == "GET"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'selenium-webdriver'
|
2
|
+
require 'headless'
|
3
|
+
|
4
|
+
module RenderStatic
|
5
|
+
class Renderer
|
6
|
+
|
7
|
+
def self.render(env)
|
8
|
+
Headless.ly do
|
9
|
+
browser = Selenium::WebDriver.for(:firefox)
|
10
|
+
path = "#{env["rack.url_scheme"]}://#{env["HTTP_HOST"]}#{env["REQUEST_PATH"]}"
|
11
|
+
browser.navigate.to(path)
|
12
|
+
[200, { "Content-Type" => "text/html" }, [browser.page_source]] # TODO status code not supported by selenium
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "render_static"
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["herval"]
|
12
|
+
s.date = "2013-05-08"
|
13
|
+
s.description = " render_static allows you to make your single-page apps (Backbone, Angular, etc) built on Rails SEO-friendly. It works by injecting a small rack middleware that will render pages as plain html, when the requester is one of the most common crawlers/bots out there (Google, Yahoo Baidu and Bing) "
|
14
|
+
s.email = "hervalfreire@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.txt"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.txt",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/render_static.rb",
|
27
|
+
"lib/render_static/middleware.rb",
|
28
|
+
"lib/render_static/rails/railtie.rb",
|
29
|
+
"lib/render_static/renderer.rb",
|
30
|
+
"render_static.gemspec",
|
31
|
+
"spec/middleware_spec.rb",
|
32
|
+
"spec/renderer_spec.rb"
|
33
|
+
]
|
34
|
+
s.homepage = "http://github.com/herval/render_static"
|
35
|
+
s.licenses = ["MIT"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = "1.8.15"
|
38
|
+
s.summary = "render_static allows you to make your single-page apps (Backbone, Angular, etc) built on Rails SEO-friendly."
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
|
+
s.add_runtime_dependency(%q<selenium-webdriver>, [">= 0"])
|
45
|
+
s.add_runtime_dependency(%q<headless>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
49
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<selenium-webdriver>, [">= 0"])
|
53
|
+
s.add_dependency(%q<headless>, [">= 0"])
|
54
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
55
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
56
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
57
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
58
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
59
|
+
end
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<selenium-webdriver>, [">= 0"])
|
62
|
+
s.add_dependency(%q<headless>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
64
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
65
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
66
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "render_static/middleware"
|
2
|
+
|
3
|
+
describe RenderStatic::Middleware do
|
4
|
+
let(:app) { stub }
|
5
|
+
let(:middleware) { RenderStatic::Middleware.new(app) }
|
6
|
+
let(:request) {
|
7
|
+
{
|
8
|
+
"PATH_INFO" => "/somewhere/",
|
9
|
+
"REQUEST_METHOD" => "GET"
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
before do
|
14
|
+
RenderStatic::Middleware.base_path = "/somewhere/"
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "a non-bot user agent" do
|
18
|
+
it "passes-through" do
|
19
|
+
env = request.merge("HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31")
|
20
|
+
|
21
|
+
app.should_receive(:call).with(env)
|
22
|
+
RenderStatic::Renderer.should_not_receive(:render)
|
23
|
+
|
24
|
+
middleware.call(env)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "a bot user agent" do
|
29
|
+
it "does not render if path doesn't match" do
|
30
|
+
env = request.merge("HTTP_USER_AGENT" => "Googlebot", "PATH_INFO" => "/somewhere_else/a.html")
|
31
|
+
|
32
|
+
app.should_receive(:call).with(env)
|
33
|
+
RenderStatic::Renderer.should_not_receive(:render)
|
34
|
+
middleware.call(env)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "requests the same url and renders it" do
|
38
|
+
env = request.merge("HTTP_USER_AGENT" => "Googlebot", "PATH_INFO" => "/somewhere/index.html")
|
39
|
+
|
40
|
+
app.should_not_receive(:call)
|
41
|
+
RenderStatic::Renderer.should_receive(:render).with(env)
|
42
|
+
middleware.call(env)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "renders content without an explicit type" do
|
46
|
+
env = request.merge("HTTP_USER_AGENT" => "Googlebot", "PATH_INFO" => "/somewhere/index")
|
47
|
+
|
48
|
+
app.should_not_receive(:call)
|
49
|
+
RenderStatic::Renderer.should_receive(:render).with(env)
|
50
|
+
middleware.call(env)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "only renders GETs" do
|
54
|
+
env = request.merge("REQUEST_METHOD" => "POST", "PATH_INFO" => "/somewhere/index")
|
55
|
+
|
56
|
+
app.should_receive(:call)
|
57
|
+
RenderStatic::Renderer.should_not_receive(:render)
|
58
|
+
middleware.call(env)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "does not render non-html content" do
|
62
|
+
env = request.merge("HTTP_USER_AGENT" => "Googlebot", "PATH_INFO" => "/somewhere/a.js")
|
63
|
+
|
64
|
+
app.should_receive(:call).with(env)
|
65
|
+
RenderStatic::Renderer.should_not_receive(:render)
|
66
|
+
middleware.call(env)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "render_static/renderer"
|
2
|
+
|
3
|
+
describe RenderStatic::Renderer do
|
4
|
+
class Headless
|
5
|
+
def self.ly &block
|
6
|
+
yield
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".render" do
|
11
|
+
it "requests the content" do
|
12
|
+
env = { "HTTP_HOST" => "localhost:3000", "REQUEST_PATH" => "/abc", "rack.url_scheme" => "https" }
|
13
|
+
|
14
|
+
navigate = stub
|
15
|
+
browser = stub(navigate: navigate, page_source: "loaded page")
|
16
|
+
Selenium::WebDriver.should_receive(:for).with(:firefox) { browser }
|
17
|
+
|
18
|
+
navigate.should_receive(:to).with("https://localhost:3000/abc")
|
19
|
+
|
20
|
+
response = RenderStatic::Renderer.render(env)
|
21
|
+
|
22
|
+
response[0].should == 200
|
23
|
+
response[1].should == {"Content-Type"=>"text/html"}
|
24
|
+
response[2].should == ["loaded page"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: render_static
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- herval
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: selenium-webdriver
|
16
|
+
requirement: &2165685120 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2165685120
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: headless
|
27
|
+
requirement: &2165684400 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2165684400
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &2165683640 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2165683640
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: shoulda
|
49
|
+
requirement: &2165721660 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2165721660
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rdoc
|
60
|
+
requirement: &2165720560 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '3.12'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2165720560
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: &2165718900 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2165718900
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: jeweler
|
82
|
+
requirement: &2165718360 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.8.4
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2165718360
|
91
|
+
description: ! ' render_static allows you to make your single-page apps (Backbone,
|
92
|
+
Angular, etc) built on Rails SEO-friendly. It works by injecting a small rack middleware
|
93
|
+
that will render pages as plain html, when the requester is one of the most common
|
94
|
+
crawlers/bots out there (Google, Yahoo Baidu and Bing) '
|
95
|
+
email: hervalfreire@gmail.com
|
96
|
+
executables: []
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files:
|
99
|
+
- LICENSE.txt
|
100
|
+
- README.txt
|
101
|
+
files:
|
102
|
+
- Gemfile
|
103
|
+
- Gemfile.lock
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.txt
|
106
|
+
- Rakefile
|
107
|
+
- VERSION
|
108
|
+
- lib/render_static.rb
|
109
|
+
- lib/render_static/middleware.rb
|
110
|
+
- lib/render_static/rails/railtie.rb
|
111
|
+
- lib/render_static/renderer.rb
|
112
|
+
- render_static.gemspec
|
113
|
+
- spec/middleware_spec.rb
|
114
|
+
- spec/renderer_spec.rb
|
115
|
+
homepage: http://github.com/herval/render_static
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
segments:
|
129
|
+
- 0
|
130
|
+
hash: 1724286605502739496
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.8.15
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: render_static allows you to make your single-page apps (Backbone, Angular,
|
143
|
+
etc) built on Rails SEO-friendly.
|
144
|
+
test_files: []
|