dryml 1.3.0.pre31 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0.pre31
1
+ 1.3.0
data/dryml.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.summary = "The Don't Repeat Yourself Markup Language"
12
12
  s.description = "The Don't Repeat Yourself Markup Language"
13
13
 
14
- s.add_runtime_dependency('actionpack', [">= 3.0.0"])
14
+ s.add_runtime_dependency('actionpack', ["~> 3.0.0"])
15
15
  s.add_runtime_dependency('hobo_support', ["= #{version}"])
16
16
  s.add_development_dependency('rubydoctest', [">= 0"])
17
17
 
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.rdoc_options = ["--charset=UTF-8"]
26
26
  s.require_paths = ["lib"]
27
27
 
28
+ s.extensions = 'ext/mkrf_conf.rb'
28
29
  end
data/ext/mkrf_conf.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+
3
+ # the whole reason this file exists: to return an error if openssl
4
+ # isn't installed.
5
+ require 'openssl'
6
+
7
+ f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w") # create dummy rakefile to indicate success
8
+ f.write("task :default\n")
9
+ f.close
@@ -1,3 +1,5 @@
1
+ require 'erubis'
2
+
1
3
  module Dryml
2
4
 
3
5
  class DRYMLBuilder
@@ -58,10 +60,49 @@ module Dryml
58
60
  end
59
61
 
60
62
 
63
+ class Erubis < ::Erubis::Eruby
64
+ def add_preamble(src)
65
+
66
+ end
67
+
68
+ def add_text(src, text)
69
+ return if text.empty?
70
+ src << "self.output_buffer.safe_concat('" << escape_text(text) << "');"
71
+ end
72
+
73
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
74
+
75
+ def add_expr_literal(src, code)
76
+ if code =~ BLOCK_EXPR
77
+ src << 'self.output_buffer.append= ' << code << ";\nself.output_buffer;"
78
+ else
79
+ src << 'self.output_buffer.append= (' << code << ");\nself.output_buffer;"
80
+ end
81
+ end
82
+
83
+ def add_stmt(src, code)
84
+ # skip fallback code - it utterly destroys DRYML-generated ERB
85
+ super
86
+ end
87
+
88
+ def add_expr_escaped(src, code)
89
+ if code =~ BLOCK_EXPR
90
+ src << "self.output_buffer.safe_append= " << code << ";\nself.output_buffer;"
91
+ else
92
+ src << "self.output_buffer.safe_concat((" << code << ").to_s);"
93
+ end
94
+ end
95
+
96
+ def add_postamble(src)
97
+ # NOTE: we can't just add a 'self.output_buffer' here because this parser
98
+ # is used to compile taglibs which don't HAVE one
99
+ end
100
+ end
101
+
61
102
  def erb_process(erb_src)
62
103
  trim_mode = ActionView::TemplateHandlers::ERB.erb_trim_mode
63
- erb = ERB.new(erb_src, nil, trim_mode, "output_buffer")
64
- res = erb.src.split(';')[1..-2].join(';')
104
+ erb = Erubis.new(erb_src, :trim_mode => trim_mode)
105
+ res = erb.src
65
106
  if res.respond_to? :force_encoding
66
107
  res.force_encoding(erb_src.encoding)
67
108
  end
@@ -195,6 +195,7 @@ require 'fileutils'
195
195
  refl = model.reflections[collection]
196
196
  klass = refl.klass
197
197
  klass < ActiveRecord::Acts::List::InstanceMethods &&
198
+ klass.table_exists? &&
198
199
  klass.new.position_column == refl.options[:order].to_s
199
200
  end
200
201
  end
@@ -121,7 +121,7 @@
121
121
  def restore_locals(locals)
122
122
  locals.map do |l|
123
123
  if l.is_a?(TypedId)
124
- Hobo::Model.find_by_typed_id(this_id)
124
+ Hobo::Model.find_by_typed_id(l)
125
125
  else
126
126
  l
127
127
  end
data/lib/dryml/taglib.rb CHANGED
@@ -24,29 +24,40 @@
24
24
 
25
25
  private
26
26
 
