hobo 0.5.3 → 0.6
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/bin/hobo +18 -4
- data/hobo_files/plugin/CHANGES.txt +511 -0
- data/hobo_files/plugin/README +8 -3
- data/hobo_files/plugin/Rakefile +81 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +4 -4
- data/hobo_files/plugin/generators/hobo/templates/guest.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +16 -22
- data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +6 -5
- data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +237 -0
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +9 -0
- data/hobo_files/plugin/generators/hobo_model/USAGE +2 -3
- data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +1 -6
- data/hobo_files/plugin/generators/hobo_model/templates/model.rb +10 -4
- data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +7 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_base.css +68 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.css +93 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +11 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/plus.png +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +24 -14
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +28 -44
- data/hobo_files/plugin/generators/hobo_user_model/USAGE +2 -12
- data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +0 -6
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -1
- data/hobo_files/plugin/init.rb +6 -2
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +23 -12
- data/hobo_files/plugin/lib/extensions.rb +134 -40
- data/hobo_files/plugin/lib/extensions/test_case.rb +0 -1
- data/hobo_files/plugin/lib/hobo.rb +77 -46
- data/hobo_files/plugin/lib/hobo/authenticated_user.rb +24 -2
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +2 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +35 -12
- data/hobo_files/plugin/lib/hobo/define_tags.rb +4 -4
- data/hobo_files/plugin/lib/hobo/dryml.rb +33 -51
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +47 -34
- data/hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb +37 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +27 -5
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +545 -302
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +305 -135
- data/hobo_files/plugin/lib/hobo/email_address.rb +5 -0
- data/hobo_files/plugin/lib/hobo/field_spec.rb +66 -0
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +325 -0
- data/hobo_files/plugin/lib/hobo/html_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +13 -1
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +3 -1
- data/hobo_files/plugin/lib/hobo/model.rb +185 -66
- data/hobo_files/plugin/lib/hobo/model_controller.rb +56 -49
- data/hobo_files/plugin/lib/hobo/password_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/plugins.rb +75 -0
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +98 -0
- data/hobo_files/plugin/lib/hobo/static_tags +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +11 -1
- data/hobo_files/plugin/lib/hobo/undefined.rb +1 -1
- data/hobo_files/plugin/lib/rexml.rb +166 -75
- data/hobo_files/plugin/spec/fixtures/users.yml +9 -0
- data/hobo_files/plugin/spec/spec.opts +6 -0
- data/hobo_files/plugin/spec/spec_helper.rb +28 -0
- data/hobo_files/plugin/spec/unit/hobo/dryml/template_spec.rb +650 -0
- data/hobo_files/plugin/tags/core.dryml +58 -4
- data/hobo_files/plugin/tags/rapid.dryml +289 -135
- data/hobo_files/plugin/tags/rapid_document_tags.dryml +49 -0
- data/hobo_files/plugin/tags/rapid_editing.dryml +92 -69
- data/hobo_files/plugin/tags/rapid_forms.dryml +242 -0
- data/hobo_files/plugin/tags/rapid_navigation.dryml +65 -65
- data/hobo_files/plugin/tags/rapid_pages.dryml +197 -124
- data/hobo_files/plugin/tags/rapid_support.dryml +23 -0
- metadata +29 -22
- data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +0 -13
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +0 -11
- data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +0 -15
- data/hobo_files/plugin/lib/hobo/HtmlString +0 -3
- data/hobo_files/plugin/lib/hobo/controller_helpers.rb +0 -135
- data/hobo_files/plugin/lib/hobo/core.rb +0 -475
- data/hobo_files/plugin/lib/hobo/rapid.rb +0 -447
- data/hobo_files/plugin/test/hobo_dryml_template_test.rb +0 -7
- data/hobo_files/plugin/test/hobo_test.rb +0 -7
|
@@ -4,10 +4,22 @@ module Hobo
|
|
|
4
4
|
|
|
5
5
|
module AuthenticatedUser
|
|
6
6
|
|
|
7
|
+
# Extend the base class with AuthenticatedUser functionality
|
|
8
|
+
# This includes:
|
|
9
|
+
# - plaintext password during login and encrypted password in the database
|
|
10
|
+
# - plaintext password validation
|
|
11
|
+
# - login token for rembering a login during multiple browser sessions
|
|
7
12
|
def self.included(base)
|
|
8
13
|
base.extend(ClassMethods)
|
|
9
14
|
|
|
10
15
|
base.class_eval do
|
|
16
|
+
fields do
|
|
17
|
+
crypted_password :string, :limit => 40
|
|
18
|
+
salt :string, :limit => 40
|
|
19
|
+
remember_token :string
|
|
20
|
+
remember_token_expires_at :datetime
|
|
21
|
+
end
|
|
22
|
+
|
|
11
23
|
# Virtual attribute for the unencrypted password
|
|
12
24
|
attr_accessor :password
|
|
13
25
|
|
|
@@ -25,8 +37,10 @@ module Hobo
|
|
|
25
37
|
end
|
|
26
38
|
end
|
|
27
39
|
|
|
40
|
+
# Additional classmethods for AuthenticatedUser
|
|
28
41
|
module ClassMethods
|
|
29
42
|
|
|
43
|
+
# Validation of the plaintext password
|
|
30
44
|
def password_validations
|
|
31
45
|
validates_length_of :password, :within => 4..40, :if => :password_required?
|
|
32
46
|
end
|
|
@@ -49,7 +63,11 @@ module Hobo
|
|
|
49
63
|
u = find(:first, :conditions => ["#{@login_attr} = ?", login]) # need to get the salt
|
|
50
64
|
|
|
51
65
|
if u && u.authenticated?(password)
|
|
52
|
-
u.last_login_at
|
|
66
|
+
if u.respond_to?(:last_login_at) || u.respond_to?(:logins_count)
|
|
67
|
+
u.last_login_at = Time.now if u.respond_to?(:last_login_at)
|
|
68
|
+
u.logins_count = (u.logins_count.to_i + 1) if u.respond_to?(:logins_count)
|
|
69
|
+
u.save
|
|
70
|
+
end
|
|
53
71
|
u
|
|
54
72
|
else
|
|
55
73
|
nil
|
|
@@ -68,10 +86,12 @@ module Hobo
|
|
|
68
86
|
self.class.encrypt(password, salt)
|
|
69
87
|
end
|
|
70
88
|
|
|
89
|
+
# Check if the encrypted passwords match
|
|
71
90
|
def authenticated?(password)
|
|
72
91
|
crypted_password == encrypt(password)
|
|
73
92
|
end
|
|
74
93
|
|
|
94
|
+
# Do we still need to remember the login token, or has it expired?
|
|
75
95
|
def remember_token?
|
|
76
96
|
remember_token_expires_at && Time.now.utc < remember_token_expires_at
|
|
77
97
|
end
|
|
@@ -83,6 +103,7 @@ module Hobo
|
|
|
83
103
|
save(false)
|
|
84
104
|
end
|
|
85
105
|
|
|
106
|
+
# Expire the login token, resulting in a forced login next time.
|
|
86
107
|
def forget_me
|
|
87
108
|
self.remember_token_expires_at = nil
|
|
88
109
|
self.remember_token = nil
|
|
@@ -90,13 +111,14 @@ module Hobo
|
|
|
90
111
|
end
|
|
91
112
|
|
|
92
113
|
protected
|
|
93
|
-
# before
|
|
114
|
+
# Before filter that encrypts the password before having it stored in the database.
|
|
94
115
|
def encrypt_password
|
|
95
116
|
return if password.blank?
|
|
96
117
|
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
|
|
97
118
|
self.crypted_password = encrypt(password)
|
|
98
119
|
end
|
|
99
120
|
|
|
121
|
+
# Is a password required for login? (or do we have an empty password?
|
|
100
122
|
def password_required?
|
|
101
123
|
(crypted_password.blank? && password != nil) || !password.blank?
|
|
102
124
|
end
|
|
@@ -77,7 +77,7 @@ module Hobo
|
|
|
77
77
|
# Redirect to the URI stored by the most recent store_location call or
|
|
78
78
|
# to the passed default.
|
|
79
79
|
def redirect_back_or_default(default)
|
|
80
|
-
session[:return_to] ?
|
|
80
|
+
session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default)
|
|
81
81
|
session[:return_to] = nil
|
|
82
82
|
end
|
|
83
83
|
|
|
@@ -85,6 +85,7 @@ module Hobo
|
|
|
85
85
|
# cookie and log the user back in if apropriate
|
|
86
86
|
def login_from_cookie
|
|
87
87
|
return unless cookies[:auth_token] && !logged_in?
|
|
88
|
+
|
|
88
89
|
user = Hobo.user_model.find_by_remember_token(cookies[:auth_token])
|
|
89
90
|
if user && user.remember_token?
|
|
90
91
|
user.remember_me
|
|
@@ -2,19 +2,35 @@ module Hobo
|
|
|
2
2
|
|
|
3
3
|
module Controller
|
|
4
4
|
|
|
5
|
-
include ControllerHelpers
|
|
6
|
-
|
|
7
5
|
include AuthenticationSupport
|
|
8
|
-
|
|
6
|
+
|
|
9
7
|
def self.included(base)
|
|
10
8
|
if base.is_a?(Class)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
included_in_class(base)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.included_in_class(klass)
|
|
14
|
+
klass.extend(ClassMethods)
|
|
15
|
+
klass.class_eval do
|
|
16
|
+
alias_method_chain :redirect_to, :object_url
|
|
17
|
+
@included_taglibs = []
|
|
15
18
|
end
|
|
19
|
+
Hobo::HoboHelper.add_to_controller(klass)
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
module ClassMethods
|
|
23
|
+
|
|
24
|
+
attr_reader :included_taglibs
|
|
25
|
+
|
|
26
|
+
def include_taglib(src, options={})
|
|
27
|
+
@included_taglibs << if options[:from_plugin]
|
|
28
|
+
'plugins/' + options[:from_plugin] + '/taglibs/' + src
|
|
29
|
+
else
|
|
30
|
+
src
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
18
34
|
|
|
19
35
|
protected
|
|
20
36
|
|
|
@@ -91,17 +107,24 @@ module Hobo
|
|
|
91
107
|
end
|
|
92
108
|
|
|
93
109
|
|
|
94
|
-
def render_tag(tag, options={})
|
|
110
|
+
def render_tag(tag, options={}, render_options={})
|
|
95
111
|
add_variables_to_assigns
|
|
96
|
-
render
|
|
112
|
+
render({:text => Hobo::Dryml.render_tag(@template, tag, options),
|
|
113
|
+
:layout => false }.merge(render_options))
|
|
97
114
|
end
|
|
98
115
|
|
|
99
116
|
|
|
100
117
|
def render_tags(objects, tag, options={})
|
|
118
|
+
for_type = options.delete(:for_type)
|
|
101
119
|
add_variables_to_assigns
|
|
102
120
|
dryml_renderer = Hobo::Dryml.empty_page_renderer(@template)
|
|
103
|
-
|
|
104
|
-
|
|
121
|
+
|
|
122
|
+
results = objects.map do |o|
|
|
123
|
+
tag = dryml_renderer.find_polymorphic_tag(tag, o.class) if for_type
|
|
124
|
+
dryml_renderer.send(tag, options.merge(:with => o))
|
|
125
|
+
end.join
|
|
126
|
+
|
|
127
|
+
render :text => results + dryml_renderer.part_contexts_js
|
|
105
128
|
end
|
|
106
129
|
|
|
107
130
|
|
|
@@ -110,7 +133,7 @@ module Hobo
|
|
|
110
133
|
if results.empty?
|
|
111
134
|
render :text => "<p>Your search returned no matches.</p>"
|
|
112
135
|
else
|
|
113
|
-
render_tags(results,
|
|
136
|
+
render_tags(results, :card, :for_type => true)
|
|
114
137
|
end
|
|
115
138
|
end
|
|
116
139
|
|
|
@@ -25,7 +25,7 @@ module Hobo
|
|
|
25
25
|
@hobo_tag_blocks["#{name}_predicate"] = pred if pred
|
|
26
26
|
|
|
27
27
|
safe_name = Dryml.unreserve(name)
|
|
28
|
-
locals = attrs.map{|a| Hobo::Dryml.unreserve(a)} +
|
|
28
|
+
locals = attrs.map{|a| Hobo::Dryml.unreserve(a)} + %w{options inner_tag_options}
|
|
29
29
|
|
|
30
30
|
def_line = if pred
|
|
31
31
|
"defp :#{safe_name}, @hobo_tag_blocks['#{name}_predicate'] do |options, block|"
|
|
@@ -36,17 +36,17 @@ module Hobo
|
|
|
36
36
|
"def #{safe_name}(options={}, &block)"
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
class_eval(<<-END, __FILE__, __LINE__+1)
|
|
40
40
|
#{def_line}
|
|
41
41
|
_tag_context(options, block) do |tagbody|
|
|
42
|
-
locals = _tag_locals(options, #{attrs.inspect}
|
|
42
|
+
locals = _tag_locals(options, #{attrs.inspect})
|
|
43
43
|
locals_hash = { :tagbody => tagbody };
|
|
44
44
|
#{locals.inspect}.each_with_index{|a, i| locals_hash[a] = locals[i]}
|
|
45
45
|
Hobo::ProcBinding.new(self, locals_hash).instance_eval(&#{self.name}.hobo_tag_blocks['#{name}'])
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
END
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
end
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
module Hobo::Dryml
|
|
2
|
+
|
|
3
|
+
class DrymlSyntaxError < RuntimeError; end
|
|
2
4
|
|
|
3
|
-
class DrymlException < Exception
|
|
5
|
+
class DrymlException < Exception
|
|
6
|
+
def initialize(message, path=nil, line_num=nil)
|
|
7
|
+
if path && line_num
|
|
8
|
+
super(message + " -- at #{path}:#{line_num}")
|
|
9
|
+
else
|
|
10
|
+
super(message)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
4
14
|
|
|
5
15
|
class AttributeExtensionString < String;
|
|
6
16
|
def drop_prefix; self[2..-1]; end
|
|
@@ -12,6 +22,9 @@ module Hobo::Dryml
|
|
|
12
22
|
|
|
13
23
|
EMPTY_PAGE = "[tag-page]"
|
|
14
24
|
|
|
25
|
+
APPLICATION_TAGLIB = "taglibs/application"
|
|
26
|
+
CORE_TAGLIB = "plugins/hobo/tags/core"
|
|
27
|
+
|
|
15
28
|
@renderer_classes = {}
|
|
16
29
|
|
|
17
30
|
class << self
|
|
@@ -41,8 +54,15 @@ module Hobo::Dryml
|
|
|
41
54
|
end
|
|
42
55
|
|
|
43
56
|
prepare_view!(view)
|
|
57
|
+
included_taglibs = if view.controller.class.respond_to? :included_taglibs
|
|
58
|
+
view.controller.class.included_taglibs
|
|
59
|
+
else
|
|
60
|
+
[]
|
|
61
|
+
end
|
|
62
|
+
|
|
44
63
|
if page == EMPTY_PAGE
|
|
45
|
-
@tag_page_renderer_class = make_renderer_class("", EMPTY_PAGE, local_names,
|
|
64
|
+
@tag_page_renderer_class = make_renderer_class("", EMPTY_PAGE, local_names,
|
|
65
|
+
[Hobo::HoboHelper, ApplicationHelper], included_taglibs) if
|
|
46
66
|
@tag_page_renderer_class.nil?
|
|
47
67
|
@tag_page_renderer_class.new(page, view)
|
|
48
68
|
else
|
|
@@ -56,7 +76,7 @@ module Hobo::Dryml
|
|
|
56
76
|
(local_names - renderer_class.compiled_local_names).any? or # any new local names?
|
|
57
77
|
renderer_class.load_time < src_file.mtime) # cache out of date?
|
|
58
78
|
renderer_class = make_renderer_class(src_file.read, template_path, local_names,
|
|
59
|
-
default_imports_for_view(view))
|
|
79
|
+
default_imports_for_view(view), included_taglibs)
|
|
60
80
|
renderer_class.load_time = src_file.mtime
|
|
61
81
|
@renderer_classes[page] = renderer_class
|
|
62
82
|
end
|
|
@@ -82,26 +102,30 @@ module Hobo::Dryml
|
|
|
82
102
|
|
|
83
103
|
|
|
84
104
|
def default_imports_for_view(view)
|
|
85
|
-
[ApplicationHelper
|
|
86
|
-
|
|
105
|
+
imports = [Hobo::HoboHelper, ApplicationHelper]
|
|
106
|
+
controller_helper = view.controller.class.name.sub(/Controller$/, "Helper")
|
|
107
|
+
imports << controller_helper.constantize if Object.const_defined? controller_helper
|
|
108
|
+
imports
|
|
87
109
|
end
|
|
88
110
|
|
|
89
111
|
|
|
90
|
-
def make_renderer_class(template_src, template_path, locals, imports)
|
|
112
|
+
def make_renderer_class(template_src, template_path, locals, imports, included_taglibs=[])
|
|
91
113
|
renderer_class = Class.new(TemplateEnvironment)
|
|
92
|
-
compile_renderer_class(renderer_class, template_src, template_path, locals, imports)
|
|
114
|
+
compile_renderer_class(renderer_class, template_src, template_path, locals, imports, included_taglibs)
|
|
93
115
|
renderer_class
|
|
94
116
|
end
|
|
95
117
|
|
|
96
118
|
|
|
97
|
-
def compile_renderer_class(renderer_class, template_src, template_path, locals, imports)
|
|
119
|
+
def compile_renderer_class(renderer_class, template_src, template_path, locals, imports, included_taglibs=[])
|
|
98
120
|
template = Template.new(template_src, renderer_class, template_path)
|
|
99
121
|
imports.each {|m| template.import_module(m)}
|
|
100
122
|
|
|
123
|
+
taglibs = [CORE_TAGLIB, APPLICATION_TAGLIB] + included_taglibs
|
|
124
|
+
|
|
101
125
|
# the sum of all the names we've seen so far - eventually we'll be ready for all of 'em
|
|
102
126
|
all_local_names = renderer_class.compiled_local_names | locals
|
|
103
127
|
|
|
104
|
-
template.compile(all_local_names)
|
|
128
|
+
template.compile(all_local_names, taglibs)
|
|
105
129
|
end
|
|
106
130
|
|
|
107
131
|
|
|
@@ -114,48 +138,6 @@ module Hobo::Dryml
|
|
|
114
138
|
end
|
|
115
139
|
end
|
|
116
140
|
|
|
117
|
-
|
|
118
|
-
def merge_tag_options(to, from)
|
|
119
|
-
res = to.merge({})
|
|
120
|
-
from.each_pair do |option, value|
|
|
121
|
-
res[option] = if value.is_a?(AttributeExtensionString) and to.has_key?(option)
|
|
122
|
-
"#{to[option]} #{value.drop_prefix}"
|
|
123
|
-
else
|
|
124
|
-
value
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
res
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def hashify_options(options, merge_into=nil)
|
|
132
|
-
result = merge_into || options
|
|
133
|
-
|
|
134
|
-
options.each_pair do |key, val|
|
|
135
|
-
if key.is_a? Array
|
|
136
|
-
result.delete(key)
|
|
137
|
-
k = key.first
|
|
138
|
-
|
|
139
|
-
if key.length == 2 and key.last.is_a? Fixnum
|
|
140
|
-
hashify_options(val) if val.is_a?(Hash)
|
|
141
|
-
result[k] ||= []
|
|
142
|
-
result[k][key.last] = val
|
|
143
|
-
else
|
|
144
|
-
existing = options[k]
|
|
145
|
-
v = if key.length == 1
|
|
146
|
-
val.is_a?(Hash) ? hashify_options(val, existing) : val
|
|
147
|
-
else
|
|
148
|
-
hashify_options({key[1..-1] => val}, existing)
|
|
149
|
-
end
|
|
150
|
-
result[k] = v
|
|
151
|
-
end
|
|
152
|
-
else
|
|
153
|
-
hashify_options(val) if val.is_a?(Hash)
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
result
|
|
157
|
-
end
|
|
158
|
-
|
|
159
141
|
end
|
|
160
142
|
|
|
161
143
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
module Hobo::Dryml
|
|
2
2
|
|
|
3
3
|
class DRYMLBuilder
|
|
4
|
-
|
|
5
|
-
APPLICATION_TAGLIB = "hobolib/application"
|
|
6
|
-
CORE_TAGLIB = "plugins/hobo/tags/core"
|
|
7
4
|
|
|
8
5
|
def initialize(template_path)
|
|
6
|
+
@template_path = template_path
|
|
9
7
|
@build_instructions = Array.new
|
|
10
|
-
@
|
|
8
|
+
@part_names = []
|
|
11
9
|
end
|
|
10
|
+
|
|
11
|
+
attr_reader :template_path
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def set_environment(environment)
|
|
@@ -22,12 +22,20 @@ module Hobo::Dryml
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def clear_instructions
|
|
25
|
+
@part_names.clear
|
|
25
26
|
@build_instructions.clear
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
def add_build_instruction(params)
|
|
30
|
-
@build_instructions << params
|
|
30
|
+
def add_build_instruction(type, params)
|
|
31
|
+
@build_instructions << params.merge(:type => type)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def add_part(name, src, line_num)
|
|
36
|
+
raise DrymlException.new("duplicate part: #{name}", template_path, line_num) if name.in?(@part_names)
|
|
37
|
+
add_build_instruction(:part, :src => src, :line_num => line_num)
|
|
38
|
+
@part_names << name
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
|
|
@@ -36,47 +44,57 @@ module Hobo::Dryml
|
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
|
|
39
|
-
def
|
|
47
|
+
def render_page_source(src, local_names)
|
|
40
48
|
locals = local_names.map{|l| "#{l} = __local_assigns__[:#{l}];"}.join(' ')
|
|
41
49
|
|
|
42
50
|
("def render_page(__page_this__, __local_assigns__); " +
|
|
43
51
|
"#{locals} new_object_context(__page_this__) do " +
|
|
44
52
|
src +
|
|
45
|
-
"; end + part_contexts_js; end")
|
|
53
|
+
"; _erbout; end + part_contexts_js; end")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def erb_process(erb_src)
|
|
58
|
+
# Strip off "_erbout = ''" from the beginning and "; _erbout"
|
|
59
|
+
# from the end, because we do things differently around
|
|
60
|
+
# here. (_erbout is defined as a method)
|
|
61
|
+
ERB.new(erb_src, nil, ActionView::Base.erb_trim_mode).src[("_erbout = '';").length..-("; _erbout".length)]
|
|
46
62
|
end
|
|
47
63
|
|
|
48
64
|
|
|
49
65
|
def build(local_names, auto_taglibs)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
import_taglib(APPLICATION_TAGLIB)
|
|
53
|
-
Hobo::MappingTags.apply_standard_mappings(@environment)
|
|
54
|
-
end
|
|
66
|
+
|
|
67
|
+
auto_taglibs.each{|t| import_taglib(t)}
|
|
55
68
|
|
|
56
|
-
@build_instructions.each do |
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
@build_instructions.each do |instruction|
|
|
70
|
+
name = instruction[:name]
|
|
71
|
+
case instruction[:type]
|
|
72
|
+
when :def
|
|
73
|
+
src = erb_process(instruction[:src])
|
|
74
|
+
@environment.class_eval(src, template_path, instruction[:line_num])
|
|
75
|
+
|
|
76
|
+
when :part
|
|
77
|
+
@environment.class_eval(erb_process(instruction[:src]), template_path, instruction[:line_num])
|
|
60
78
|
|
|
61
79
|
when :render_page
|
|
62
|
-
method_src =
|
|
80
|
+
method_src = render_page_source(erb_process(instruction[:src]), local_names)
|
|
63
81
|
@environment.compiled_local_names = local_names
|
|
64
|
-
@environment.class_eval(method_src,
|
|
82
|
+
@environment.class_eval(method_src, template_path, instruction[:line_num])
|
|
65
83
|
|
|
66
|
-
when :
|
|
67
|
-
import_taglib(
|
|
84
|
+
when :include
|
|
85
|
+
import_taglib(name, instruction[:as])
|
|
68
86
|
|
|
69
87
|
when :module
|
|
70
|
-
import_module(
|
|
88
|
+
import_module(name.constantize, instruction[:as])
|
|
71
89
|
|
|
72
90
|
when :set_theme
|
|
73
|
-
set_theme(
|
|
91
|
+
set_theme(name)
|
|
74
92
|
|
|
75
93
|
when :alias_method
|
|
76
|
-
@environment.send(:alias_method,
|
|
94
|
+
@environment.send(:alias_method, instruction[:new], instruction[:old])
|
|
77
95
|
|
|
78
96
|
else
|
|
79
|
-
raise
|
|
97
|
+
raise RuntimeError.new("DRYML: Unknown build instruction :#{instruction[:type]}, building #{template_path}")
|
|
80
98
|
end
|
|
81
99
|
end
|
|
82
100
|
@last_build_time = Time.now
|
|
@@ -89,7 +107,7 @@ module Hobo::Dryml
|
|
|
89
107
|
elsif path.include?("/")
|
|
90
108
|
"app/views/#{path}"
|
|
91
109
|
else
|
|
92
|
-
template_dir = File.dirname(
|
|
110
|
+
template_dir = File.dirname(template_path)
|
|
93
111
|
"#{template_dir}/#{path}"
|
|
94
112
|
end
|
|
95
113
|
base + ".dryml"
|
|
@@ -98,7 +116,7 @@ module Hobo::Dryml
|
|
|
98
116
|
|
|
99
117
|
def import_taglib(src_path, as=nil)
|
|
100
118
|
path = expand_template_path(src_path)
|
|
101
|
-
unless
|
|
119
|
+
unless template_path == path
|
|
102
120
|
taglib = Taglib.get(RAILS_ROOT + (path.starts_with?("/") ? path : "/" + path))
|
|
103
121
|
taglib.import_into(@environment, as)
|
|
104
122
|
end
|
|
@@ -106,7 +124,7 @@ module Hobo::Dryml
|
|
|
106
124
|
|
|
107
125
|
|
|
108
126
|
def import_module(mod, as=nil)
|
|
109
|
-
raise NotImplementedError
|
|
127
|
+
raise NotImplementedError if as
|
|
110
128
|
@environment.send(:include, mod)
|
|
111
129
|
end
|
|
112
130
|
|
|
@@ -114,12 +132,7 @@ module Hobo::Dryml
|
|
|
114
132
|
def set_theme(name)
|
|
115
133
|
if Hobo.current_theme.nil? or Hobo.current_theme == name
|
|
116
134
|
Hobo.current_theme = name
|
|
117
|
-
import_taglib("
|
|
118
|
-
mapping_module = "#{name}_mapping"
|
|
119
|
-
if File.exists?(path = RAILS_ROOT + "/app/views/hobolib/themes/#{mapping_module}.rb")
|
|
120
|
-
load(path)
|
|
121
|
-
Hobo::MappingTags.apply_mappings(@environment)
|
|
122
|
-
end
|
|
135
|
+
import_taglib("taglibs/themes/#{name}/application")
|
|
123
136
|
end
|
|
124
137
|
end
|
|
125
138
|
end
|