nitro 0.26.0 → 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +312 -0
- data/INSTALL +3 -1
- data/ProjectInfo +6 -9
- data/README +32 -5
- data/Rakefile +5 -1
- data/bin/nitrogen +3 -60
- data/doc/MIGRATION +24 -0
- data/doc/RELEASES +141 -0
- data/doc/lhttpd.txt +3 -0
- data/lib/glue/magick.rb +38 -0
- data/lib/glue/thumbnails.rb +3 -0
- data/lib/glue/webfile.rb +137 -0
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +235 -0
- data/lib/nitro/adapter/cgi.rb +16 -17
- data/lib/nitro/adapter/scgi.rb +4 -4
- data/lib/nitro/adapter/webrick.rb +9 -2
- data/lib/nitro/cgi.rb +49 -49
- data/lib/nitro/cgi/response.rb +4 -0
- data/lib/nitro/cgi/stream.rb +7 -7
- data/lib/nitro/cgi/utils.rb +2 -1
- data/lib/nitro/compiler.rb +47 -4
- data/lib/nitro/compiler/elements.rb +40 -20
- data/lib/nitro/compiler/layout.rb +21 -0
- data/lib/nitro/compiler/localization.rb +3 -1
- data/lib/nitro/compiler/markup.rb +2 -0
- data/lib/nitro/compiler/morphing.rb +16 -4
- data/lib/nitro/compiler/script.rb +109 -0
- data/lib/nitro/context.rb +10 -10
- data/lib/nitro/dispatcher.rb +4 -2
- data/lib/nitro/element.rb +107 -26
- data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
- data/lib/nitro/flash.rb +4 -1
- data/lib/nitro/helper.rb +15 -0
- data/lib/nitro/helper/benchmark.rb +8 -2
- data/lib/nitro/helper/form.rb +3 -3
- data/lib/nitro/helper/form/controls.rb +131 -29
- data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
- data/lib/nitro/helper/javascript.rb +69 -59
- data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
- data/lib/nitro/helper/javascript/morphing.rb +163 -0
- data/lib/nitro/helper/javascript/prototype.rb +96 -0
- data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
- data/lib/nitro/helper/layout.rb +42 -0
- data/lib/nitro/helper/table.rb +190 -27
- data/lib/nitro/{adapter → helper}/wee.rb +9 -3
- data/lib/nitro/render.rb +23 -17
- data/lib/nitro/scaffolding.rb +19 -2
- data/lib/nitro/server.rb +4 -8
- data/lib/nitro/server/runner.rb +28 -6
- data/lib/nitro/session.rb +7 -7
- data/lib/nitro_and_og.rb +2 -0
- data/proto/public/Makefile.acgi +40 -0
- data/proto/public/acgi.c +138 -0
- data/proto/public/js/builder.js +7 -3
- data/proto/public/js/controls.js +32 -12
- data/proto/public/js/dragdrop.js +4 -3
- data/proto/public/js/effects.js +111 -62
- data/proto/public/js/scriptaculous.js +10 -13
- data/proto/public/js/slider.js +88 -31
- data/proto/public/scaffold/new.xhtml +2 -2
- data/setup.rb +1585 -0
- data/src/part/admin.rb +6 -0
- data/src/part/admin/controller.rb +3 -3
- data/src/part/admin/skin.rb +1 -8
- data/test/nitro/adapter/tc_webrick.rb +2 -0
- data/test/nitro/tc_controller_aspect.rb +1 -1
- data/test/nitro/tc_element.rb +5 -6
- data/test/nitro/tc_table.rb +66 -0
- metadata +277 -271
- data/doc/architecture.txt +0 -2
- data/doc/bugs.txt +0 -15
- data/doc/tutorial.txt +0 -26
- data/install.rb +0 -37
- data/lib/nitro/compiler/script_generator.rb +0 -14
- data/lib/nitro/compiler/shaders.rb +0 -206
- data/lib/nitro/helper/prototype.rb +0 -49
- data/lib/nitro/scaffold/relations.rb +0 -54
data/Rakefile
CHANGED
@@ -32,7 +32,11 @@ $NITRO_NO_ENVIRONMENT = true
|
|
32
32
|
# Run the tests.
|
33
33
|
|
34
34
|
Rake::TestTask.new do |t|
|
35
|
+
cwd = File.expand_path(File.join(File.dirname(__FILE__) + '.'))
|
35
36
|
t.libs << 'test'
|
37
|
+
%w[glue nitro og].each do |dir|
|
38
|
+
t.libs << File.join(cwd, dir, 'lib')
|
39
|
+
end
|
36
40
|
t.test_files = FileList['test/**/tc*.rb']
|
37
41
|
t.verbose = true
|
38
42
|
end
|
@@ -69,7 +73,7 @@ spec = Gem::Specification.new do |s|
|
|
69
73
|
s.required_ruby_version = '= 1.8.3'
|
70
74
|
|
71
75
|
s.files = FileList[
|
72
|
-
'[A-Z]*', '
|
76
|
+
'[A-Z]*', 'setup.rb', '{bin,benchmark,examples,doc,proto,lib,test,vendor}/**/*'
|
73
77
|
].exclude("_darcs").exclude("_darcs/**/*").exclude('*.og').exclude('**/*.log').to_a
|
74
78
|
|
75
79
|
s.require_path = 'lib'
|
data/bin/nitrogen
CHANGED
@@ -1,62 +1,5 @@
|
|
1
|
-
|
1
|
+
puts <<-MSG
|
2
2
|
|
3
|
-
|
3
|
+
This script is deprecated. Use 'gen app my_app' instead.
|
4
4
|
|
5
|
-
|
6
|
-
require 'ftools'
|
7
|
-
|
8
|
-
require 'nano/dir/%3A%3Arecurse'
|
9
|
-
|
10
|
-
PROTO_DIR = File.join(Nitro::LibPath, '..', 'proto')
|
11
|
-
|
12
|
-
def usage
|
13
|
-
puts <<-USAGE
|
14
|
-
|
15
|
-
NAME
|
16
|
-
nitrogen - frontend for the Nitro generator mechanism.
|
17
|
-
|
18
|
-
SYNOPSIS
|
19
|
-
nitrogen app [full path]
|
20
|
-
|
21
|
-
DESCRIPTION
|
22
|
-
This is a frontend to the Nitro generator mechanism. Nitro
|
23
|
-
generators are used to 'bootstrap' development by creating
|
24
|
-
a standard directory structure and files for common tasks.
|
25
|
-
|
26
|
-
app: This will create some basic files to get you
|
27
|
-
started fleshing out your Nitro web application.
|
28
|
-
|
29
|
-
EXAMPLE
|
30
|
-
nitrogen app ~/my_application
|
31
|
-
|
32
|
-
This will generate a new Nitro application in the
|
33
|
-
~/my_application folder.
|
34
|
-
USAGE
|
35
|
-
exit 1
|
36
|
-
end
|
37
|
-
|
38
|
-
def run
|
39
|
-
case command = ARGV[0] || usage()
|
40
|
-
when 'app'
|
41
|
-
path = ARGV[1] || usage()
|
42
|
-
path = File.expand_path(path)
|
43
|
-
|
44
|
-
if File.exists?(path)
|
45
|
-
STDERR.puts "ERROR: Path #{path} already exists! Aborting!"
|
46
|
-
exit 1
|
47
|
-
end
|
48
|
-
|
49
|
-
FileUtils.cp_r(PROTO_DIR, path)
|
50
|
-
|
51
|
-
Dir.recurse(path) do |f|
|
52
|
-
FileUtils.rm_rf(f) if /\.svn$/ =~ f
|
53
|
-
end
|
54
|
-
|
55
|
-
else
|
56
|
-
usage()
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
run
|
61
|
-
|
62
|
-
# This script is based on Michael Neumann's Wee creator script.
|
5
|
+
MSG
|
data/doc/MIGRATION
CHANGED
@@ -10,6 +10,30 @@ For more help, send your question to the mailing list:
|
|
10
10
|
http://rubyforge.org/mailman/listinfo/nitro-general
|
11
11
|
|
12
12
|
|
13
|
+
== 0.27.0 <- 0.26.0
|
14
|
+
|
15
|
+
1. If you use a custom compiler pipeline, notice that the interface
|
16
|
+
has changes slightly:
|
17
|
+
|
18
|
+
def transform_template(template)
|
19
|
+
template = StaticInclude.transform(template)
|
20
|
+
template = Morphing.transform(template, self)
|
21
|
+
# template = LayoutCompiler.transform(template, self)
|
22
|
+
template = Elements.transform(template, self)
|
23
|
+
template = Markup.transform(template)
|
24
|
+
template = ScriptCompiler.transform(template, self)
|
25
|
+
template = Cleanup.transform(template)
|
26
|
+
template = Template.transform(template)
|
27
|
+
end
|
28
|
+
|
29
|
+
you need to pass 'self' for some compilers.
|
30
|
+
|
31
|
+
2. The helper script 'nitrogen' is removed. Use gen instead
|
32
|
+
|
33
|
+
3. There is a new system for prototype/scriptaculous integration.
|
34
|
+
Have a look at the flickr example for more details.
|
35
|
+
|
36
|
+
|
13
37
|
== 0.21.2 <- 0.21.0
|
14
38
|
|
15
39
|
1. The new 'nice' dispatching alogirthm is enabled by default. If
|
data/doc/RELEASES
CHANGED
@@ -1,3 +1,144 @@
|
|
1
|
+
== Version 0.27.0
|
2
|
+
|
3
|
+
Once again we have a great mix of cool new features, along
|
4
|
+
with bugfixes and a myriad of smaller improvements. Go and
|
5
|
+
download the most advanced Ruby Web/ORM Framework you can find.
|
6
|
+
|
7
|
+
Most notable changes:
|
8
|
+
|
9
|
+
* Added groundbreaking client side action/scripting support:
|
10
|
+
|
11
|
+
class FlickrDemo < Nitro::Controller
|
12
|
+
helper :javascript
|
13
|
+
|
14
|
+
class Client
|
15
|
+
# Actions defined here are executed as javescript in the
|
16
|
+
# browser.
|
17
|
+
def clear_me
|
18
|
+
hide :hide_me
|
19
|
+
end
|
20
|
+
|
21
|
+
def grab
|
22
|
+
ajax_upadate ...
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
in the template:
|
28
|
+
|
29
|
+
<div id="hide_me">...</div>
|
30
|
+
<a client="clear_me">clear</a>
|
31
|
+
|
32
|
+
the client element is converted to a javascript call that
|
33
|
+
executes the code in the client action. A domain specific
|
34
|
+
language is provided for the client action to implement stuff
|
35
|
+
like ajax async updates, scriptaculous visual fx and more.
|
36
|
+
|
37
|
+
* A collection of morphers to work along with client actions.
|
38
|
+
Here are some examples:
|
39
|
+
|
40
|
+
<!-- make a div draggable -->
|
41
|
+
<div id="hello" draggable="true">Drag me</div>
|
42
|
+
|
43
|
+
<!-- autocomplete a text field -->
|
44
|
+
<input type="text" name="tags" auto_complete="true" />
|
45
|
+
|
46
|
+
in the controller:
|
47
|
+
|
48
|
+
def tags_auto_complete
|
49
|
+
%{
|
50
|
+
<ul>
|
51
|
+
<li>navel</li>
|
52
|
+
<li>nitro</li>
|
53
|
+
<li>sexy</li>
|
54
|
+
</ul>
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
More stuff is coming in future versions.
|
59
|
+
|
60
|
+
* Greatly imporoved the Elements system. The ElementMixin module
|
61
|
+
is auto-injected if missing. Nitro automatically transforms
|
62
|
+
xhtml template files in the Element.template_root into
|
63
|
+
Element classes for even better separation of code and design.
|
64
|
+
A simple Rails style layout helper is implememnted on top of
|
65
|
+
the general and powerful Elements mechanism for people familiar
|
66
|
+
with Rails.
|
67
|
+
|
68
|
+
* New WebFile system. Uploading files and handling photos was
|
69
|
+
never easier:
|
70
|
+
|
71
|
+
class Photo
|
72
|
+
is Timestamped
|
73
|
+
is Taggable
|
74
|
+
property :title, String
|
75
|
+
property :file, WebFile, :magick => { :small => '64x64', :medium => '128x128' }
|
76
|
+
end
|
77
|
+
|
78
|
+
# the upload action
|
79
|
+
|
80
|
+
def upload
|
81
|
+
photo = Photo.assign(request)
|
82
|
+
photo.save
|
83
|
+
end
|
84
|
+
|
85
|
+
This saves the photo, and creates 2 thumbnails. You can easily
|
86
|
+
access the photo and thumbnails like this:
|
87
|
+
|
88
|
+
<img src="#{photo.file_medium_thumbnail}" />
|
89
|
+
<img src="#{photo.file_small_thumbnail}" />
|
90
|
+
|
91
|
+
ie obj.{propertyname}_#{thumbname}_thumbnail
|
92
|
+
|
93
|
+
* Og live collections support accumulation. Here is an example:
|
94
|
+
|
95
|
+
class Category
|
96
|
+
has_many :projects
|
97
|
+
end
|
98
|
+
|
99
|
+
class Project
|
100
|
+
has_many :clients
|
101
|
+
end
|
102
|
+
|
103
|
+
class Client
|
104
|
+
end
|
105
|
+
|
106
|
+
clients = category.projects.clients
|
107
|
+
|
108
|
+
# => returns all clients for this category!
|
109
|
+
|
110
|
+
* Improved TableHelper, better configurability, more skinnable,
|
111
|
+
sorting support and more.
|
112
|
+
|
113
|
+
* Added some intelligent auto-discovery features to minimize the
|
114
|
+
setup code. For example helpers are automatically loaded, and
|
115
|
+
the template_root is auto-discovered.
|
116
|
+
|
117
|
+
* Optimized the autoreloading system to only reload the dirty
|
118
|
+
files. In fact the new autoreloading system is so efficient
|
119
|
+
that it is enables by default even in live/production mode.
|
120
|
+
|
121
|
+
* Add Flickr, a great new example that shows off the new
|
122
|
+
javascript integration and AJAX features of Nitro.
|
123
|
+
|
124
|
+
* Added Gallery example to demonstrate the new WebFile
|
125
|
+
functionality.
|
126
|
+
|
127
|
+
* Improved the generated RDOC comments.
|
128
|
+
|
129
|
+
* Fixes in CGI adapter.
|
130
|
+
|
131
|
+
* Added evolution support to the KirbyBase adapter.
|
132
|
+
|
133
|
+
* Updated to scriptaculous 1.5.1
|
134
|
+
|
135
|
+
* Scaffolding - auto admin interface improvements.
|
136
|
+
|
137
|
+
* Added setup.rb for non-gem installation (experimental).
|
138
|
+
|
139
|
+
* Added ACGI adapter (experimental).
|
140
|
+
|
141
|
+
|
1
142
|
== Version 0.26.0
|
2
143
|
|
3
144
|
Another step closer to web programming nirvana. This release
|
data/doc/lhttpd.txt
CHANGED
data/lib/glue/magick.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
|
3
|
+
module Glue
|
4
|
+
|
5
|
+
# Magick transformation.
|
6
|
+
#--
|
7
|
+
# TODO: pass generalized RMagick command.
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Thumbnails
|
11
|
+
|
12
|
+
# Default thumbnail width.
|
13
|
+
|
14
|
+
setting :width, :default => 128, :doc => 'Default thumbnail width'
|
15
|
+
|
16
|
+
# Default thumbnail height.
|
17
|
+
|
18
|
+
setting :height, :default => 128, :doc => 'Default thumbnail height'
|
19
|
+
|
20
|
+
def self.generate_thumbnail(src, tname, geostring)
|
21
|
+
ext = File.extname(src)
|
22
|
+
dst = "#{File.join(File.dirname(src), File.basename(src, ext))}_#{tname}#{ext}"
|
23
|
+
|
24
|
+
thumb = Magick::Image.read(File.join(Nitro::Server.public_root, src)).first
|
25
|
+
thumb.change_geometry!(geostring) do |cols, rows, thumb|
|
26
|
+
thumb.resize!(cols, rows)
|
27
|
+
end
|
28
|
+
thumb.write(File.join(Nitro::Server.public_root, dst))
|
29
|
+
|
30
|
+
return dst
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# * George Moschovitis <gm@navel.gr>
|
38
|
+
# * Michael Fellinger <m.fellinger@gmail.com>
|
data/lib/glue/webfile.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require 'mega/inheritor'
|
4
|
+
|
5
|
+
module Glue
|
6
|
+
|
7
|
+
# A Web File.
|
8
|
+
|
9
|
+
class WebFile
|
10
|
+
|
11
|
+
# The directory where uploaded files are stored. Typically
|
12
|
+
# this is a symlink to another directory outside of the
|
13
|
+
# webapp dir for easier updates.
|
14
|
+
|
15
|
+
setting :upload_root, :default => 'upload', :doc => 'The directory where upload files are stored'
|
16
|
+
|
17
|
+
# Modify the base class when this class is included as
|
18
|
+
# property
|
19
|
+
|
20
|
+
def self.included_as_property(base, names, options)
|
21
|
+
if thumbnails = (options[:thumbnail] || options[:thumbnails] || options[:magick]) or self.name == 'WebImage'
|
22
|
+
require 'glue/thumbnails'
|
23
|
+
base.send :include, Thumbnails
|
24
|
+
thumbnails = { :small => :thumbnails } if thumbnails.is_a?(String)
|
25
|
+
end
|
26
|
+
|
27
|
+
for name in names
|
28
|
+
base.module_eval do
|
29
|
+
# The 'web' path to the file (relative to the public
|
30
|
+
# root directory. Uses the original property name
|
31
|
+
# or the #{name}_path alias.
|
32
|
+
|
33
|
+
property name.to_sym, String
|
34
|
+
alias_method "#{name}_path".to_sym, name.to_sym
|
35
|
+
|
36
|
+
# The file size.
|
37
|
+
|
38
|
+
property "#{name}_size".to_sym, Fixnum
|
39
|
+
|
40
|
+
# The mime type
|
41
|
+
|
42
|
+
property "#{name}_mime_type".to_sym, String
|
43
|
+
|
44
|
+
# Assignment callbacks.
|
45
|
+
#--
|
46
|
+
# gmosx, FIXME: this is a hack!! better implementation
|
47
|
+
# is needed (generalized property assigners).
|
48
|
+
|
49
|
+
inheritor(:assign_callbacks, [], :merge) unless @assign_callbacks
|
50
|
+
end
|
51
|
+
|
52
|
+
if thumbnails
|
53
|
+
for tname in thumbnails.keys
|
54
|
+
base.module_eval do
|
55
|
+
property "#{name}_#{tname}_thumbnail".to_sym, String
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
code = %{
|
61
|
+
def #{name}_real_path
|
62
|
+
File.join(Nitro::Server.public_root, @#{name})
|
63
|
+
end
|
64
|
+
|
65
|
+
def #{name}_from_request(request)
|
66
|
+
param = request['#{name}']
|
67
|
+
}
|
68
|
+
|
69
|
+
if base.respond_to? :webfile_path
|
70
|
+
code << %{
|
71
|
+
path = #{base}.webfile_path(request, '#{name}')
|
72
|
+
}
|
73
|
+
else
|
74
|
+
code << %{
|
75
|
+
path = File.join(WebFile.upload_root, param.original_filename)
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
code << %{
|
80
|
+
@#{name} = WebFile.sanitize(path)
|
81
|
+
@#{name}_size = param.size
|
82
|
+
|
83
|
+
real_path = #{name}_real_path
|
84
|
+
FileUtils.mkdir_p(File.dirname(real_path))
|
85
|
+
if param.path
|
86
|
+
FileUtils.cp(param.path, real_path)
|
87
|
+
else
|
88
|
+
# gmosx FIXME: this is a hack!!
|
89
|
+
param.rewind
|
90
|
+
File.open(real_path, 'wb') { |f| f << param.read }
|
91
|
+
end
|
92
|
+
FileUtils.chmod(0777, real_path)
|
93
|
+
}
|
94
|
+
|
95
|
+
if thumbnails
|
96
|
+
for tname, geostring in thumbnails
|
97
|
+
code << %{
|
98
|
+
@#{name}_#{tname}_thumbnail = Thumbnails.generate_thumbnail(path, '#{tname}', '#{geostring}')
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
code << %{
|
104
|
+
end
|
105
|
+
|
106
|
+
def delete_#{name}
|
107
|
+
FileUtils.rm(#{name}_real_path)
|
108
|
+
end
|
109
|
+
|
110
|
+
assign_callbacks! << proc { |obj, values, options|
|
111
|
+
obj.#{name}_from_request(values)
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
base.module_eval(code)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Sanitize a filename.
|
120
|
+
#--
|
121
|
+
# TODO: implement me!
|
122
|
+
#++
|
123
|
+
|
124
|
+
def self.sanitize(filename)
|
125
|
+
filename
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
# An alias, implies thumbnailing.
|
131
|
+
|
132
|
+
WebImage = WebFile
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
# * George Moschovitis <gm@navel.gr>
|
137
|
+
# * Michael Fellinger <m.fellinger@gmail.com>
|