First commit.
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
pkg/*
|
||||
*~
|
||||
\#*
|
||||
.\#*
|
||||
|
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009 Wlodek Bzyl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
142
README.markdown
Normal file
@ -0,0 +1,142 @@
|
||||
# Sinatra Extension: StaticAssets
|
||||
|
||||
Gem *sinatra-static-assets* implements the following helpers methods:
|
||||
|
||||
* `image_tag`
|
||||
* `stylesheet_link_tag`
|
||||
* `javascript_script_tag`
|
||||
* `link_tag`
|
||||
|
||||
To install it, run:
|
||||
|
||||
sudo gem install wbzyl-sinatra-static-assets -s http://gems.github.com
|
||||
|
||||
All these methods are simple wrappers around the `url_for` method
|
||||
from the [sinatra-url-for](http://github.com/emk/sinatra-url-for/) gem.
|
||||
|
||||
## When will you need it?
|
||||
|
||||
Whenever you use the
|
||||
[Passenger module for Apache2](http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rack_to_sub_uri)
|
||||
or use `Rack::URLMap` to dispatch an application to
|
||||
sub URI.
|
||||
|
||||
Example: Suppose that we already have a virtual host `hitch.local`
|
||||
and two Sinatra applications that live in
|
||||
`/home/me/www/summer` and `/home/me/www/winter`
|
||||
directories, respectively.
|
||||
We want our Sinatra applications to be accessible from
|
||||
the following sub URI:
|
||||
|
||||
http://hitch.local/summer
|
||||
|
||||
and
|
||||
|
||||
http://hitch.local/winter
|
||||
|
||||
To configure Apache2 and Passenger to serve our applications
|
||||
we need to create a new configuration file with the following content:
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName hitch.local
|
||||
DocumentRoot /srv/www/hitch.local
|
||||
|
||||
RackBaseURI /summer
|
||||
RackBaseURI /winter
|
||||
</VirtualHost>
|
||||
|
||||
and a link to the applications directories in `/srv/www/hitch.local`:
|
||||
|
||||
ln -s /home/me/www/summer/public /srv/www/hitch.local/summer
|
||||
ln -s /home/me/www/winter/public /srv/www/hitch.local/winter
|
||||
|
||||
After restarting an Apache2 server and visiting, for example, the first
|
||||
application at `http://hitch.local/summer` we see that links to
|
||||
images, stylesheets and javascripts are broken.
|
||||
|
||||
The hitch here is that in Sinatra applications we usually refer to
|
||||
images/stylesheets/javascripts with absolute URI:
|
||||
|
||||
/images/tatry1.jpg /stylesheets/app.css /javascripts/app.js
|
||||
|
||||
That setup **works** whenever we are running applications locally.
|
||||
The absolute URI above tells a browser to request images
|
||||
(stylesheets and javascripts) from:
|
||||
|
||||
http://localhost:4567/images/tatry1.jpg
|
||||
|
||||
which in turn, tells a server to send a file:
|
||||
|
||||
/home/me/www/summer/public/images/tatry1.jpg
|
||||
|
||||
The `public` directory is the default directory where static files
|
||||
should be served from.
|
||||
So, the `/images/tatry1.jpg` picture will be there and will be served
|
||||
unless we had changed that default directory.
|
||||
|
||||
But these absolute URIs do not work when, for example,
|
||||
the *summer* application is dispatched to `/summer` sub URI.
|
||||
As a result the images are at:
|
||||
|
||||
http://hitch.local/summer/images/tatry1.jpg
|
||||
|
||||
but we request them from:
|
||||
|
||||
http://hitch.local/images/tatry1.jpg
|
||||
|
||||
And this **does not work** because there is no application
|
||||
dispatched to *images* sub URI.
|
||||
|
||||
The recommended way to deal with an absolute URI
|
||||
is to use a helper method that automatically converts
|
||||
`/images/tatry1.jpg` to `/summer/images/tatry1.jpg`
|
||||
for application dispatched to `/summer` sub URI.
|
||||
|
||||
In the above example you can simply remove the `<img>`
|
||||
HTML tag and replace it with a Ruby inline code like this:
|
||||
|
||||
<%= image_tag("/images/tatry1.jpg", :alt => "Błyszcz, 2159 m") %>
|
||||
|
||||
See also, [How to fix broken images/CSS/JavaScript URIs in sub-URI
|
||||
deployments](http://www.modrails.com/documentation/Users%20guide%20Apache.html#sub_uri_deployment_uri_fix)
|
||||
|
||||
## Usage examples
|
||||
|
||||
In HTML `<link>` and `<img>` tags have no end tag.
|
||||
In XHTML, on the contrary, these tags must be properly closed.
|
||||
|
||||
We can choose the appropriate behaviour with *closed* option:
|
||||
|
||||
image_tag "/images/tatry1.jpg", :alt => "Błyszcz, 2159 m", :closed => true
|
||||
|
||||
The default value of *closed* option is `false`.
|
||||
|
||||
stylesheet_link_tag "/stylesheets/screen.css", "/stylesheets/summer.css", :media => "projection"
|
||||
javascript_script_tag "/javascripts/jquery.js", "/javascripts/summer.js", :charset => "iso-8859-2"
|
||||
link_to "Tatry Mountains Rescue Team", "/topr"
|
||||
|
||||
In order to use include the following in a Sinatra application:
|
||||
|
||||
gem 'wbzyl-sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
Or, if subclassing `Sinatra::Base`, include helpers manually:
|
||||
|
||||
gem 'wbzyl-sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
class Summer < Sinatra::Base
|
||||
helpers Sinatra::StaticAssets
|
||||
# ...
|
||||
end
|
||||
|
||||
|
||||
## Miscellaneous stuff
|
||||
|
||||
1. The `examples` directory contains *summer* and *winter* applications.
|
||||
|
||||
2. In order to create a virual host add the following to */etc/hosts/*:
|
||||
|
||||
127.0.0.1 localhost.localdomain localhost hitch.local
|
||||
|
||||
3. TODO: write tests
|
40
Rakefile
Normal file
@ -0,0 +1,40 @@
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
|
||||
begin
|
||||
require 'jeweler'
|
||||
Jeweler::Tasks.new do |gemspec|
|
||||
gemspec.name = "sinatra-static-assets"
|
||||
gemspec.summary = "Sinatra extension providing helper methods to output tags for static assetgemspec."
|
||||
gemspec.email = "matwb@univ.gda.pl"
|
||||
gemspec.homepage = "http://github.com/wbzyl/sinatra-static-assets"
|
||||
gemspec.authors = ["Wlodek Bzyl"]
|
||||
|
||||
gemspec.description = <<-EOF
|
||||
This Sinatra extensions provides following helper methods:
|
||||
- image_tag
|
||||
- stylesheet_link_tag
|
||||
- javascript_script_tag
|
||||
EOF
|
||||
|
||||
gemspec.files = %w{TODO VERSION.yml} + FileList['lib/**/*.rb', 'test/**/*.rb', 'examples/**/*']
|
||||
|
||||
gemspec.add_runtime_dependency 'rack', '>=1.0.0'
|
||||
gemspec.add_runtime_dependency 'sinatra'
|
||||
gemspec.add_runtime_dependency 'emk-sinatra-url-for', '>=0.2.1'
|
||||
|
||||
gemspec.add_development_dependency 'rack-test', '>=0.3.0'
|
||||
|
||||
gemspec.rubyforge_project = 'sinatra-static-assets'
|
||||
end
|
||||
rescue LoadError
|
||||
puts "Jeweler not available."
|
||||
puts "Install it with:"
|
||||
puts " sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
||||
end
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib' << 'test'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = false
|
||||
end
|
4
VERSION.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
:major: 0
|
||||
:minor: 1
|
||||
:patch: 0
|
14
examples/mapp1/config.ru
Normal file
@ -0,0 +1,14 @@
|
||||
require 'mapp'
|
||||
|
||||
Mapp1 = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Lint
|
||||
|
||||
use Rack::Static, :urls => ["/stylesheets", "/images"], :root => "public"
|
||||
|
||||
map '/' do
|
||||
run Sinatra::Mapp1.new
|
||||
end
|
||||
end
|
||||
|
||||
run Mapp1
|
24
examples/mapp1/mapp.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
require 'sinatra/base'
|
||||
|
||||
gem 'sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
module Sinatra
|
||||
class Mapp1 < Sinatra::Base
|
||||
helpers Sinatra::UrlForHelper
|
||||
helpers Sinatra::StaticAssets
|
||||
|
||||
set :app_file, __FILE__
|
||||
set :static, true
|
||||
|
||||
#set :root, File.dirname(__FILE__)
|
||||
#set :views, Proc.new { File.join(root, "views") }
|
||||
|
||||
get '/' do
|
||||
@title = "Tatra Mountains, Błyszcz (2159 m)"
|
||||
erb :app
|
||||
end
|
||||
end
|
||||
end
|
BIN
examples/mapp1/public/images/tatry1.jpg
Normal file
After Width: | Height: | Size: 82 KiB |
1
examples/mapp1/public/javascripts/mapp.js
Normal file
@ -0,0 +1 @@
|
||||
/* mapp1 */
|
14
examples/mapp1/public/stylesheets/mapp.css
Normal file
@ -0,0 +1,14 @@
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #ABA418 url(src/background.png);
|
||||
}
|
||||
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 1em auto;
|
||||
padding: 1em 2em;
|
||||
border: black solid 1px;
|
||||
background-color: #D1C704;
|
||||
font: normal 14px/1.6 Arial, Helvetica, sans-serif;
|
||||
}
|
BIN
examples/mapp1/public/stylesheets/src/background.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
0
examples/mapp1/tmp/always_restart.txt
Normal file
3
examples/mapp1/views/app.erb
Normal file
@ -0,0 +1,3 @@
|
||||
<h2><%= @title %></h2>
|
||||
|
||||
<p><%= image_tag "/images/tatry1.jpg", :closed => true, :alt => @title, :title => @title %></p>
|
23
examples/mapp1/views/layout.erb
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
|
||||
<!-- does not work
|
||||
|
||||
<link charset="utf-8" href="/stylesheets/mapp.css" media="screen" rel="stylesheet" type="text/css">
|
||||
|
||||
-->
|
||||
|
||||
<%= stylesheet_link_tag "/stylesheets/mapp.css" %>
|
||||
<%= javascript_script_tag "/javascripts/mapp.js" %>
|
||||
|
||||
<title><%= @title %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
14
examples/mapp2/config.ru
Normal file
@ -0,0 +1,14 @@
|
||||
require 'mapp'
|
||||
|
||||
Mapp2 = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Lint
|
||||
|
||||
use Rack::Static, :urls => ["/stylesheets", "/images"], :root => "public"
|
||||
|
||||
map '/' do
|
||||
run Sinatra::Mapp2.new
|
||||
end
|
||||
end
|
||||
|
||||
run Mapp2
|
21
examples/mapp2/mapp.rb
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
require 'sinatra/base'
|
||||
|
||||
gem 'sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
module Sinatra
|
||||
class Mapp2 < Sinatra::Base
|
||||
helpers Sinatra::UrlForHelper
|
||||
helpers Sinatra::StaticAssets
|
||||
|
||||
set :app_file, __FILE__
|
||||
set :static, true
|
||||
|
||||
get '/' do
|
||||
@title = "Tatra Mountains, Dolina Gąsienicowa (1500 m)"
|
||||
erb :mapp
|
||||
end
|
||||
end
|
||||
end
|
BIN
examples/mapp2/public/images/tatry2.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
1
examples/mapp2/public/javascripts/mapp.js
Normal file
@ -0,0 +1 @@
|
||||
/* mapp.js */
|
14
examples/mapp2/public/stylesheets/mapp.css
Normal file
@ -0,0 +1,14 @@
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #ABA418 url(src/background.png);
|
||||
}
|
||||
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 1em auto;
|
||||
padding: 1em 2em;
|
||||
border: black solid 1px;
|
||||
background-color: #D8E8FF;
|
||||
font: normal 14px/1.6 Arial, Helvetica, sans-serif;
|
||||
}
|
BIN
examples/mapp2/public/stylesheets/src/background.png
Normal file
After Width: | Height: | Size: 27 KiB |
0
examples/mapp2/tmp/always_restart.txt
Normal file
16
examples/mapp2/views/layout.erb
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<%= stylesheet_link_tag "/stylesheets/mapp.css" %>
|
||||
<%= javascript_script_tag "/javascripts/mapp.js" %>
|
||||
|
||||
<title><%= @title %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
3
examples/mapp2/views/mapp.erb
Normal file
@ -0,0 +1,3 @@
|
||||
<h2><%= @title %></h2>
|
||||
|
||||
<p><%= image_tag "/images/tatry2.jpg", :closed => true, :alt => @title, :title => @title %></p>
|
19
examples/mconfig.ru
Normal file
@ -0,0 +1,19 @@
|
||||
require 'mapp1/mapp'
|
||||
require 'mapp2/mapp'
|
||||
|
||||
Mapp = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Lint
|
||||
|
||||
#use Rack::Static, :urls => ["/stylesheets", "/images"], :root => "public"
|
||||
|
||||
map '/mapp1' do
|
||||
run Sinatra::Mapp1.new
|
||||
end
|
||||
|
||||
map '/mapp2' do
|
||||
run Sinatra::Mapp2.new
|
||||
end
|
||||
end
|
||||
|
||||
run Mapp
|
4
examples/summer/config.ru
Normal file
@ -0,0 +1,4 @@
|
||||
require 'summer'
|
||||
|
||||
use Rack::ShowExceptions
|
||||
run Sinatra::Application
|
BIN
examples/summer/public/images/tatry1.jpg
Normal file
After Width: | Height: | Size: 82 KiB |
1
examples/summer/public/javascripts/app.js
Normal file
@ -0,0 +1 @@
|
||||
/* summer: app.js */
|
14
examples/summer/public/stylesheets/app.css
Normal file
@ -0,0 +1,14 @@
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #ABA418 url(src/bronzed_olive.png);
|
||||
}
|
||||
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 1em auto;
|
||||
padding: 1em 2em;
|
||||
border: black solid 1px;
|
||||
background-color: #D1C704;
|
||||
font: normal 14px/1.6 Arial, Helvetica, sans-serif;
|
||||
}
|
BIN
examples/summer/public/stylesheets/src/bronzed_olive.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
16
examples/summer/summer.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
require 'sinatra'
|
||||
|
||||
gem 'wbzyl-sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
get "/?" do
|
||||
@title = "Tatra Mountains, Błyszcz (2159 m)"
|
||||
erb :index
|
||||
end
|
||||
|
||||
get "/:page" do
|
||||
@title = "#{params[:page]}"
|
||||
erb :"#{params[:page]}"
|
||||
end
|
0
examples/summer/tmp/always_restart.txt
Normal file
6
examples/summer/views/index.erb
Normal file
@ -0,0 +1,6 @@
|
||||
<h2><%= @title %></h2>
|
||||
|
||||
<p><%= image_tag "/images/tatry1.jpg", :closed => true, :alt => @title, :title => @title %></p>
|
||||
|
||||
<p><a href="/winter">Tatra Mountain in Winter</a></p>
|
||||
<p><%= link_to "Tatry Mountains Rescue Team", "/topr" %></p>
|
16
examples/summer/views/layout.erb
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<%= stylesheet_link_tag "/stylesheets/app.css" %>
|
||||
<%= javascript_script_tag "/javascripts/app.js" %>
|
||||
|
||||
<title><%= @title %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
5
examples/summer/views/topr.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<h3>Tatry Mountains Rescue Team</h3>
|
||||
|
||||
<p>The home page: <a href="http://www.topr.pl/">TOPR</a></a>
|
||||
|
||||
<p>The emergency telephone: +48 601 100 300</p>
|
12
examples/winter/app2.rb
Normal file
@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
|
||||
gem 'sinatra-static-assets'
|
||||
require 'sinatra/static_assets'
|
||||
|
||||
get "/?" do
|
||||
@title = "Tatra Mountains, Dolina Gąsienicowa (1500 m)"
|
||||
erb :index
|
||||
end
|
7
examples/winter/config.ru
Normal file
@ -0,0 +1,7 @@
|
||||
# run with: thin --rackup config.ru -p 4567 start
|
||||
|
||||
require 'app2'
|
||||
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Static, :urls => ["/stylesheets", "/javascripts", "/images"], :root => "public"
|
||||
run Sinatra::Application
|
BIN
examples/winter/public/images/tatry2.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
1
examples/winter/public/javascripts/app2.js
Normal file
@ -0,0 +1 @@
|
||||
/* app1.js */
|
18
examples/winter/public/stylesheets/app2.css
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Theme for app2: http://www.colourlovers.com/palette/81363/rainy
|
||||
*/
|
||||
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #659DF1 url(src/skating.png);
|
||||
}
|
||||
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 1em auto;
|
||||
padding: 1em 2em;
|
||||
border: black solid 1px;
|
||||
background-color: #D8E8FF;
|
||||
font: normal 14px/1.6 Arial, Helvetica, sans-serif;
|
||||
}
|
BIN
examples/winter/public/stylesheets/src/skating.png
Normal file
After Width: | Height: | Size: 27 KiB |
0
examples/winter/tmp/always_restart.txt
Normal file
3
examples/winter/views/index.erb
Normal file
@ -0,0 +1,3 @@
|
||||
<h2><%= @title %></h2>
|
||||
|
||||
<p><%= image_tag "/images/tatry2.jpg", :alt => @title, :title => @title %></p>
|
16
examples/winter/views/layout.erb
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<%= stylesheet_link_tag "/stylesheets/app2.css" %>
|
||||
<%= javascript_script_tag "/javascripts/app2.js" %>
|
||||
|
||||
<title><%= @title %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
72
lib/sinatra/static_assets.rb
Normal file
@ -0,0 +1,72 @@
|
||||
gem 'sinatra', '~>0.9.2'
|
||||
require 'sinatra/base'
|
||||
|
||||
gem 'emk-sinatra-url-for', '>=0.2.1'
|
||||
require 'sinatra/url_for'
|
||||
|
||||
module Sinatra
|
||||
module StaticAssets
|
||||
# In HTML <link> and <img> tags have no end tag.
|
||||
# In XHTML, on the contrary, these tags must be properly closed.
|
||||
#
|
||||
# We can choose the appropriate behaviour with +closed+ option:
|
||||
#
|
||||
# image_tag "/images/foo.png", :alt => "Foo itself", :closed => true
|
||||
#
|
||||
# The default value of +closed+ option is +false+.
|
||||
#
|
||||
def image_tag(source, options = {})
|
||||
closed = options.delete(:closed)
|
||||
options[:src] = url_for(source)
|
||||
tag("img", options, closed)
|
||||
end
|
||||
|
||||
def stylesheet_link_tag(*sources)
|
||||
list, options = extract_options(sources)
|
||||
closed = options.delete(:closed)
|
||||
list.collect { |source| stylesheet_tag(source, options, closed) }.join("\n")
|
||||
end
|
||||
|
||||
def javascript_script_tag(*sources)
|
||||
list, options = extract_options(sources)
|
||||
list.collect { |source| javascript_tag(source, options) }.join("\n")
|
||||
end
|
||||
|
||||
def link_to(desc, url)
|
||||
"<a href='#{url_for url}'>#{desc}</a>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag(name, options = {}, closed = false)
|
||||
"<#{name}#{tag_options(options) if options}#{closed ? " />" : ">"}"
|
||||
end
|
||||
|
||||
def tag_options(options)
|
||||
unless options.empty?
|
||||
attrs = []
|
||||
attrs = options.map { |key, value| %(#{key}="#{value}") }
|
||||
" #{attrs.sort * ' '}" unless attrs.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def stylesheet_tag(source, options, closed = false)
|
||||
tag("link", { :type => "text/css",
|
||||
:charset => "utf-8", :media => "screen", :rel => "stylesheet",
|
||||
:href => url_for(source) }.merge(options), closed)
|
||||
end
|
||||
|
||||
def javascript_tag(source, options)
|
||||
tag("script", { :type => "text/javascript", :charset => "utf-8",
|
||||
:src => url_for(source) }.merge(options), false) + "</script>"
|
||||
end
|
||||
|
||||
def extract_options(a)
|
||||
opts = a.last.is_a?(::Hash) ? a.pop : {}
|
||||
[a, opts]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
helpers StaticAssets
|
||||
end
|
101
sinatra-static-assets.gemspec
Normal file
@ -0,0 +1,101 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = %q{sinatra-static-assets}
|
||||
s.version = "0.1.0"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["Wlodek Bzyl"]
|
||||
s.date = %q{2009-06-01}
|
||||
s.description = %q{This Sinatra extensions provides following helper methods:
|
||||
- image_tag
|
||||
- stylesheet_link_tag
|
||||
- javascript_script_tag
|
||||
}
|
||||
s.email = %q{matwb@univ.gda.pl}
|
||||
s.extra_rdoc_files = [
|
||||
"LICENSE",
|
||||
"README.markdown"
|
||||
]
|
||||
s.files = [
|
||||
"TODO",
|
||||
"VERSION.yml",
|
||||
"examples/mapp1/config.ru",
|
||||
"examples/mapp1/mapp.rb",
|
||||
"examples/mapp1/public/images/tatry1.jpg",
|
||||
"examples/mapp1/public/javascripts/mapp.js",
|
||||
"examples/mapp1/public/stylesheets/mapp.css",
|
||||
"examples/mapp1/public/stylesheets/src/background.png",
|
||||
"examples/mapp1/tmp/always_restart.txt",
|
||||
"examples/mapp1/views/app.erb",
|
||||
"examples/mapp1/views/layout.erb",
|
||||
"examples/mapp2/config.ru",
|
||||
"examples/mapp2/mapp.rb",
|
||||
"examples/mapp2/public/images/tatry2.jpg",
|
||||
"examples/mapp2/public/javascripts/mapp.js",
|
||||
"examples/mapp2/public/stylesheets/mapp.css",
|
||||
"examples/mapp2/public/stylesheets/src/background.png",
|
||||
"examples/mapp2/tmp/always_restart.txt",
|
||||
"examples/mapp2/views/layout.erb",
|
||||
"examples/mapp2/views/mapp.erb",
|
||||
"examples/mconfig.ru",
|
||||
"examples/summer/config.ru",
|
||||
"examples/summer/public/images/tatry1.jpg",
|
||||
"examples/summer/public/javascripts/app.js",
|
||||
"examples/summer/public/stylesheets/app.css",
|
||||
"examples/summer/public/stylesheets/src/bronzed_olive.png",
|
||||
"examples/summer/summer.rb",
|
||||
"examples/summer/tmp/always_restart.txt",
|
||||
"examples/summer/views/index.erb",
|
||||
"examples/summer/views/layout.erb",
|
||||
"examples/summer/views/topr.erb",
|
||||
"examples/winter/app2.rb",
|
||||
"examples/winter/config.ru",
|
||||
"examples/winter/public/images/tatry2.jpg",
|
||||
"examples/winter/public/javascripts/app2.js",
|
||||
"examples/winter/public/stylesheets/app2.css",
|
||||
"examples/winter/public/stylesheets/src/skating.png",
|
||||
"examples/winter/tmp/always_restart.txt",
|
||||
"examples/winter/views/index.erb",
|
||||
"examples/winter/views/layout.erb",
|
||||
"lib/sinatra/static_assets.rb",
|
||||
"test/sinatra_static_assets_test.rb",
|
||||
"test/test_helper.rb"
|
||||
]
|
||||
s.homepage = %q{http://github.com/wbzyl/sinatra-static-assets}
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.require_paths = ["lib"]
|
||||
s.rubyforge_project = %q{sinatra-static-assets}
|
||||
s.rubygems_version = %q{1.3.4}
|
||||
s.summary = %q{Sinatra extension providing helper methods to output tags for static assetgemspec.}
|
||||
s.test_files = [
|
||||
"test/test_helper.rb",
|
||||
"test/sinatra_static_assets_test.rb",
|
||||
"examples/summer/summer.rb",
|
||||
"examples/mapp2/mapp.rb",
|
||||
"examples/mapp1/mapp.rb",
|
||||
"examples/winter/app2.rb"
|
||||
]
|
||||
|
||||
if s.respond_to? :specification_version then
|
||||
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||
s.specification_version = 3
|
||||
|
||||
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||
s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
|
||||
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
||||
s.add_runtime_dependency(%q<emk-sinatra-url-for>, [">= 0.2.1"])
|
||||
s.add_development_dependency(%q<rack-test>, [">= 0.3.0"])
|
||||
else
|
||||
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
||||
s.add_dependency(%q<sinatra>, [">= 0"])
|
||||
s.add_dependency(%q<emk-sinatra-url-for>, [">= 0.2.1"])
|
||||
s.add_dependency(%q<rack-test>, [">= 0.3.0"])
|
||||
end
|
||||
else
|
||||
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
||||
s.add_dependency(%q<sinatra>, [">= 0"])
|
||||
s.add_dependency(%q<emk-sinatra-url-for>, [">= 0.2.1"])
|
||||
s.add_dependency(%q<rack-test>, [">= 0.3.0"])
|
||||
end
|
||||
end
|
91
test/sinatra_static_assets_test.rb
Normal file
@ -0,0 +1,91 @@
|
||||
require File.dirname(__FILE__) + '/test_helper'
|
||||
|
||||
class SinatraRDiscountTest < Test::Unit::TestCase
|
||||
include Rack::Test::Methods
|
||||
|
||||
def rdiscount_app(&block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
helpers Sinatra::RDiscount
|
||||
set :show_exceptions, false
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
end
|
||||
|
||||
def test_renders_inline_strings
|
||||
rdiscount_app { rdiscount 'hello world' }
|
||||
assert last_response.ok?
|
||||
assert_equal "<p>hello world</p>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_renders_inline_erb_string
|
||||
rdiscount_app { rdiscount '{%= 1 + 1 %}' }
|
||||
assert last_response.ok?
|
||||
assert_equal "<p>2</p>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_renders_files_in_views_path
|
||||
rdiscount_app { rdiscount :hello }
|
||||
assert last_response.ok?
|
||||
assert_equal "<h1>hello world</h1>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_takes_locals_option
|
||||
rdiscount_app {
|
||||
locals = {:foo => 'Bar'}
|
||||
rdiscount "{%= foo %}", :locals => locals
|
||||
}
|
||||
assert last_response.ok?
|
||||
assert_equal "<p>Bar</p>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_renders_with_inline_layouts
|
||||
rdiscount_app {
|
||||
rdiscount 'Sparta', :layout => 'THIS. IS. <%= yield.upcase %>'
|
||||
}
|
||||
assert last_response.ok?
|
||||
assert_equal "THIS. IS. <P>SPARTA</P>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_renders_with_file_layouts
|
||||
rdiscount_app {
|
||||
rdiscount 'hello world', :layout => :layout2
|
||||
}
|
||||
assert last_response.ok?
|
||||
assert_equal "erb layout\n<p>hello world</p>\n\n", last_response.body
|
||||
end
|
||||
|
||||
def test_renders_erb_with_blocks
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
helpers Sinatra::RDiscount
|
||||
|
||||
def container
|
||||
yield
|
||||
end
|
||||
def is;
|
||||
"THIS. IS. SPARTA!"
|
||||
end
|
||||
|
||||
get '/' do
|
||||
rdiscount '{% container do %} {%= is %} {% end %}'
|
||||
end
|
||||
}
|
||||
|
||||
get '/'
|
||||
assert last_response.ok?
|
||||
assert_equal "<p> THIS. IS. SPARTA! </p>\n", last_response.body
|
||||
end
|
||||
|
||||
def test_raises_error_if_template_not_found
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
helpers Sinatra::RDiscount
|
||||
set :show_exceptions, false
|
||||
|
||||
get('/') { rdiscount :no_such_template }
|
||||
}
|
||||
assert_raise(Errno::ENOENT) { get('/') }
|
||||
end
|
||||
end
|
21
test/test_helper.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'rack/test'
|
||||
|
||||
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
||||
require 'sinatra/rdiscount'
|
||||
|
||||
require 'rdiscount'
|
||||
|
||||
class Test::Unit::TestCase
|
||||
include Rack::Test::Methods
|
||||
|
||||
attr_reader :app
|
||||
|
||||
# Sets up a Sinatra::Base subclass defined with the block
|
||||
# given. Used in setup or individual spec methods to establish
|
||||
# the application.
|
||||
def mock_app(base=Sinatra::Base, &block)
|
||||
@app = Sinatra.new(base, &block)
|
||||
end
|
||||
end
|