piano 0.10.4 → 0.10.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +248 -234
- data/Rakefile +1 -1
- data/bin/piano +62 -87
- data/bin/piano~ +87 -0
- data/lib/piano.rb +46 -186
- data/lib/piano/controllerloader.rb +39 -39
- data/lib/piano/routes.rb +23 -23
- data/lib/piano/version.rb +3 -3
- data/lib/sinatra/piano.rb +141 -0
- data/sample/data/index.yaml +7 -7
- data/sample/index.haml +10 -10
- data/sample/style.sass +5 -5
- metadata +22 -21
- data/Gemfile +0 -4
- data/spec/controller_spec.rb +0 -90
@@ -1,39 +1,39 @@
|
|
1
|
-
require "polyglot"
|
2
|
-
|
3
|
-
module Piano
|
4
|
-
# Controller loader especifically for polyglot
|
5
|
-
class PolyglotControllerLoader
|
6
|
-
# Loads the file, no more settings for the moment
|
7
|
-
def self.load filename, options = nil, &block
|
8
|
-
Kernel.eval File.read filename
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
# Handler of .controller files loading
|
13
|
-
class ControllerLoader
|
14
|
-
def self.folder path
|
15
|
-
$LOAD_PATH << Dir.pwd
|
16
|
-
recursive path do |item|
|
17
|
-
require item
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Iterates recursively over the path and calls the block
|
22
|
-
# with each newfound file
|
23
|
-
def self.recursive path, &block
|
24
|
-
files = []
|
25
|
-
Dir.new(File.expand_path(path)).each do |file|
|
26
|
-
if File.directory? "#{path}/#{file}"
|
27
|
-
recursive "#{path}/#{file}" do |item|
|
28
|
-
files << "#{item}"
|
29
|
-
end unless file == ".." or file == "."
|
30
|
-
elsif file.end_with? ".controller"
|
31
|
-
files << "#{path}/#{file[0..-12]}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
files.each { |item| block.call(item) }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
Polyglot.register "controller", Piano::PolyglotControllerLoader
|
1
|
+
require "polyglot"
|
2
|
+
|
3
|
+
module Piano
|
4
|
+
# Controller loader especifically for polyglot
|
5
|
+
class PolyglotControllerLoader
|
6
|
+
# Loads the file, no more settings for the moment
|
7
|
+
def self.load filename, options = nil, &block
|
8
|
+
Kernel.eval File.read filename
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Handler of .controller files loading
|
13
|
+
class ControllerLoader
|
14
|
+
def self.folder path
|
15
|
+
$LOAD_PATH << Dir.pwd
|
16
|
+
recursive path do |item|
|
17
|
+
require item
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Iterates recursively over the path and calls the block
|
22
|
+
# with each newfound file
|
23
|
+
def self.recursive path, &block
|
24
|
+
files = []
|
25
|
+
Dir.new(File.expand_path(path)).each do |file|
|
26
|
+
if File.directory? "#{path}/#{file}"
|
27
|
+
recursive "#{path}/#{file}" do |item|
|
28
|
+
files << "#{item}"
|
29
|
+
end unless file == ".." or file == "."
|
30
|
+
elsif file.end_with? ".controller"
|
31
|
+
files << "#{path}/#{file[0..-12]}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
files.each { |item| block.call(item) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Polyglot.register "controller", Piano::PolyglotControllerLoader
|
data/lib/piano/routes.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
module Piano
|
2
|
-
class Base
|
3
|
-
get "/" do
|
4
|
-
@data = data_for "index"
|
5
|
-
try_haml "index"
|
6
|
-
end
|
7
|
-
|
8
|
-
get %r{/(.+?).css$} do |something|
|
9
|
-
content_type :css
|
10
|
-
sass something
|
11
|
-
end
|
12
|
-
|
13
|
-
get %r{/(.+?).js$} do |something|
|
14
|
-
content_type :js
|
15
|
-
coffee something
|
16
|
-
end
|
17
|
-
|
18
|
-
get "/*" do
|
19
|
-
something = request.path[1..(request.path.length-1)]
|
20
|
-
@data = data_for something
|
21
|
-
try_haml something
|
22
|
-
end
|
23
|
-
end
|
1
|
+
module Piano
|
2
|
+
class Base
|
3
|
+
get "/" do
|
4
|
+
@data = data_for "index"
|
5
|
+
try_haml "index"
|
6
|
+
end
|
7
|
+
|
8
|
+
get %r{/(.+?).css$} do |something|
|
9
|
+
content_type :css
|
10
|
+
sass something
|
11
|
+
end
|
12
|
+
|
13
|
+
get %r{/(.+?).js$} do |something|
|
14
|
+
content_type :js
|
15
|
+
coffee something
|
16
|
+
end
|
17
|
+
|
18
|
+
get "/*" do
|
19
|
+
something = request.path[1..(request.path.length-1)]
|
20
|
+
@data = data_for something
|
21
|
+
try_haml something
|
22
|
+
end
|
23
|
+
end
|
24
24
|
end
|
data/lib/piano/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Piano
|
2
|
-
VERSION = "0.10.
|
3
|
-
end
|
1
|
+
module Piano
|
2
|
+
VERSION = "0.10.6"
|
3
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Sinatra
|
2
|
+
|
3
|
+
# Piano was originally though as a Sinatra extension
|
4
|
+
# That's why the code was defined here
|
5
|
+
module Piano
|
6
|
+
|
7
|
+
# Like Sinatra's/Tilt's `haml`, but adds etags and
|
8
|
+
# returns a 404 with some hints if the haml is not found
|
9
|
+
def try_haml(template)
|
10
|
+
file_name = "#{pwd}/#{template}.haml"
|
11
|
+
bad_luck file_name unless File.exists? file_name
|
12
|
+
|
13
|
+
if etags?
|
14
|
+
hash = hash_for template, :haml
|
15
|
+
hash += hash_for "data/#{template}", :yaml if File.exists? "#{pwd}/data/#{template}.yaml"
|
16
|
+
etag hash
|
17
|
+
end
|
18
|
+
haml template.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
# Loads and parses a `sass` template from the :views directory.
|
22
|
+
# Adds an etag if `etags?` is enabled and returns 404 and hints
|
23
|
+
# if it can't find the .sass file.
|
24
|
+
def sass(template)
|
25
|
+
file_name = "#{pwd}/#{template}.sass"
|
26
|
+
bad_luck file_name unless File.exists? file_name
|
27
|
+
|
28
|
+
etag hash_for(template, :sass) if etags?
|
29
|
+
Sass.compile File.read(file_name), :syntax => :sass
|
30
|
+
end
|
31
|
+
|
32
|
+
# Loads and parses a `coffee-script` template from the :views
|
33
|
+
# directory.
|
34
|
+
# Adds an etag if `etags?` is enabled and returns 404 and hints
|
35
|
+
# if it can't find the .coffee file.
|
36
|
+
def coffee(template)
|
37
|
+
file_name = "#{pwd}/#{template}.coffee"
|
38
|
+
bad_luck file_name unless File.exists? file_name
|
39
|
+
|
40
|
+
etag hash_for(template, :coffee) if etags?
|
41
|
+
CoffeeScript.compile(File.read(file_name))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Loads and parses the YAML data from the data directory
|
45
|
+
def data_for(template)
|
46
|
+
file_name = "#{settings.data}/#{template}.yaml"
|
47
|
+
YAML.load_file(file_name) if File.exists?(file_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sugar: formats a css stylesheet <link /> tag with the input
|
51
|
+
def style(path)
|
52
|
+
"<link rel='stylesheet' type='text/css' href='#{path}' />"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sugar: formats a javascript <script> tag with the input
|
56
|
+
def script(path)
|
57
|
+
"<script type='text/javascript' src='#{path}'></script>"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the path to the :views directory
|
61
|
+
def pwd
|
62
|
+
settings.views
|
63
|
+
end
|
64
|
+
|
65
|
+
# Fails. Shouts a 404 response and prints hints
|
66
|
+
#
|
67
|
+
# If Piano is running in production mode, prints a plain 404 html
|
68
|
+
# or, if a 404.haml exists in the :views directory, returns it
|
69
|
+
def bad_luck(path)
|
70
|
+
content_type :html
|
71
|
+
if settings.environment == :production
|
72
|
+
if File.exists? "#{pwd}/404.haml"
|
73
|
+
@data = data_for "404"
|
74
|
+
halt 404, haml(:"404")
|
75
|
+
else
|
76
|
+
halt 404, "<h1>404 - Not Found</h1><p>Piano has found nothing in this address</p>"
|
77
|
+
end
|
78
|
+
else
|
79
|
+
halt 404, "<h1>You have still to put something here.</h1><p>This is <em>#{path}</em></p><blockquote>Good luck!</blockquote>"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Builds a hash for a file within the :views directory
|
84
|
+
# Note: I feel like this functionality should be private
|
85
|
+
def hash_for(name, type)
|
86
|
+
"#{name}.#{type} - " + File.mtime("#{pwd}/#{name}.#{type}").to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
# Makes an extract out of the given text with the default length
|
90
|
+
# of 80 words
|
91
|
+
#
|
92
|
+
# If an integer is passed as the second argument, the length
|
93
|
+
# of the result is adjusted properly:
|
94
|
+
#
|
95
|
+
# extract "Hello World! Too much text is inconvenient", 2
|
96
|
+
#
|
97
|
+
# returns
|
98
|
+
#
|
99
|
+
# => "Hello World!..."
|
100
|
+
#
|
101
|
+
def extract(text, length = 80)
|
102
|
+
words = text.gsub(/<.+?>/, "").split
|
103
|
+
return text if words.length <= length
|
104
|
+
words[0..(length-1)].join(" ") + "..."
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns a url-friendly version of the given link, with a
|
108
|
+
# default maximum of 5 words.
|
109
|
+
# `link` strips any non-letter or special character, downcases the
|
110
|
+
# string and replaces whitespace with "-"
|
111
|
+
# For example:
|
112
|
+
#
|
113
|
+
# link "This is a special text! This won't be shown"
|
114
|
+
#
|
115
|
+
# returns
|
116
|
+
#
|
117
|
+
# => "this-is-a-special-text"
|
118
|
+
#
|
119
|
+
# You can specify a word length in the second argument.
|
120
|
+
def link(text, length = 5)
|
121
|
+
words = text.gsub(/<.+?>/, "").gsub(" ", "-").downcase.gsub(/[^a-z0-9\-]/, "").split("-")
|
122
|
+
words[0..(length-1)].join("-")
|
123
|
+
end
|
124
|
+
|
125
|
+
# Shorthand to settings.etags == :on
|
126
|
+
def etags?
|
127
|
+
if settings.respond_to? :etags
|
128
|
+
settings.etags == :on
|
129
|
+
else
|
130
|
+
true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Non implemented yet
|
135
|
+
def t(key)
|
136
|
+
I18n.translate key
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
register Piano
|
141
|
+
end
|
data/sample/data/index.yaml
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
title: 5 minutes site!
|
2
|
-
description: Is amazing how simple it gets
|
3
|
-
list:
|
4
|
-
- and I can have
|
5
|
-
- a list
|
6
|
-
- also.
|
7
|
-
content: |
|
1
|
+
title: 5 minutes site!
|
2
|
+
description: Is amazing how simple it gets
|
3
|
+
list:
|
4
|
+
- and I can have
|
5
|
+
- a list
|
6
|
+
- also.
|
7
|
+
content: |
|
8
8
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a tortor vel sapien facilisis faucibus at eget dolor. Sed rhoncus est sit amet ipsum cursus eu porttitor dui eleifend. Maecenas accumsan egestas dolor eu imperdiet. Maecenas molestie urna quis sapien volutpat eu pretium risus rutrum. Pellentesque commodo urna eu tortor euismod venenatis. Pellentesque luctus dui ullamcorper eros feugiat sit amet suscipit lectus iaculis. Aliquam dolor massa, pulvinar id feugiat sed, commodo non dolor. Mauris fringilla purus ut nunc dapibus ac posuere velit adipiscing. Etiam id vestibulum eros. Aenean id dolor lorem. Donec sed lacus vel sem congue congue eu nec tellus.
|
data/sample/index.haml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
!!! 5
|
2
|
-
%head
|
3
|
-
%title= @data['title']
|
4
|
-
= style "style.css"
|
5
|
-
= script "app.js"
|
6
|
-
%body
|
7
|
-
%h1= @data['title']
|
8
|
-
%p= @data['description']
|
9
|
-
%ul
|
10
|
-
- @data['list'].each do |item|
|
1
|
+
!!! 5
|
2
|
+
%head
|
3
|
+
%title= @data['title']
|
4
|
+
= style "style.css"
|
5
|
+
= script "app.js"
|
6
|
+
%body
|
7
|
+
%h1= @data['title']
|
8
|
+
%p= @data['description']
|
9
|
+
%ul
|
10
|
+
- @data['list'].each do |item|
|
11
11
|
%li= item
|
data/sample/style.sass
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
body
|
2
|
-
width: 960px
|
3
|
-
margin: 0 auto
|
4
|
-
font:
|
5
|
-
family: sans-serif
|
1
|
+
body
|
2
|
+
width: 960px
|
3
|
+
margin: 0 auto
|
4
|
+
font:
|
5
|
+
family: sans-serif
|
6
6
|
size: 15px
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: piano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
requirement: &
|
16
|
+
requirement: &16774000 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.2.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *16774000
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: haml
|
27
|
-
requirement: &
|
27
|
+
requirement: &16772720 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.1.1
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *16772720
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sass
|
38
|
-
requirement: &
|
38
|
+
requirement: &16770960 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 3.1.1
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *16770960
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: coffee-script
|
49
|
-
requirement: &
|
49
|
+
requirement: &16770080 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 2.2.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *16770080
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: i18n
|
60
|
-
requirement: &
|
60
|
+
requirement: &16769340 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.6.0
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *16769340
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: polyglot
|
71
|
-
requirement: &
|
71
|
+
requirement: &16768600 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.3.1
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *16768600
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: metafun
|
82
|
-
requirement: &
|
82
|
+
requirement: &16756100 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *16756100
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: rspec
|
93
|
-
requirement: &
|
93
|
+
requirement: &16755220 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,31 +98,32 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *16755220
|
102
102
|
description: Out-of-the-box sinatra server for web site sketching using haml + sass
|
103
103
|
+ coffee-script
|
104
104
|
email:
|
105
105
|
- xavierviacanel@gmail.com
|
106
106
|
executables:
|
107
107
|
- piano
|
108
|
+
- piano~
|
108
109
|
extensions: []
|
109
110
|
extra_rdoc_files: []
|
110
111
|
files:
|
111
112
|
- .gitignore
|
112
|
-
- Gemfile
|
113
113
|
- README.rdoc
|
114
114
|
- Rakefile
|
115
115
|
- bin/piano
|
116
|
+
- bin/piano~
|
116
117
|
- lib/piano.rb
|
117
118
|
- lib/piano/controllerloader.rb
|
118
119
|
- lib/piano/routes.rb
|
119
120
|
- lib/piano/version.rb
|
121
|
+
- lib/sinatra/piano.rb
|
120
122
|
- piano.gemspec
|
121
123
|
- sample/app.coffee
|
122
124
|
- sample/data/index.yaml
|
123
125
|
- sample/index.haml
|
124
126
|
- sample/style.sass
|
125
|
-
- spec/controller_spec.rb
|
126
127
|
homepage: http://github.com/xaviervia/piano
|
127
128
|
licenses: []
|
128
129
|
post_install_message:
|
@@ -143,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
144
|
version: '0'
|
144
145
|
requirements: []
|
145
146
|
rubyforge_project: piano
|
146
|
-
rubygems_version: 1.8.
|
147
|
+
rubygems_version: 1.8.10
|
147
148
|
signing_key:
|
148
149
|
specification_version: 3
|
149
150
|
summary: Out-of-the-box sinatra server for web site sketching using haml + sass +
|