dryml 1.3.3 → 1.4.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/README +2 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/cucumber.yml +9 -0
- data/dryml.gemspec +4 -2
- data/features/cookbook/01_simple_page_templates.feature +44 -0
- data/features/cookbook/02_defining_simple_tags.feature +375 -0
- data/features/cookbook/03_implicit_context.feature +229 -0
- data/features/cookbook/04_tag_attributes.feature +120 -0
- data/features/cookbook/05_repeated_and_optional_content.feature +241 -0
- data/features/cookbook/06_pseudo_parameters.feature +191 -0
- data/features/cookbook/07_nested_parameters.feature +147 -0
- data/features/cookbook/08_customizing_tags.feature +307 -0
- data/features/cookbook/09_aliasing_tags.feature +50 -0
- data/features/cookbook/10_polymorphic_tags.feature +168 -0
- data/features/cookbook/11_wrapping_content.feature +57 -0
- data/features/cookbook/12_local_and_scoped_variables.feature +102 -0
- data/features/doctest_examples.feature +187 -0
- data/features/merge_params.feature +36 -0
- data/features/replace_parameters.feature +21 -0
- data/features/static_tags.feature +91 -0
- data/features/step_definitions/contexts.rb +25 -0
- data/features/step_definitions/dom_comparison.rb +10 -0
- data/features/step_definitions/rendering.rb +21 -0
- data/features/support/env.rb +32 -0
- data/features/support/models/author.rb +18 -0
- data/features/support/models/blog_post.rb +37 -0
- data/features/support/models/discussion.rb +15 -0
- data/features/support/models/post.rb +12 -0
- data/features/support/strip_formatter.rb +14 -0
- data/lib/dryml/dryml_builder.rb +4 -14
- data/lib/dryml/dryml_doc.rb +6 -1
- data/lib/dryml/helper.rb +17 -1
- data/lib/dryml/part_context.rb +12 -15
- data/lib/dryml/railtie/template_handler.rb +1 -3
- data/lib/dryml/railtie.rb +1 -0
- data/lib/dryml/taglib.rb +24 -30
- data/lib/dryml/template.rb +32 -86
- data/lib/dryml/template_environment.rb +40 -17
- data/lib/dryml.rb +22 -11
- data/taglibs/core.dryml +18 -12
- data/taglibs/dryml.dryml +3 -0
- metadata +97 -56
@@ -0,0 +1,10 @@
|
|
1
|
+
Then /^the output DOM should be:$/ do |expected_html|
|
2
|
+
expected_rendered = ''
|
3
|
+
actual_rendered = ''
|
4
|
+
formatter = StripFormatter.new
|
5
|
+
# wrap in html tag, as REXML gets grumpy if there's more than one root node
|
6
|
+
formatter.write(REXML::Document.new("<html>#{expected_html}</html>"), expected_rendered)
|
7
|
+
formatter.write(REXML::Document.new("<html>#{@rendered_dom}</html>"), actual_rendered)
|
8
|
+
actual_rendered.should eq(expected_rendered)
|
9
|
+
end
|
10
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
When /^I render "([^"]*)"$/ do |file|
|
2
|
+
file_path = aruba_path(file)
|
3
|
+
file_data = File.read(file_path)
|
4
|
+
@locals ||= {}
|
5
|
+
@taglibs ||= []
|
6
|
+
@rendered_dom = Dryml.render(file_data, @locals, file_path, @taglibs)
|
7
|
+
Dryml::Template.clear_build_cache
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I include the taglib "([^"]*)"$/ do |file|
|
11
|
+
file_path = aruba_path(file+".dryml")
|
12
|
+
template_dir = File.dirname(file_path)
|
13
|
+
@taglibs ||= []
|
14
|
+
@taglibs << { :src => file, :absolute_template_path => template_dir }
|
15
|
+
end
|
16
|
+
|
17
|
+
Given /^the local variable "([^"]*)" has the value "([^"]*)"$/ do |var, value|
|
18
|
+
@locals ||= {}
|
19
|
+
@locals[var.to_sym] = value
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
lib = File.expand_path('../../../lib', __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
|
4
|
+
require 'bundler'
|
5
|
+
Bundler.setup
|
6
|
+
require 'aruba/cucumber'
|
7
|
+
|
8
|
+
require 'active_support'
|
9
|
+
require 'action_view'
|
10
|
+
require 'action_controller'
|
11
|
+
|
12
|
+
require 'dryml'
|
13
|
+
require 'dryml/railtie/template_handler'
|
14
|
+
|
15
|
+
def aruba_path(file_or_dir)
|
16
|
+
File.expand_path("../../../tmp/aruba/#{file_or_dir}", __FILE__)
|
17
|
+
end
|
18
|
+
|
19
|
+
After do
|
20
|
+
# muck out the caches
|
21
|
+
Dryml::Taglib.clear_cache
|
22
|
+
Dryml::Template.clear_build_cache
|
23
|
+
Dryml.clear_cache
|
24
|
+
end
|
25
|
+
|
26
|
+
# stub this
|
27
|
+
module Hobo
|
28
|
+
def self.root
|
29
|
+
'no_such_path'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Author
|
2
|
+
attr_accessor :id
|
3
|
+
attr_accessor :name
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
self.id = options[:id] || 1
|
7
|
+
self.name = options[:name] || 'Nobody'
|
8
|
+
end
|
9
|
+
|
10
|
+
# needed for field= to work
|
11
|
+
def [](idx)
|
12
|
+
send(idx)
|
13
|
+
end
|
14
|
+
|
15
|
+
def url
|
16
|
+
"/authors/#{id}"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class BlogPost
|
2
|
+
attr_accessor :id
|
3
|
+
attr_accessor :title
|
4
|
+
attr_accessor :body
|
5
|
+
attr_accessor :published_at
|
6
|
+
attr_accessor :author
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
self.id = options[:id] || 1
|
10
|
+
self.title = options[:title] || 'A Blog Post'
|
11
|
+
self.body = options[:body] || 'Some body content'
|
12
|
+
self.published_at = options[:published_at] || Time.utc(2011,12,30,10,25)
|
13
|
+
self.author = Author.new(options[:author] || {})
|
14
|
+
end
|
15
|
+
|
16
|
+
# needed for field= to work
|
17
|
+
def [](idx)
|
18
|
+
send(idx)
|
19
|
+
end
|
20
|
+
|
21
|
+
def url
|
22
|
+
"/blog_posts/#{id}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
title
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class SpecialBlogPost < BlogPost
|
32
|
+
|
33
|
+
def url
|
34
|
+
"/special_blog_posts/#{id}"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Discussion
|
2
|
+
attr_accessor :name
|
3
|
+
attr_accessor :posts
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
self.name = options[:name] || 'Some Discussion'
|
7
|
+
self.posts = options[:posts] || []
|
8
|
+
end
|
9
|
+
|
10
|
+
# needed for field= to work
|
11
|
+
def [](idx)
|
12
|
+
send(idx)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
data/lib/dryml/dryml_builder.rb
CHANGED
@@ -134,9 +134,6 @@ module Dryml
|
|
134
134
|
when :module
|
135
135
|
import_module(name.constantize, instruction[:as])
|
136
136
|
|
137
|
-
when :set_theme
|
138
|
-
set_theme(name)
|
139
|
-
|
140
137
|
when :alias_method
|
141
138
|
@environment.send(:alias_method, instruction[:new], instruction[:old])
|
142
139
|
|
@@ -154,10 +151,11 @@ module Dryml
|
|
154
151
|
import_module(options[:module].constantize, options[:as])
|
155
152
|
else
|
156
153
|
template_dir = File.dirname(template_path)
|
157
|
-
options = options.merge(:template_dir => template_dir)
|
154
|
+
options = options.merge(:template_dir => template_dir, :source_template => template_path)
|
158
155
|
|
159
|
-
|
160
|
-
|
156
|
+
Taglib.get(options).each do |taglib|
|
157
|
+
taglib.import_into(@environment, options[:as])
|
158
|
+
end
|
161
159
|
end
|
162
160
|
end
|
163
161
|
|
@@ -166,14 +164,6 @@ module Dryml
|
|
166
164
|
raise NotImplementedError if as
|
167
165
|
@environment.send(:include, mod)
|
168
166
|
end
|
169
|
-
|
170
|
-
|
171
|
-
def set_theme(name)
|
172
|
-
if Hobo.current_theme.nil? or Hobo.current_theme == name
|
173
|
-
Hobo.current_theme = name
|
174
|
-
import_taglib(:src => "taglibs/themes/#{name}/#{name}")
|
175
|
-
end
|
176
|
-
end
|
177
167
|
end
|
178
168
|
end
|
179
169
|
|
data/lib/dryml/dryml_doc.rb
CHANGED
@@ -32,12 +32,17 @@ require 'rexml/xpath'
|
|
32
32
|
|
33
33
|
def initialize(home, filename, name=nil)
|
34
34
|
@name = name || filename.sub(/.dryml$/, '')[home.length+1..-1]
|
35
|
+
@filename = filename
|
36
|
+
parse_file(filename)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_file(filename)
|
35
40
|
@source = File.read(filename)
|
36
41
|
@doc = Dryml::Parser::Document.new(File.read(filename), filename)
|
37
42
|
parse_tag_defs
|
38
43
|
end
|
39
44
|
|
40
|
-
attr_reader :name, :doc, :tag_defs, :source
|
45
|
+
attr_reader :name, :doc, :tag_defs, :source, :filename
|
41
46
|
|
42
47
|
def comment
|
43
48
|
first_node = doc[0][0]
|
data/lib/dryml/helper.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# An ActionView Helper
|
2
2
|
module Dryml::Helper
|
3
|
+
def create_part_id(part_name, part_locals, binding)
|
4
|
+
locals={}
|
5
|
+
part_locals.split(',').each do |local|
|
6
|
+
local=local.strip
|
7
|
+
locals[local] = eval(local, binding)
|
8
|
+
end
|
9
|
+
key2=[typed_id, locals.to_yaml]
|
10
|
+
@part_ids ||= {}
|
11
|
+
if @part_ids[part_name]
|
12
|
+
@part_ids[part_name][key2] ||= "#{part_name}-#{@part_ids[part_name].length.to_s}"
|
13
|
+
else
|
14
|
+
@part_ids[part_name] = {key2 => part_name}
|
15
|
+
part_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
3
19
|
def context_map(enum = this)
|
4
20
|
# TODO: Calls to respond_to? in here can cause the full collection hiding behind a scoped collection to get loaded
|
5
21
|
res = []
|
@@ -59,7 +75,7 @@ module Dryml::Helper
|
|
59
75
|
def param_name_for_this(foreign_key=false)
|
60
76
|
return "" unless form_this
|
61
77
|
name = if foreign_key && (refl = this_field_reflection) && refl.macro == :belongs_to
|
62
|
-
param_name_for(path_for_form_field[0..-2] + [refl.
|
78
|
+
param_name_for(path_for_form_field[0..-2] + [refl.foreign_key])
|
63
79
|
else
|
64
80
|
param_name_for(path_for_form_field)
|
65
81
|
end
|
data/lib/dryml/part_context.rb
CHANGED
@@ -13,16 +13,13 @@
|
|
13
13
|
self.digest = 'SHA1'
|
14
14
|
|
15
15
|
|
16
|
-
def self.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
"hoboParts['#{dom_id}'] = (#{code});\n"
|
22
|
-
end.join.html_safe
|
16
|
+
def self.client_side_storage_uncoded(contexts, session)
|
17
|
+
contexts.inject({}) do |h, (dom_id, context)|
|
18
|
+
h[dom_id] = context.marshal(session)
|
19
|
+
h
|
20
|
+
end
|
23
21
|
end
|
24
22
|
|
25
|
-
|
26
23
|
def self.pre_marshal(x)
|
27
24
|
if x.is_a?(ActiveRecord::Base) && x.respond_to?(:typed_id)
|
28
25
|
TypedId.new(x.typed_id)
|
@@ -75,9 +72,9 @@
|
|
75
72
|
|
76
73
|
part_name, this_id, locals, form_field_path = context
|
77
74
|
|
78
|
-
if
|
79
|
-
|
80
|
-
|
75
|
+
if Rails
|
76
|
+
Rails.logger.info "Call part: #{part_name}. this-id = #{this_id}, locals = #{locals.inspect}"
|
77
|
+
Rails.logger.info " : form_field_path = #{form_field_path.inspect}" if form_field_path
|
81
78
|
end
|
82
79
|
|
83
80
|
self.part_name = part_name
|
@@ -99,13 +96,13 @@
|
|
99
96
|
|
100
97
|
|
101
98
|
def parse_this_id(page_this)
|
102
|
-
if this_id ==
|
99
|
+
if this_id.nil? || this_id =="nil"
|
100
|
+
nil
|
101
|
+
elsif this_id == "this" || this_id == page_this.typed_id
|
103
102
|
self.this = page_this
|
104
|
-
elsif this_id =~ /^this:(.*)/
|
103
|
+
elsif this_id =~ /^this:(.*)/ || (page_this.typed_id && this_id =~ /^#{page_this.typed_id}:(.*)/)
|
105
104
|
self.this = page_this
|
106
105
|
self.this_field = $1
|
107
|
-
elsif this_id == "nil"
|
108
|
-
nil
|
109
106
|
else
|
110
107
|
parts = this_id.split(':')
|
111
108
|
if parts.length == 3
|
data/lib/dryml/railtie.rb
CHANGED
data/lib/dryml/taglib.rb
CHANGED
@@ -7,15 +7,16 @@
|
|
7
7
|
class << self
|
8
8
|
|
9
9
|
def get(options)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
taglib_filenames(options).map do |src_file|
|
11
|
+
taglib = @cache[src_file]
|
12
|
+
if taglib
|
13
|
+
taglib.reload
|
14
|
+
else
|
15
|
+
taglib = Taglib.new(src_file)
|
16
|
+
@cache[src_file] = taglib
|
17
|
+
end
|
18
|
+
taglib
|
17
19
|
end
|
18
|
-
taglib
|
19
20
|
end
|
20
21
|
|
21
22
|
def clear_cache
|
@@ -32,32 +33,25 @@
|
|
32
33
|
# If the plugin defines different taglibs you must also specify the src attribute of the taglib that you want
|
33
34
|
# to include: <include gem='gem_name' src='taglib_name'/>'
|
34
35
|
|
35
|
-
def
|
36
|
+
def taglib_filenames(options)
|
36
37
|
plugin = options[:plugin]
|
37
38
|
gem = options[:gem]
|
38
39
|
app_root = Object.const_defined?(:Rails) ? Rails.root : Pathname.new(File.expand_path('.'))
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
when options[:src] =~ /\//
|
49
|
-
app_root.join 'app/views'
|
50
|
-
when options[:template_dir] =~ /^#{Hobo.root}/
|
51
|
-
Pathname.new(options[:template_dir])
|
52
|
-
when options[:absolute_template_path]
|
53
|
-
Pathname.new(options[:absolute_template_path])
|
54
|
-
else
|
55
|
-
app_root.join options[:template_dir].gsub(/^\//, '') # remove leading / if there is one
|
56
|
-
end
|
40
|
+
search_path = []
|
41
|
+
search_path << Dryml.root.join('taglibs') if plugin == 'dryml'
|
42
|
+
search_path << Hobo.root.join('lib/hobo/rapid/taglibs') if plugin == 'hobo' || gem == 'hobo'
|
43
|
+
search_path << app_root.join('vendor/plugins', plugin, 'taglibs') if !plugin.blank?
|
44
|
+
search_path << gem.tr('-','_').camelize.constantize.root.join('taglibs') if !gem.blank?
|
45
|
+
search_path << app_root.join('app/views') if options[:src] =~ /\//
|
46
|
+
search_path << Pathname.new(options[:absolute_template_path]) if options[:absolute_template_path]
|
47
|
+
search_path << Pathname.new(options[:template_dir]) if options[:template_dir] =~ /^\//
|
48
|
+
search_path << app_root.join(options[:template_dir].gsub(/^\//, ''))
|
57
49
|
src = options[:src] || gem || plugin
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
results = nil
|
51
|
+
search_path.any? {|path| !(results = Dir[path.join "#{src}.dryml"]).empty?}
|
52
|
+
raise DrymlException, "No such taglib: #{src} #{options.inspect}" if results.empty?
|
53
|
+
results - [File.expand_path(options[:source_template])]
|
54
|
+
|
61
55
|
end
|
62
56
|
|
63
57
|
end
|