1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
require 'sinatra/base'
module Sinatra
# = Sinatra::LinkHeader
#
# <tt>Sinatra::LinkHeader</tt> adds a set of helper methods to generate link
# HTML tags and their corresponding Link HTTP headers.
#
# == Usage
#
# Once you had set up the helpers in your application (see below), you will
# be able to call the following methods from inside your route handlers,
# filters and templates:
#
# +prefetch+::
# Sets the Link HTTP headers and returns HTML tags to prefetch the given
# resources.
#
# +stylesheet+::
# Sets the Link HTTP headers and returns HTML tags to use the given
# stylesheets.
#
# +link+::
# Sets the Link HTTP headers and returns the corresponding HTML tags
# for the given resources.
#
# +link_headers+::
# Returns the corresponding HTML tags for the current Link HTTP headers.
#
# === Classic Application
#
# In a classic application simply require the helpers, and start using them:
#
# require "sinatra"
# require "sinatra/link_header"
#
# # The rest of your classic application code goes here...
#
# === Modular Application
#
# In a modular application you need to require the helpers, and then tell
# the application you will use them:
#
# require "sinatra/base"
# require "sinatra/link_header"
#
# class MyApp < Sinatra::Base
# helpers Sinatra::LinkHeader
#
# # The rest of your modular application code goes here...
# end
#
module LinkHeader
##
# Sets 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'] ||= '')
link = response['Link'] = +link
urls.map do |url|
link << "," unless link.empty?
link << (http_pattern % url)
html_pattern % url
end.join
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'].split(",").map do |line|
url, *opts = line.split(';').map(&:strip)
"<link href=\"#{url[1..-2]}\" #{opts.join ' '} />"
end.join
end
def self.registered(_base)
puts "WARNING: #{self} is a helpers module, not an extension."
end
end
helpers LinkHeader
end
|