27
+ # Requirements for hobo-plugin for loading a taglib when the plugin is loaded as a gem:
28
+ # - the plugin must define the <gem_name>.camelize.constantize.root() method
29
+ # - the root() method must return a Pathname object (like Hobo.root, Dryml.root, Rails.root, etc.)
30
+ # - the taglibs must be available in the 'taglibs' dir in the gem root
31
+ # You can include the taglib with <include gem='gem_name'/> if the taglib name has the same gem name.
32
+ # If the plugin defines different taglibs you must also specify the src attribute of the taglib that you want
33
+ # to include: <include gem='gem_name' src='taglib_name'/>'
34
+
27
35
  def taglib_filename(options)
28
- plugin = options[:plugin]
29
- rails_root = Object.const_defined?(:Rails) ? Rails.root : "."
30
- base = if plugin == "dryml"
31
- "#{Dryml.root}/taglibs"
32
- elsif plugin == "hobo"
33
- "#{Hobo.root}/lib/hobo/rapid/taglibs"
34
- elsif not plugin.blank?
35
- "#{rails_root}/vendor/plugins/#{plugin}/taglibs"
36
- elsif options[:src] =~ /\//
37
- "#{rails_root}/app/views"
38
- elsif options[:template_dir] =~ /^#{Hobo.root}/
39
- options[:template_dir]
40
- elsif options[:absolute_template_path]
41
- options[:absolute_template_path]
42
- else
43
- "#{rails_root}/#{options[:template_dir].gsub(/^\//, '')}" # remove leading / if there is one
44
- end
45
-
46
- src = options[:src] || plugin
47
- filename = "#{base}/#{src}.dryml"
48
- raise DrymlException, "No such taglib: #{base} #{options.inspect} #{filename}" unless File.exists?(filename)
49
- filename
36
+ plugin = options[:plugin]
37
+ gem = options[:gem]
38
+ app_root = Object.const_defined?(:Rails) ? Rails.root : Pathname.new(File.expand_path('.'))
39
+ taglibs_path = case
40
+ when plugin == 'dryml'
41
+ Dryml.root.join 'taglibs'
42
+ when plugin == 'hobo', gem == 'hobo'
43
+ Hobo.root.join 'lib/hobo/rapid/taglibs'
44
+ when !plugin.blank?
45
+ app_root.join 'vendor/plugins', plugin, 'taglibs'
46
+ when !gem.blank?
47
+ gem.tr('-','_').camelize.constantize.root.join 'taglibs'
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
57
+ src = options[:src] || gem || plugin
58
+ taglib_file = taglibs_path.join "#{src}.dryml"
59
+ raise DrymlException, "No such taglib: #{src} #{options.inspect} #{taglib_file}" unless taglib_file.exist?
60
+ taglib_file.to_s
50
61
  end
51
62
 
52
63
  end
@@ -190,7 +190,7 @@ module Dryml
190
190
  require_toplevel(el)
