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
|