mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
new extensions: sinatra-link-helper
This commit is contained in:
parent
fd19d70134
commit
074aedc187
2 changed files with 184 additions and 0 deletions
84
sinatra-contrib/lib/sinatra/link_header.rb
Normal file
84
sinatra-contrib/lib/sinatra/link_header.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
require 'sinatra/base'
|
||||
|
||||
module Sinatra
|
||||
##
|
||||
# Helper methods for generating Link HTTP headers and HTML tags.
|
||||
module LinkHeader
|
||||
##
|
||||
# Set Link HTTP header and returns HTML tags for telling the browser to
|
||||
# prefetch given resources (only supported by Opera and Firefox at the
|
||||
# moment).
|
||||
def prefetch(*urls)
|
||||
link(:prefetch, *urls)
|
||||
end
|
||||
|
||||
##
|
||||
# Sets Link HTTP header and returns HTML tags for using stylesheets.
|
||||
def stylesheet(*urls)
|
||||
urls << {} unless urls.last.respond_to? :to_hash
|
||||
urls.last[:type] ||= mime_type(:css)
|
||||
link(:stylesheet, *urls)
|
||||
end
|
||||
|
||||
##
|
||||
# Sets Link HTTP header and returns corresponding HTML tags.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# # Sets header:
|
||||
# # Link: </foo>; rel="next"
|
||||
# # Returns String:
|
||||
# # '<link href="/foo" rel="next" />'
|
||||
# link '/foo', :rel => :next
|
||||
#
|
||||
# # Multiple URLs
|
||||
# link :stylesheet, '/a.css', '/b.css'
|
||||
def link(*urls)
|
||||
opts = urls.last.respond_to?(:to_hash) ? urls.pop : {}
|
||||
opts[:rel] = urls.shift unless urls.first.respond_to? :to_str
|
||||
options = opts.map { |k, v| " #{k}=#{v.to_s.inspect}" }
|
||||
html_pattern = "<link href=\"%s\"#{options.join} />"
|
||||
http_pattern = ["<%s>", *options].join ";"
|
||||
link = (response["Link"] ||= "")
|
||||
|
||||
urls.map do |url|
|
||||
link << "\n" unless link.empty?
|
||||
link << (http_pattern % url)
|
||||
html_pattern % url
|
||||
end.join "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Takes the current value of th Link header(s) and generates HTML tags
|
||||
# from it.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# get '/' do
|
||||
# # You can of course use fancy helpers like #link, #stylesheet
|
||||
# # or #prefetch
|
||||
# response["Link"] = '</foo>; rel="next"'
|
||||
# haml :some_page
|
||||
# end
|
||||
#
|
||||
# __END__
|
||||
#
|
||||
# @@ layout
|
||||
# %head= link_headers
|
||||
# %body= yield
|
||||
def link_headers
|
||||
yield if block_given?
|
||||
return "" unless response.include? "Link"
|
||||
response["Link"].lines.map do |line|
|
||||
url, *opts = line.split(';').map(&:strip)
|
||||
"<link href=\"#{url[1..-2]}\" #{opts.join " "} />"
|
||||
end.join "\n"
|
||||
end
|
||||
|
||||
def self.registered(base)
|
||||
puts "WARNING: #{self} is a helpers module, not an extension."
|
||||
end
|
||||
end
|
||||
|
||||
helpers LinkHeader
|
||||
end
|
100
sinatra-contrib/spec/link_header_spec.rb
Normal file
100
sinatra-contrib/spec/link_header_spec.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
require 'backports'
|
||||
require_relative 'spec_helper'
|
||||
|
||||
describe Sinatra::LinkHeader do
|
||||
before do
|
||||
mock_app do
|
||||
helpers Sinatra::LinkHeader
|
||||
before('/') { link 'something', :rel => 'from-filter', :foo => :bar }
|
||||
|
||||
get '/' do
|
||||
link :something, 'booyah'
|
||||
end
|
||||
|
||||
get '/style' do
|
||||
stylesheet '/style.css'
|
||||
end
|
||||
|
||||
get '/prefetch' do
|
||||
prefetch '/foo'
|
||||
end
|
||||
|
||||
get '/link_headers' do
|
||||
response['Link'] = "<foo> ;bar=\"baz\""
|
||||
stylesheet '/style.css'
|
||||
prefetch '/foo'
|
||||
link_headers
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :link do
|
||||
it "sets link headers" do
|
||||
get '/'
|
||||
headers['Link'].lines.should include('<booyah>; rel="something"')
|
||||
end
|
||||
|
||||
it "returns link html tags" do
|
||||
get '/'
|
||||
body.should == '<link href="booyah" rel="something" />'
|
||||
end
|
||||
|
||||
it "takes an options hash" do
|
||||
get '/'
|
||||
elements = ["<something>", "foo=\"bar\"", "rel=\"from-filter\""]
|
||||
headers['Link'].lines.first.strip.split('; ').sort.should == elements
|
||||
end
|
||||
end
|
||||
|
||||
describe :stylesheet do
|
||||
it 'sets link headers' do
|
||||
get '/style'
|
||||
headers['Link'].should match(%r{^</style\.css>;})
|
||||
end
|
||||
|
||||
it 'sets type to text/css' do
|
||||
get '/style'
|
||||
headers['Link'].should include('type="text/css"')
|
||||
end
|
||||
|
||||
it 'sets rel to stylesheet' do
|
||||
get '/style'
|
||||
headers['Link'].should include('rel="stylesheet"')
|
||||
end
|
||||
|
||||
it 'returns html tag' do
|
||||
get '/style'
|
||||
body.should match(%r{^<link href="/style\.css"})
|
||||
end
|
||||
end
|
||||
|
||||
describe :prefetch do
|
||||
it 'sets link headers' do
|
||||
get '/prefetch'
|
||||
headers['Link'].should match(%r{^</foo>;})
|
||||
end
|
||||
|
||||
it 'sets rel to prefetch' do
|
||||
get '/prefetch'
|
||||
headers['Link'].should include('rel="prefetch"')
|
||||
end
|
||||
|
||||
it 'returns html tag' do
|
||||
get '/prefetch'
|
||||
body.should == '<link href="/foo" rel="prefetch" />'
|
||||
end
|
||||
end
|
||||
|
||||
describe :link_headers do
|
||||
it 'generates html for all link headers' do
|
||||
get '/link_headers'
|
||||
body.should include('<link href="/foo" rel="prefetch" />')
|
||||
body.should include('<link href="/style.css" ')
|
||||
end
|
||||
|
||||
it "respects Link headers not generated on its own" do
|
||||
get '/link_headers'
|
||||
body.should include('<link href="foo" bar="baz" />')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue