dryml 1.3.3 → 1.4.0.pre2
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/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
|