191
191
  require_attribute(el, "as", /^#{DRYML_NAME}$/, true)
192
192
  options = {}
193
- %w(src module plugin as).each do |attr|
193
+ %w(src module plugin gem as).each do |attr|
194
194
  options[attr.to_sym] = el.attributes[attr] if el.attributes[attr]
195
195
  end
196
196
  @builder.add_build_instruction(:include, options)
@@ -251,7 +251,11 @@ module Dryml
251
251
  _tag_context(attributes) do
252
252
  attributes.delete :with
253
253
  attributes.delete :field
254
- call_polymorphic_tag('#{name}', attributes, parameters) { #{name}__base(attributes.except, parameters) }
254
+ if for_klass = parse_for_type(attributes)
255
+ call_polymorphic_tag('#{name}', for_klass, attributes, parameters) { #{name}__base(attributes.except, parameters) }
256
+ else
257
+ call_polymorphic_tag('#{name}', attributes, parameters) { #{name}__base(attributes.except, parameters) }
258
+ end
255
259
  end
256
260
  end
257
261
  )
@@ -398,17 +402,17 @@ module Dryml
398
402
  "<% output_buffer; end"
399
403
  end
400
404
 
401
-
402
405
  def wrap_source_with_metadata(content, kind, name, *args)
403
406
  if (!include_source_metadata) || name.in?(NO_METADATA_TAGS)
404
407
  content
405
408
  else
406
409
  metadata = [kind, name] + args + [@template_path]
407
- "<!--[DRYML|#{metadata * '|'}[-->" + content + "<!--]DRYML]-->"
410
+ "<% safe_concat(%(<!--[DRYML|#{metadata * '|'}[-->)) %>" +
411
+ content +
412
+ "<% safe_concat(%(<!--]DRYML]-->)) %>"
408
413
  end
409
414
  end
410
415
 
411
-
412
416
  def wrap_tag_method_body_with_metadata(content)
413
417
  name = @def_element.attributes['tag']
414
418
  for_ = @def_element.attributes['for']
@@ -722,14 +726,14 @@ module Dryml
722
726
  def append_parameter_tag_hash_item(name, el, metadata_name)
723
727
  ":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
724
728
  param_content_element(name) + children_to_erb(el) +
725
- "<% } } } ] }"
729
+ "<% ; output_buffer } } } ] }"
726
730
  end
727
731
 
728
732
 
729
733
  def prepend_parameter_tag_hash_item(name, el, metadata_name)
730
734
  ":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
731
735
  children_to_erb(el) + param_content_element(name) +
732
- "<% } } } ] }"
736
+ "<% ; output_buffer } } } ] }"
733
737
  end
734
738
 
735
739
 
@@ -737,7 +741,7 @@ module Dryml
737
741
  content = children_to_erb(el)
738
742
  content = wrap_source_with_metadata(content, "param", containing_param_name,
739
743
  element_line_num(el)) if containing_param_name
740
- "proc { |#{param_content_local_name(el.dryml_name)}| new_context { %>#{content}<% } #{tag_newlines(el)}}"
744
+ "proc { |#{param_content_local_name(el.dryml_name)}| new_context { %>#{content}<% ; output_buffer } #{tag_newlines(el)}}"
741
745
  end
742
746
 
743
747
 
@@ -751,8 +755,8 @@ module Dryml
751
755
  end
752
756
 
753
757
 
754
- def param_proc(el, metadata_name_prefix)
755
- metadata_name = "#{metadata_name_prefix}><#{el.name}"
758
+ def param_proc(el, metadata_name_suffix)
759
+ metadata_name = "#{el.name} < #{metadata_name_suffix}"
756
760
 
757
761
  nl = tag_newlines(el)
758
762
 
@@ -785,7 +789,7 @@ module Dryml
785
789
  def replace_parameter_proc(el, metadata_name, content=nil)
786
790
  content ||= wrap_replace_parameter(el, metadata_name)
787
791
  param_name = el.dryml_name.sub(/^(before|after|append|prepend)-/, "")
788
- "proc { |#{param_restore_local_name(param_name)}| new_context { %>#{content}<% } #{tag_newlines(el)}}"
792
+ "proc { |#{param_restore_local_name(param_name)}| new_context { %>#{content}<% ; output_buffer } #{tag_newlines(el)}}"
789
793
  end
790
794
 
791
795
 
@@ -813,7 +817,7 @@ module Dryml
813
817
  items = attributes.map do |n,v|
814
818
  dryml_exception("invalid attribute name '#{n}' (remember to use '-' rather than '_')", el) unless n =~ DRYML_NAME_RX
815
819
 
816
- next if n.in?(SPECIAL_ATTRIBUTES) || n =~ /^without-/
820
+ next if n.in?(SPECIAL_ATTRIBUTES-['for-type']) || n =~ /^without-/
817
821
  next if el.attributes['part'] && n == 'id' # The id is rendered on the <div class="part-wrapper"> instead
818
822
 
819
823
  ":#{ruby_name n} => #{attribute_to_ruby(v)}"
@@ -1026,8 +1030,6 @@ module Dryml
1026
1030
  end
1027
1031
 
1028
1032
  def include_source_metadata
1029
- # disabled for now -- we're still getting broken rendering with this feature on
1030
- return false
1031
1033
  @include_source_metadata = Rails.env.development? && !ENV['DRYML_EDITOR'].blank? if @include_source_metadata.nil?
1032
1034
  @include_source_metadata
1033
1035
  end
@@ -144,7 +144,7 @@ module Dryml
144
144
 
145
145
  id = if (typed_id = object.try.typed_id)
146
146
  typed_id
147
- elsif object == this
147
+ elsif object == @this
148
148
  "this"
149
149
  end
150
150
  attribute ? "#{id}:#{attribute}" : id
@@ -162,7 +162,7 @@ module Dryml
162
162
 
163
163
 
164
164
  def refresh_part(encoded_context, session, dom_id)
165
- context = Dryml::PartContext.for_refresh(encoded_context, this, session)
165
+ context = Dryml::PartContext.for_refresh(encoded_context, @this, session)
166
166
 
167
167
  with_part_context(context) do
168
168
  send("#{context.part_name}_part", *context.locals)
@@ -188,6 +188,20 @@ module Dryml
188
188
  end
189
189
  end
190
190
 
191
+ def parse_for_type(attributes)
192
+ t = attributes[:for_type]
193
+ if t.nil?
194
+ nil
195
+ elsif t.is_a?(Class)
196
+ t
197
+ elsif t =~ /^[A-Z]/
198
+ t.constantize
199
+ elsif t =~ /^[a-z]/ && defined?(HoboFields.to_class)
200
+ HoboFields.to_class(t)
201
+ else
202
+ nil
203
+ end
204
+ end
191
205
 
192
206
  def call_polymorphic_tag(name, *args)
193
207
  name = name.to_s.gsub('-', '_')
@@ -246,7 +260,8 @@ module Dryml
246
260
  @_form_field_path, @_form_field_paths_by_object ]
247
261
  @_this_type = nil
248
262
  res = nil
249
- @view.with_output_buffer { res = yield }
263
+ outer_res = @view.with_output_buffer { res = yield }
264
+ Rails.logger.error("new_context: #{caller.first}") if !outer_res.blank? && outer_res.to_s != res.to_s
250
265
  @_this, @_this_parent, @_this_field, @_this_type, @_form_field_path, @_form_field_paths_by_object = ctx
251
266
  res.to_s
252
267
  end
@@ -332,13 +347,14 @@ module Dryml
332
347
 
333
348
 
334
349
  def with_form_context(form_this=this, form_field_path=[form_this.class.name.underscore])
350
+ ctx = [@_form_this, @_form_field_path, @_form_field_paths_by_object]
335
351
  @_form_this = form_this
336
352
  @_form_field_path = form_field_path
337
353
  @_form_field_paths_by_object = { form_this => form_field_path }
338
354
  res = scope.new_scope :in_form => true, :form_field_names => [] do
339
355
  yield
340
356
  end
341
- @_form_this = @_form_field_path = @_form_field_paths_by_object = nil
357
+ @_form_this, @_form_field_path, @_form_field_paths_by_object = ctx
342
358
  res
343
359
  end
344
360
 
@@ -526,14 +542,6 @@ module Dryml
526
542
  end
527
543
 
528
544
 
529
-
530
-
531
- def part_contexts_javascripts
532
- storage = part_contexts_storage
533
- storage.blank? ? "" : "<script type=\"text/javascript\">\n#{storage}</script>\n"
534
- end
535
-
536
-
537
545
  def part_contexts_storage
538
546
  PartContext.client_side_storage(@_part_contexts, session)
539
547
  end
data/lib/dryml.rb CHANGED
@@ -6,8 +6,10 @@
6
6
 
7
7
  require 'hobo_support'
8
8
  require 'action_pack'
9
+ require 'openssl'
9
10
 
10
11
  ActiveSupport::Dependencies.autoload_paths |= [File.dirname(__FILE__)]
12
+ ActiveSupport::Dependencies.autoload_once_paths |= [File.dirname(__FILE__)]
11
13
 
12
14
  # The Don't Repeat Yourself Markup Language
13
15
  module Dryml
@@ -64,9 +66,10 @@ module Dryml
64
66
  end
65
67
 
66
68
  def call_render(view, local_assigns, identifier)
67
- renderer = page_renderer(view, identifier, local_assigns.keys)
68
69
  this = view.controller.send(:dryml_context) || local_assigns[:this]
69
70
  view.instance_variable_set("@this", this)
71
+ # do this last, as TemplateEnvironment copies instance variables in initalize
72
+ renderer = page_renderer(view, identifier, local_assigns.keys)
70
73
  if identifier =~ /#{ID_SEPARATOR}/
71
74
  tag_name = identifier.split(ID_SEPARATOR).last
72
75
  renderer.render_tag(tag_name, {:with => this} )
@@ -111,10 +114,10 @@ module Dryml
111
114
  end
112
115
 
113
116
  def get_field_path(object, path)
117
+ return nil if object.nil?
114
118
  path = path.is_a?(String) ? path.split('.') : Array(path)
115
119
  parent = nil
116
120
  path.each do |field|
117
- return nil if object.nil?
118
121
  parent = object
119
122
  object = get_field(parent, field)
120
123
  end
@@ -181,7 +184,7 @@ private
181
184
  def taglibs_for(controller_path)
182
185
  ( taglibs_in_dir('application').unshift(APPLICATION_TAGLIB) +
183
186
  subsite_taglibs(controller_path) +
184
- (controller_path.camelize+"Controller").constantize.try.included_taglibs||[]
187
+ ((controller_path.camelize+"Controller").constantize.try.included_taglibs||[])
185
188
  ).compact
186
189
  end
187
190
 
data/taglibs/core.dryml CHANGED
@@ -4,7 +4,9 @@
4
4
  It's the DRYML equivalent of Ruby's `send` method.
5
5
  -->
6
6
  <def tag="call-tag" attrs="tag">
7
- <%= send(tag.gsub('-', '_'), attributes, parameters) %>
7
+ <%= Dryml.static_tags.include?(tag) ?
8
+ content_tag(tag, parameters.default, attributes) :
9
+ send(tag.gsub('-', '_'), attributes, parameters) %>
8
10
  </def>
9
11
 
10
12
 
@@ -21,7 +23,15 @@ For example, you might want to wrap an `<img>` tag in an `<a>` tag but only unde
21
23
  -->
22
24
  <def tag="wrap" attrs="tag, when, parameter">
23
25
  <% parameter ||= :default %>
24
- <%= when_ ? send(tag, attributes, { parameter.to_sym => parameters[:default] }) : parameters.default %>
26
+ <%= if when_
27
+ if Dryml.static_tags.include?(tag)
28
+ content_tag(tag, parameters.default, attributes)
29
+ else
30
+ send(tag.gsub('-', '_'), attributes, { parameter.to_sym => parameters[:default] })
31
+ end
32
+ else
33
+ parameters.default
34
+ end %>
25
35
  </def>
26
36
 
27
37
 
@@ -61,10 +71,10 @@ For example, you might want to wrap an `<img>` tag in an `<a>` tag but only unde
61
71
 
62
72
  ### Usage
63
73
 
64
- <if test="&current_user.administrtator?">Logged in as administrator</if>
74
+ <if test="&current_user.administrator?">Logged in as administrator</if>
65
75
  <else>Logged in as normal user</else>
66
-
67
- **IMPORTANT NOTE**: `<if>` tests for non-blank vs. blank (as defined by ActiveSuport), not true vs. false.
76
+
77
+ **IMPORTANT NOTE**: `<if>` tests for non-blank vs. blank (as defined by ActiveSupport), not true vs. false.
68
78
 
69
79
  If you do not give the `test` attribute, uses the current context instead. This allows a nice trick like this:
70
80
 
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dryml
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 6
5
- version: 1.3.0.pre31
4
+ prerelease:
5
+ version: 1.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tom Locke
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-29 00:00:00 -04:00
13
+ date: 2011-11-14 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -19,7 +19,7 @@ dependencies:
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
- - - ">="
22
+ - - ~>
23
23
  - !ruby/object:Gem::Version
24
24
  version: 3.0.0
25
25
  type: :runtime
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - "="
34
34
  - !ruby/object:Gem::Version
35
- version: 1.3.0.pre31
35
+ version: 1.3.0
36
36
  type: :runtime
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
@@ -50,8 +50,8 @@ description: The Don't Repeat Yourself Markup Language
50
50
  email: tom@tomlocke.com
51
51
  executables: []
52
52
 
53
- extensions: []
54
-
53
+ extensions:
54
+ - ext/mkrf_conf.rb
55
55
  extra_rdoc_files: []
56
56
 
57
57
  files:
@@ -62,6 +62,7 @@ files:
62
62
  - TODO.txt
63
63
  - VERSION
64
64
  - dryml.gemspec
65
+ - ext/mkrf_conf.rb
65
66
  - lib/dryml.rb
66
67
  - lib/dryml/dryml_builder.rb
67
68
  - lib/dryml/dryml_doc.rb
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
114
  requirements: []
114
115
 
115
116
  rubyforge_project: hobo
116
- rubygems_version: 1.5.0
117
+ rubygems_version: 1.6.2
117
118
  signing_key:
118
119
  specification_version: 3
119
120
  summary: The Don't Repeat Yourself Markup Language