amrita2 1.9.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +112 -0
- data/init.rb +6 -0
- data/lib/amrita2/gettext.rb +116 -0
- data/lib/amrita2/macro.rb +153 -0
- data/lib/amrita2/rails_bridge.rb +172 -26
- data/lib/amrita2/template.rb +2634 -234
- data/lib/amrita2/testsupport.rb +171 -0
- data/lib/amrita2/version.rb +3 -3
- data/lib/amrita2.rb +1 -0
- data/sample/depot/app/controllers/admin_controller.rb +59 -0
- data/sample/depot/app/controllers/application.rb +20 -0
- data/sample/depot/app/controllers/info_controller.rb +19 -0
- data/sample/depot/app/controllers/login_controller.rb +85 -0
- data/sample/depot/app/controllers/store_controller.rb +68 -0
- data/sample/depot/app/helpers/admin_helper.rb +7 -0
- data/sample/depot/app/helpers/application_helper.rb +10 -0
- data/sample/depot/app/helpers/ar_form.rb +169 -0
- data/sample/depot/app/helpers/form_tag.rb +24 -0
- data/sample/depot/app/helpers/info_helper.rb +7 -0
- data/sample/depot/app/helpers/standard_form.rb +73 -0
- data/sample/depot/app/helpers/store_helper.rb +14 -0
- data/sample/depot/app/models/cart.rb +36 -0
- data/sample/depot/app/models/cart_item.rb +26 -0
- data/sample/depot/app/models/line_item.rb +34 -0
- data/sample/depot/app/models/order.rb +57 -0
- data/sample/depot/app/models/product.rb +41 -0
- data/sample/depot/app/models/user.rb +83 -0
- data/sample/depot/config/boot.rb +49 -0
- data/sample/depot/config/environment.rb +83 -0
- data/sample/depot/config/environments/development.rb +24 -0
- data/sample/depot/config/environments/production.rb +24 -0
- data/sample/depot/config/environments/test.rb +24 -0
- data/sample/depot/config/routes.rb +10 -0
- data/sample/depot/db/migrate/001_create_products.rb +18 -0
- data/sample/depot/db/migrate/002_add_price.rb +14 -0
- data/sample/depot/db/migrate/003_add_test_data.rb +68 -0
- data/sample/depot/db/migrate/004_add_sessions.rb +20 -0
- data/sample/depot/db/migrate/005_create_orders.rb +21 -0
- data/sample/depot/db/migrate/006_create_line_items.rb +27 -0
- data/sample/depot/db/migrate/007_create_users.rb +18 -0
- data/sample/depot/db/schema.rb +45 -0
- data/sample/depot/public/dispatch.rb +15 -0
- data/sample/depot/test/functional/admin_controller_test.rb +54 -0
- data/sample/depot/test/functional/info_controller_test.rb +23 -0
- data/sample/depot/test/functional/login_controller_test.rb +74 -0
- data/sample/depot/test/functional/store_controller_test.rb +57 -0
- data/sample/depot/test/integration/dsl_user_stories_test.rb +126 -0
- data/sample/depot/test/integration/user_stories_test.rb +70 -0
- data/sample/depot/test/performance/order_speed_test.rb +58 -0
- data/sample/depot/test/test_helper.rb +16 -0
- data/sample/depot/test/unit/cart_test.rb +39 -0
- data/sample/depot/test/unit/cart_test1.rb +31 -0
- data/sample/depot/test/unit/line_item_test.rb +15 -0
- data/sample/depot/test/unit/order_test.rb +15 -0
- data/sample/depot/test/unit/product_test.rb +98 -0
- data/sample/depot/vendor/plugins/amrita2/init.rb +6 -0
- data/sample/hello/hello.rb +22 -0
- data/sample/login_engine/app/controllers/application.rb +16 -0
- data/sample/login_engine/app/controllers/user_controller.rb +265 -0
- data/sample/login_engine/app/helpers/application_helper.rb +3 -0
- data/sample/login_engine/app/helpers/form_tag.rb +16 -0
- data/sample/login_engine/app/helpers/two_columns.rb +24 -0
- data/sample/login_engine/app/helpers/two_columns_form.rb +47 -0
- data/sample/login_engine/app/helpers/user_helper.rb +88 -0
- data/sample/login_engine/app/models/user.rb +7 -0
- data/sample/login_engine/app/models/user_notify.rb +75 -0
- data/sample/login_engine/config/boot.rb +45 -0
- data/sample/login_engine/config/environment.rb +140 -0
- data/sample/login_engine/config/environments/development.rb +21 -0
- data/sample/login_engine/config/environments/production.rb +18 -0
- data/sample/login_engine/config/environments/test.rb +19 -0
- data/sample/login_engine/config/routes.rb +23 -0
- data/sample/login_engine/db/migrate/001_create_users.rb +25 -0
- data/sample/login_engine/db/schema.rb +25 -0
- data/sample/login_engine/lib/config.rb +113 -0
- data/sample/login_engine/lib/hpricot_test_extension.rb +80 -0
- data/sample/login_engine/lib/login_engine/authenticated_system.rb +113 -0
- data/sample/login_engine/lib/login_engine/authenticated_user.rb +155 -0
- data/sample/login_engine/lib/login_engine.rb +62 -0
- data/sample/login_engine/public/dispatch.rb +10 -0
- data/sample/login_engine/test/functional/amrita2_test.rb +267 -0
- data/sample/login_engine/test/functional/user_controller_test.rb +544 -0
- data/sample/login_engine/test/mocks/mail.rb +14 -0
- data/sample/login_engine/test/mocks/time.rb +19 -0
- data/sample/login_engine/test/test_helper.rb +31 -0
- data/sample/login_engine/test/unit/user_test.rb +116 -0
- data/sample/login_engine/vendor/plugins/amrita2/init.rb +6 -0
- data/specs/attribute.rb +201 -0
- data/specs/datatypes.rb +231 -0
- data/specs/dictionary.rb +68 -0
- data/specs/erb_cdata.rb +187 -0
- data/specs/filters.rb +513 -0
- data/specs/gettext/erb_gettext.rb +42 -0
- data/specs/gettext/gettext_util.rb +65 -0
- data/specs/gettext/static_text.rb +103 -0
- data/specs/impl/code_generator.rb +87 -0
- data/specs/impl/dynamic_element.rb +92 -0
- data/specs/impl/hash_delegator.rb +57 -0
- data/specs/impl/parse_opt.rb +34 -0
- data/specs/impl/preprocess.rb +823 -0
- data/specs/impl/testsupport.rb +89 -0
- data/specs/inlineruby.rb +429 -0
- data/specs/intro.rb +654 -0
- data/specs/loop.rb +203 -0
- data/specs/macro.rb +532 -0
- data/specs/sample.rb +34 -0
- data/specs/sanitize.rb +110 -0
- data/specs/template.rb +189 -0
- data/specs/trace.rb +97 -0
- metadata +138 -19
- data/lib/amrita2/core.rb +0 -1897
- data/lib/amrita2/rd.rb +0 -314
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
require 'rexml/element'
|
|
2
|
+
require 'diff/lcs'
|
|
3
|
+
require 'diff/lcs/hunk'
|
|
4
|
+
require 'hpricot'
|
|
5
|
+
|
|
6
|
+
module Hpricot # :nodoc: all
|
|
7
|
+
class STag < BaseEle
|
|
8
|
+
# original
|
|
9
|
+
# def attributes_as_html
|
|
10
|
+
# if @attributes
|
|
11
|
+
# @attributes.map do |aname, aval|
|
|
12
|
+
# " #{aname}" +
|
|
13
|
+
# (aval ? "=#{html_quote(aval)}" : "")
|
|
14
|
+
# end.join
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
undef attributes_as_html
|
|
19
|
+
def attributes_as_html
|
|
20
|
+
if @raw_attributes
|
|
21
|
+
@raw_attributes.keys.sort.map do |aname|
|
|
22
|
+
aval = @raw_attributes[aname]
|
|
23
|
+
" #{aname}" +
|
|
24
|
+
(aval ? "=#{html_quote(aval)}" : "")
|
|
25
|
+
end.join
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module REXML # :nodoc: all
|
|
32
|
+
class Attributes < Hash
|
|
33
|
+
# redefine each_attribute for unified order
|
|
34
|
+
def each_attribute
|
|
35
|
+
keys.sort.each do |key|
|
|
36
|
+
val = get_attribute(key)
|
|
37
|
+
if val.kind_of? Attribute
|
|
38
|
+
yield val
|
|
39
|
+
else
|
|
40
|
+
val.each_value { |atr| yield atr }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
module Amrita2
|
|
50
|
+
module TestSupport # :nodoc: all
|
|
51
|
+
def assert_equal_as_xml(expected, actual)
|
|
52
|
+
#assert_equal(expected.as_normalized_xml, actual.as_normalized_xml)
|
|
53
|
+
assert_equal(normalize(expected), normalize(actual))
|
|
54
|
+
rescue REXML::ParseException
|
|
55
|
+
puts expected
|
|
56
|
+
puts actual
|
|
57
|
+
puts msg = diff_as_string(expected, actual)
|
|
58
|
+
raise
|
|
59
|
+
rescue
|
|
60
|
+
msg = diff_as_string(normalize(expected),normalize(actual))
|
|
61
|
+
msg.gsub!('?', ' ')
|
|
62
|
+
msg = build_message "not equal as xml ", msg
|
|
63
|
+
raise Test::Unit::AssertionFailedError.new(msg)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# copied from rspec spec/expectations/differs/default.rb
|
|
67
|
+
def diff_as_string(data_old, data_new)
|
|
68
|
+
context_lines = 3
|
|
69
|
+
#format = :context
|
|
70
|
+
format = :unified
|
|
71
|
+
data_old = data_old.split(/\n/).map! { |e| e.chomp }
|
|
72
|
+
data_new = data_new.split(/\n/).map! { |e| e.chomp }
|
|
73
|
+
output = ""
|
|
74
|
+
diffs = Diff::LCS.diff(data_old, data_new)
|
|
75
|
+
return output if diffs.empty?
|
|
76
|
+
oldhunk = hunk = nil
|
|
77
|
+
file_length_difference = 0
|
|
78
|
+
diffs.each do |piece|
|
|
79
|
+
begin
|
|
80
|
+
hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines,
|
|
81
|
+
file_length_difference)
|
|
82
|
+
file_length_difference = hunk.file_length_difference
|
|
83
|
+
next unless oldhunk
|
|
84
|
+
# Hunks may overlap, which is why we need to be careful when our
|
|
85
|
+
# diff includes lines of context. Otherwise, we might print
|
|
86
|
+
# redundant lines.
|
|
87
|
+
if (context_lines > 0) and hunk.overlaps?(oldhunk)
|
|
88
|
+
hunk.unshift(oldhunk)
|
|
89
|
+
else
|
|
90
|
+
output << oldhunk.diff(format)
|
|
91
|
+
end
|
|
92
|
+
ensure
|
|
93
|
+
oldhunk = hunk
|
|
94
|
+
output << "\n"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
#Handle the last remaining hunk
|
|
98
|
+
output << oldhunk.diff(format) << "\n"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def normalize(x)
|
|
102
|
+
case x
|
|
103
|
+
when String
|
|
104
|
+
normalize(Hpricot.make(x))
|
|
105
|
+
when Hpricot::Text
|
|
106
|
+
x.to_s.strip.gsub(/\s+/, " ")
|
|
107
|
+
when Hpricot::Elem
|
|
108
|
+
if x.empty?
|
|
109
|
+
x.stag.output("", :style => :empty)
|
|
110
|
+
else
|
|
111
|
+
[
|
|
112
|
+
x.stag.output(""),
|
|
113
|
+
normalize(x.children),
|
|
114
|
+
x.etag ? x.etag.output("", :style => :end) : ''
|
|
115
|
+
].flatten.join("\n").strip
|
|
116
|
+
end
|
|
117
|
+
when Array
|
|
118
|
+
x.collect { |e| normalize(e) }.join("\n").strip.gsub(/\>(\n\s)+/, ">\n")
|
|
119
|
+
when Hpricot::BogusETag
|
|
120
|
+
x.to_s
|
|
121
|
+
else
|
|
122
|
+
x.to_s
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def should_be_samexml_as(expected)
|
|
127
|
+
normalize(self).should == normalize(expected)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
class Template
|
|
132
|
+
def test_with(value, b=nil)
|
|
133
|
+
set_trace(log = "")
|
|
134
|
+
result = render_with(value, b)
|
|
135
|
+
yield(result.dup)
|
|
136
|
+
rescue StandardError
|
|
137
|
+
p $!, value, result
|
|
138
|
+
puts log
|
|
139
|
+
raise
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
class Object
|
|
145
|
+
include Amrita2::TestSupport
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if Object::const_defined?(:ActionView)
|
|
149
|
+
|
|
150
|
+
class ActionView::Base # :nodoc: all
|
|
151
|
+
def self.unregister_template_handler(extension)
|
|
152
|
+
self.cache_template_extensions = false
|
|
153
|
+
@@template_handlers.delete(extension)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
module Amrita2
|
|
158
|
+
module RailsTestHelper # :nodoc: all
|
|
159
|
+
def compare_result
|
|
160
|
+
ActionView::Base.register_template_handler "a2html", Amrita2View::Base
|
|
161
|
+
amrita2_result = yield
|
|
162
|
+
ActionView::Base.unregister_template_handler "a2html"
|
|
163
|
+
erb_result = yield
|
|
164
|
+
assert_equal_as_xml(erb_result, amrita2_result)
|
|
165
|
+
#assert_dom_equal(amrita2_result, erb_result)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
|
data/lib/amrita2/version.rb
CHANGED
data/lib/amrita2.rb
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
|
|
7
|
+
class AdminController < ApplicationController
|
|
8
|
+
|
|
9
|
+
before_filter :authorize
|
|
10
|
+
|
|
11
|
+
# ....
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def index
|
|
15
|
+
list
|
|
16
|
+
render :action => 'list'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def list
|
|
20
|
+
@product_pages, @products = paginate :products, :per_page => 10
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def show
|
|
24
|
+
@product = Product.find(params[:id])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def new
|
|
28
|
+
@product = Product.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create
|
|
32
|
+
@product = Product.new(params[:product])
|
|
33
|
+
if @product.save
|
|
34
|
+
flash[:notice] = 'Product was successfully created.'
|
|
35
|
+
redirect_to :action => 'list'
|
|
36
|
+
else
|
|
37
|
+
render :action => 'new'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def edit
|
|
42
|
+
@product = Product.find(params[:id])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def update
|
|
46
|
+
@product = Product.find(params[:id])
|
|
47
|
+
if @product.update_attributes(params[:product])
|
|
48
|
+
flash[:notice] = 'Product was successfully updated.'
|
|
49
|
+
redirect_to :action => 'show', :id => @product
|
|
50
|
+
else
|
|
51
|
+
render :action => 'edit'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def destroy
|
|
56
|
+
Product.find(params[:id]).destroy
|
|
57
|
+
redirect_to :action => 'list'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
class ApplicationController < ActionController::Base
|
|
7
|
+
|
|
8
|
+
# Pick a unique cookie name to distinguish our session data from others'
|
|
9
|
+
session :session_key => '_depot_session_id'
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def authorize
|
|
14
|
+
unless User.find_by_id(session[:user_id])
|
|
15
|
+
flash[:notice] = "Please log in"
|
|
16
|
+
redirect_to(:controller => "login", :action => "login")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
class InfoController < ApplicationController
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def who_bought
|
|
10
|
+
@product = Product.find(params[:id])
|
|
11
|
+
@orders = @product.orders
|
|
12
|
+
respond_to do |format|
|
|
13
|
+
format.html
|
|
14
|
+
format.xml
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LoginController < ApplicationController
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
before_filter :authorize, :except => :login
|
|
13
|
+
|
|
14
|
+
# . .
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
layout "admin"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def index
|
|
23
|
+
@total_orders = Order.count
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# just display the form and wait for user to
|
|
28
|
+
# enter a name and password
|
|
29
|
+
|
|
30
|
+
def login
|
|
31
|
+
session[:user_id] = nil
|
|
32
|
+
if request.post?
|
|
33
|
+
user = User.authenticate(params[:name], params[:password])
|
|
34
|
+
if user
|
|
35
|
+
session[:user_id] = user.id
|
|
36
|
+
redirect_to(:action => "index")
|
|
37
|
+
else
|
|
38
|
+
flash.now[:notice] = "Invalid user/password combination"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def add_user
|
|
46
|
+
@user = User.new(params[:user])
|
|
47
|
+
if request.post? and @user.save
|
|
48
|
+
flash.now[:notice] = "User #{@user.name} created"
|
|
49
|
+
@user = User.new
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# . . .
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def delete_user
|
|
58
|
+
if request.post?
|
|
59
|
+
user = User.find(params[:id])
|
|
60
|
+
begin
|
|
61
|
+
user.destroy
|
|
62
|
+
flash[:notice] = "User #{user.name} deleted"
|
|
63
|
+
rescue Exception => e
|
|
64
|
+
flash[:notice] = e.message
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
redirect_to(:action => :list_users)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def list_users
|
|
73
|
+
@all_users = User.find(:all)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def logout
|
|
79
|
+
session[:user_id] = nil
|
|
80
|
+
flash[:notice] = "Logged out"
|
|
81
|
+
redirect_to(:action => "login")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
class StoreController < ApplicationController
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
before_filter :find_cart, :except => :empty_cart
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def index
|
|
13
|
+
@products = Product.find_products_for_sale
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def add_to_cart
|
|
18
|
+
begin
|
|
19
|
+
product = Product.find(params[:id])
|
|
20
|
+
rescue ActiveRecord::RecordNotFound
|
|
21
|
+
logger.error("Attempt to access invalid product #{params[:id]}")
|
|
22
|
+
redirect_to_index("Invalid product")
|
|
23
|
+
else
|
|
24
|
+
@current_item = @cart.add_product(product)
|
|
25
|
+
redirect_to_index unless request.xhr?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def empty_cart
|
|
30
|
+
session[:cart] = nil
|
|
31
|
+
redirect_to_index
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def checkout
|
|
36
|
+
if @cart.items.empty?
|
|
37
|
+
redirect_to_index("Your cart is empty")
|
|
38
|
+
else
|
|
39
|
+
@order = Order.new
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def save_order
|
|
46
|
+
@order = Order.new(params[:order])
|
|
47
|
+
@order.add_line_items_from_cart(@cart)
|
|
48
|
+
if @order.save
|
|
49
|
+
session[:cart] = nil
|
|
50
|
+
redirect_to_index("Thank you for your order")
|
|
51
|
+
else
|
|
52
|
+
render :action => :checkout
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def redirect_to_index(msg = nil)
|
|
59
|
+
flash[:notice] = msg if msg
|
|
60
|
+
redirect_to :action => :index
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def find_cart
|
|
65
|
+
@cart = (session[:cart] ||= Cart.new)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Agile Web Development with Rails, 2nd Ed."
|
|
3
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
4
|
+
# Visit http://www.pragmaticprogrammer.com/titles/rails2 for more book information.
|
|
5
|
+
#---
|
|
6
|
+
# Methods added to this helper will be available to all templates in the application.
|
|
7
|
+
module ApplicationHelper
|
|
8
|
+
module NumberFormatHelper
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require 'amrita2/macro'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module Amrita2View
|
|
5
|
+
class InputField < Amrita2::Macro::Base
|
|
6
|
+
include Amrita2
|
|
7
|
+
include Amrita2::Util
|
|
8
|
+
|
|
9
|
+
attr_accessor :set_value
|
|
10
|
+
|
|
11
|
+
def get_macro_template
|
|
12
|
+
%[<input macro:filter="Attr" />]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def macro_data(element)
|
|
16
|
+
attrs = element.as_amrita_dictionary
|
|
17
|
+
prefix = attrs.delete(:prefix).to_s.split
|
|
18
|
+
input_id = attrs.delete(:id)
|
|
19
|
+
if attrs.delete(:set_value)
|
|
20
|
+
self.set_value = true
|
|
21
|
+
end
|
|
22
|
+
default_attrs.merge(attrs).merge( {
|
|
23
|
+
:id => get_id(prefix, input_id),
|
|
24
|
+
:name => get_name(prefix, input_id),
|
|
25
|
+
:target_filter => target_filter(input_id)
|
|
26
|
+
} )
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def target_filter(input_id)
|
|
32
|
+
if set_value
|
|
33
|
+
"Attr[:value=>#{input_id.intern.inspect}]"
|
|
34
|
+
else
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def get_id(prefix, name)
|
|
40
|
+
(prefix + [name]).join("_")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_name(prefix, name)
|
|
44
|
+
case prefix.size
|
|
45
|
+
when 0
|
|
46
|
+
name
|
|
47
|
+
when 1
|
|
48
|
+
"#{prefix.first}[#{name}]"
|
|
49
|
+
else
|
|
50
|
+
prefix.first +
|
|
51
|
+
prefix[1..-1].collect do |pre|
|
|
52
|
+
"[#{pre}]"
|
|
53
|
+
end.join('') +
|
|
54
|
+
"[#{name}]"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class TextField < InputField
|
|
60
|
+
|
|
61
|
+
Option = {
|
|
62
|
+
:tag => "ar:text_field",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def default_attrs
|
|
66
|
+
{
|
|
67
|
+
:type => 'text',
|
|
68
|
+
:size => 30
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class TextArea < InputField
|
|
74
|
+
|
|
75
|
+
Option = {
|
|
76
|
+
:tag => "ar:textarea",
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def get_macro_template
|
|
80
|
+
%[<textarea macro:filter="Attr" />]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def default_attrs
|
|
84
|
+
{
|
|
85
|
+
:rows => 20,
|
|
86
|
+
:cols => 40,
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def target_filter(input_id)
|
|
91
|
+
if set_value
|
|
92
|
+
"Attr[:body=>#{input_id.intern.inspect}]"
|
|
93
|
+
else
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class ARForm < Amrita2::Macro::Base
|
|
100
|
+
include Amrita2
|
|
101
|
+
TemplateText = <<-'END'
|
|
102
|
+
<<:|Amrita2View::ARFormFilter[{:prefix => :uuuu}] <
|
|
103
|
+
<<:contents>>
|
|
104
|
+
END
|
|
105
|
+
|
|
106
|
+
Option = {
|
|
107
|
+
:tag=>"ar:form",
|
|
108
|
+
:use_contents=>:contents
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
FieldMacros = []
|
|
112
|
+
|
|
113
|
+
def self.add_macro(m)
|
|
114
|
+
FieldMacros << m
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
add_macro TextField
|
|
118
|
+
add_macro TextArea
|
|
119
|
+
|
|
120
|
+
def initialize
|
|
121
|
+
@filter = Amrita2::Filters::MacroFilter.new(*FieldMacros)
|
|
122
|
+
super
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def process(de, element)
|
|
126
|
+
@filter.macros.each do |m|
|
|
127
|
+
m.set_value = element.get_attribute("set_value")
|
|
128
|
+
end
|
|
129
|
+
element = process_prefix(element, [])
|
|
130
|
+
@filter.filter_element(de, element).to_s
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def process_prefix(e, prefix)
|
|
136
|
+
if e.name == "ar:form"
|
|
137
|
+
prefix = prefix + [e.get_attribute("prefix")]
|
|
138
|
+
e.name = "_"
|
|
139
|
+
e.delete_attribute("prefix")
|
|
140
|
+
e.delete_attribute("set_value")
|
|
141
|
+
elsif @filter.macros.any? { |m| m.get_element_name == e.name }
|
|
142
|
+
e.set_attribute("prefix", prefix.join(" ")) unless e.get_attribute("prefix")
|
|
143
|
+
end
|
|
144
|
+
e.children.each do |c|
|
|
145
|
+
process_prefix(c, prefix) if c.kind_of?(Hpricot::Elem)
|
|
146
|
+
end
|
|
147
|
+
e
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class FormTag < Amrita2::Macro::Base
|
|
152
|
+
TemplateText = <<-END
|
|
153
|
+
<%
|
|
154
|
+
action = $_[:action]
|
|
155
|
+
method = $_[:method]
|
|
156
|
+
%>
|
|
157
|
+
<%%= form_tag({:action=><%= action.inspect%>}, {:method=><%= method.inspect %>}) %%>
|
|
158
|
+
<span macro:src='contents' />
|
|
159
|
+
<%%= "</form>" %%>
|
|
160
|
+
END
|
|
161
|
+
|
|
162
|
+
Option = {
|
|
163
|
+
:tag => :form_tag,
|
|
164
|
+
:use_contents => :contents
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
ARForm = Amrita2View::ARForm
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
class FormTag < Amrita2::Macro::Base
|
|
3
|
+
TemplateText = <<-END_OF_TEMPLATE
|
|
4
|
+
<%%= form_tag(<%= $_[:url].inspect %>) %%>
|
|
5
|
+
<<:contents>>
|
|
6
|
+
<%%= '</form>' %%>
|
|
7
|
+
|
|
8
|
+
END_OF_TEMPLATE
|
|
9
|
+
|
|
10
|
+
def macro_data(element)
|
|
11
|
+
root = element.as_amrita_dictionary
|
|
12
|
+
url = element.search("url").first
|
|
13
|
+
contents = element.children.find_all do |c|
|
|
14
|
+
c != url
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
ret = {
|
|
18
|
+
:url => url ? url.as_amrita_dictionary : {},
|
|
19
|
+
:contents => Amrita2::SanitizedString[contents]
|
|
20
|
+
}
|
|
21
|
+
ret
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|