infopark_rails_connector 6.8.0.beta.200.621.4c8e1b0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/README +59 -0
  2. data/app/assets/images/admin/minus.gif +0 -0
  3. data/app/assets/images/bg80.png +0 -0
  4. data/app/assets/images/edit.png +0 -0
  5. data/app/assets/images/icons/mm_generic.png +0 -0
  6. data/app/assets/images/icons/mm_menu.png +0 -0
  7. data/app/assets/images/ratings/star.gif +0 -0
  8. data/app/assets/images/time_machine/calendar-menuarrow.gif +0 -0
  9. data/app/assets/images/time_machine/calendar_bg.png +0 -0
  10. data/app/assets/images/time_machine/icon.png +0 -0
  11. data/app/assets/images/time_machine/slider_bg.png +0 -0
  12. data/app/assets/images/time_machine/slider_handle.png +0 -0
  13. data/app/assets/images/time_machine/timemachine_bg.png +0 -0
  14. data/app/assets/javascripts/comments.js +29 -0
  15. data/app/assets/javascripts/editmarker.js +240 -0
  16. data/app/assets/javascripts/infopark_rails_connector.js.erb +3 -0
  17. data/app/assets/javascripts/initializer.js +9 -0
  18. data/app/assets/javascripts/ratings.js +26 -0
  19. data/app/assets/javascripts/time_machine/calendar-setup.js +200 -0
  20. data/app/assets/javascripts/time_machine/calendar.js +1806 -0
  21. data/app/assets/javascripts/time_machine/lang/calendar-de.js +127 -0
  22. data/app/assets/javascripts/time_machine/lang/calendar-en.js +127 -0
  23. data/app/assets/javascripts/time_machine/lang/calendar-es.js +129 -0
  24. data/app/assets/javascripts/time_machine/lang/calendar-fr.js +125 -0
  25. data/app/assets/javascripts/time_machine/lang/calendar-it.js +124 -0
  26. data/app/assets/javascripts/time_machine/slider.js +278 -0
  27. data/app/assets/javascripts/time_machine.js +8 -0
  28. data/app/assets/stylesheets/editmarker.css +70 -0
  29. data/app/assets/stylesheets/infopark_rails_connector.css.erb +4 -0
  30. data/app/assets/stylesheets/ratings.css +97 -0
  31. data/app/assets/stylesheets/time_machine/time_machine.css +292 -0
  32. data/app/assets/stylesheets/time_machine.css +6 -0
  33. data/app/controllers/cms_controller.rb +6 -0
  34. data/app/controllers/comments_controller.rb +6 -0
  35. data/app/controllers/crm_form_controller.rb +2 -0
  36. data/app/controllers/pdf_controller.rb +6 -0
  37. data/app/controllers/rails_connector/default_cms_controller.rb +40 -0
  38. data/app/controllers/rails_connector/default_comments_controller.rb +71 -0
  39. data/app/controllers/rails_connector/default_crm_form_controller.rb +167 -0
  40. data/app/controllers/rails_connector/default_pdf_controller.rb +136 -0
  41. data/app/controllers/rails_connector/default_ratings_controller.rb +84 -0
  42. data/app/controllers/rails_connector/default_rss_controller.rb +29 -0
  43. data/app/controllers/rails_connector/default_search_controller.rb +60 -0
  44. data/app/controllers/rails_connector/default_user_controller.rb +267 -0
  45. data/app/controllers/rails_connector/pdf_external_controller.rb +54 -0
  46. data/app/controllers/rails_connector/time_machine_controller.rb +48 -0
  47. data/app/controllers/ratings_controller.rb +6 -0
  48. data/app/controllers/rss_controller.rb +6 -0
  49. data/app/controllers/search_controller.rb +2 -0
  50. data/app/controllers/seo_sitemap_controller.rb +12 -0
  51. data/app/controllers/user_controller.rb +2 -0
  52. data/app/helpers/cms_helper.rb +6 -0
  53. data/app/helpers/cms_routing_helper.rb +6 -0
  54. data/app/helpers/crm_form_helper.rb +3 -0
  55. data/app/helpers/rails_connector/cms_asset_helper.rb +51 -0
  56. data/app/helpers/rails_connector/default_cms_helper.rb +27 -0
  57. data/app/helpers/rails_connector/default_cms_routing_helper.rb +93 -0
  58. data/app/helpers/rails_connector/default_crm_form_helper.rb +58 -0
  59. data/app/helpers/rails_connector/default_ratings_helper.rb +38 -0
  60. data/app/helpers/rails_connector/default_user_helper.rb +90 -0
  61. data/app/helpers/rails_connector/display_helper.rb +117 -0
  62. data/app/helpers/rails_connector/error_messages_helper.rb +23 -0
  63. data/app/helpers/rails_connector/layout_helper.rb +30 -0
  64. data/app/helpers/rails_connector/link_helper.rb +88 -0
  65. data/app/helpers/rails_connector/mandatory_label_helper.rb +10 -0
  66. data/app/helpers/rails_connector/marker_helper.rb +363 -0
  67. data/app/helpers/rails_connector/menu_helper.rb +72 -0
  68. data/app/helpers/rails_connector/micronav_helper.rb +107 -0
  69. data/app/helpers/rails_connector/seo_helper.rb +44 -0
  70. data/app/helpers/rails_connector/table_of_contents_helper.rb +20 -0
  71. data/app/helpers/rails_connector/time_machine_helper.rb +24 -0
  72. data/app/helpers/rails_connector/tracking_helper.rb +32 -0
  73. data/app/helpers/ratings_helper.rb +4 -0
  74. data/app/helpers/user_helper.rb +3 -0
  75. data/app/mailers/confirmation_mailer.rb +13 -0
  76. data/app/models/crm_form.rb +2 -0
  77. data/app/models/named_link.rb +2 -0
  78. data/app/models/obj.rb +9 -0
  79. data/app/models/rails_connector/default_comment.rb +28 -0
  80. data/app/models/rails_connector/default_rating.rb +20 -0
  81. data/app/models/rails_connector/link_list.rb +30 -0
  82. data/app/views/cms/_comments.html.erb +44 -0
  83. data/app/views/cms/_index.html.erb +7 -0
  84. data/app/views/cms/_rating.html.erb +31 -0
  85. data/app/views/cms/index.html.erb +3 -0
  86. data/app/views/comments/_comment.html.erb +28 -0
  87. data/app/views/confirmation_mailer/register_confirmation.erb +5 -0
  88. data/app/views/confirmation_mailer/reset_password.erb +5 -0
  89. data/app/views/crm_form/_flash_messages.html.erb +11 -0
  90. data/app/views/crm_form/_form.html.erb +17 -0
  91. data/app/views/crm_form/confirmation.html.erb +3 -0
  92. data/app/views/crm_form/index.html.erb +5 -0
  93. data/app/views/crm_form/not_logged_in.html.erb +1 -0
  94. data/app/views/errors/403_forbidden.html.erb +3 -0
  95. data/app/views/errors/410_gone.html.erb +7 -0
  96. data/app/views/layouts/rails_connector/time_machine.html.erb +12 -0
  97. data/app/views/pdf/index.html.erb +7 -0
  98. data/app/views/pdf/index.xsl +1240 -0
  99. data/app/views/rails_connector/time_machine/index.html.erb +88 -0
  100. data/app/views/rss/_item.rss.builder +11 -0
  101. data/app/views/rss/index.rss.builder +11 -0
  102. data/app/views/search/_hit.html.erb +12 -0
  103. data/app/views/search/_hits.html.erb +11 -0
  104. data/app/views/search/_mini_panel.html.erb +4 -0
  105. data/app/views/search/_pagination.html.erb +5 -0
  106. data/app/views/search/_panel.html.erb +4 -0
  107. data/app/views/search/search.html.erb +12 -0
  108. data/app/views/seo_sitemap/show.xml.builder +16 -0
  109. data/app/views/user/_flash_messages.html.erb +11 -0
  110. data/app/views/user/edit.html.erb +6 -0
  111. data/app/views/user/edit_password.html.erb +11 -0
  112. data/app/views/user/forgot_password.html.erb +7 -0
  113. data/app/views/user/login.html.erb +15 -0
  114. data/app/views/user/new.html.erb +11 -0
  115. data/app/views/user/profile.html.erb +8 -0
  116. data/app/views/user/register_pending.html.erb +1 -0
  117. data/app/views/user/set_password.html.erb +14 -0
  118. data/config/cms_routes.rb +13 -0
  119. data/config/locales/de.rails_connector.controllers.yml +30 -0
  120. data/config/locales/de.rails_connector.errors.yml +11 -0
  121. data/config/locales/de.rails_connector.helpers.yml +9 -0
  122. data/config/locales/de.rails_connector.lib.yml +6 -0
  123. data/config/locales/de.rails_connector.models.yml +8 -0
  124. data/config/locales/de.rails_connector.views.yml +87 -0
  125. data/config/locales/en.rails_connector.controllers.yml +30 -0
  126. data/config/locales/en.rails_connector.errors.yml +10 -0
  127. data/config/locales/en.rails_connector.helpers.yml +9 -0
  128. data/config/locales/en.rails_connector.lib.yml +6 -0
  129. data/config/locales/en.rails_connector.models.yml +8 -0
  130. data/config/locales/en.rails_connector.views.yml +87 -0
  131. data/config/routes.rb +37 -0
  132. data/lib/generators/rails_connector/comments/comments_generator.rb +21 -0
  133. data/lib/generators/rails_connector/comments/templates/migration.rb +17 -0
  134. data/lib/generators/rails_connector/install/install_generator.rb +38 -0
  135. data/lib/generators/rails_connector/install/templates/initializers/rails_connector.rb +58 -0
  136. data/lib/generators/rails_connector/install/templates/local/configuration.rb +2 -0
  137. data/lib/generators/rails_connector/install/templates/obj_extensions.rb +25 -0
  138. data/lib/generators/rails_connector/ratings/ratings_generator.rb +21 -0
  139. data/lib/generators/rails_connector/ratings/templates/migration.rb +15 -0
  140. data/lib/infopark_rails_connector.rb +31 -0
  141. data/lib/obj_extensions.rb +6 -0
  142. data/lib/rails_connector/authenticable.rb +30 -0
  143. data/lib/rails_connector/cms_accessible.rb +114 -0
  144. data/lib/rails_connector/cms_dispatch_controller.rb +47 -0
  145. data/lib/rails_connector/cms_env.rb +55 -0
  146. data/lib/rails_connector/cms_test_request.rb +23 -0
  147. data/lib/rails_connector/commentable.rb +23 -0
  148. data/lib/rails_connector/configuration/google_analytics.rb +29 -0
  149. data/lib/rails_connector/configuration/pdf_generator.rb +15 -0
  150. data/lib/rails_connector/configuration/rss.rb +46 -0
  151. data/lib/rails_connector/configuration.rb +235 -0
  152. data/lib/rails_connector/core_extensions/time.rb +18 -0
  153. data/lib/rails_connector/core_extensions.rb +1 -0
  154. data/lib/rails_connector/crm.rb +282 -0
  155. data/lib/rails_connector/engine.rb +78 -0
  156. data/lib/rails_connector/fop.rb +18 -0
  157. data/lib/rails_connector/fop_on_rails/document/dom_tree.rb +42 -0
  158. data/lib/rails_connector/fop_on_rails/document/images.rb +34 -0
  159. data/lib/rails_connector/fop_on_rails/document/tables.rb +67 -0
  160. data/lib/rails_connector/fop_on_rails/document.rb +25 -0
  161. data/lib/rails_connector/fop_on_rails.rb +92 -0
  162. data/lib/rails_connector/googlebot_checker.rb +47 -0
  163. data/lib/rails_connector/html_string.rb +19 -0
  164. data/lib/rails_connector/infopark_base.rb +2 -0
  165. data/lib/rails_connector/link_resolvable.rb +9 -0
  166. data/lib/rails_connector/liquid_support/action_marker.rb +69 -0
  167. data/lib/rails_connector/liquid_support/field_value_drop.rb +22 -0
  168. data/lib/rails_connector/liquid_support/general_helper_tag.rb +44 -0
  169. data/lib/rails_connector/liquid_support/link_drop.rb +22 -0
  170. data/lib/rails_connector/liquid_support/liquid_template_handler.rb +162 -0
  171. data/lib/rails_connector/liquid_support/named_object_drop.rb +14 -0
  172. data/lib/rails_connector/liquid_support/obj_drop.rb +43 -0
  173. data/lib/rails_connector/liquid_support/obj_filters.rb +77 -0
  174. data/lib/rails_connector/liquid_support.rb +23 -0
  175. data/lib/rails_connector/markdown_string.rb +19 -0
  176. data/lib/rails_connector/rateable.rb +57 -0
  177. data/lib/rails_connector/seo.rb +52 -0
  178. data/lib/rails_connector/ses.rb +72 -0
  179. data/lib/rails_connector/string_tagging.rb +29 -0
  180. data/lib/rails_connector/syndicateable.rb +11 -0
  181. data/lib/search_request.rb +2 -0
  182. data/lib/tasks/check.rake +25 -0
  183. data/lib/tasks/cms_license_check.rake +17 -0
  184. metadata +489 -0
@@ -0,0 +1,34 @@
1
+ module RailsConnector
2
+ module FopOnRails
3
+ module Document # :nodoc: all
4
+ module Images
5
+ def self.absolutize_src_attrs(xml, url)
6
+ @url = URI.parse(url)
7
+ xml.elements.each('//img') do |img|
8
+ url = URI.parse(img.attributes['src'])
9
+ unless (url.host == @url.host)
10
+ url = @url.merge(url)
11
+ end
12
+ img.attributes['src'] = url.to_s
13
+ end
14
+ xml
15
+ end
16
+
17
+ def self.dump_images(xml)
18
+ xml.elements.each('//img') do |img|
19
+ unless URI.parse(src = img.attributes['src']).absolute?
20
+ if relative_url_root = ActionController::Base.config.relative_url_root
21
+ src.sub!(/\A#{relative_url_root}/i, '')
22
+ end
23
+ params = Rails.application.routes.recognize_path(src)
24
+ if params[:controller] == 'rails_connector/cms_dispatch' and params[:id]
25
+ img.attributes['src'] = Obj.find(params[:id]).body_data_path
26
+ end
27
+ end
28
+ end
29
+ xml
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ module RailsConnector
2
+ module FopOnRails
3
+ module Document # :nodoc: all
4
+ module Tables
5
+ def self.repair(xml)
6
+ xml.elements.each '//table' do |table|
7
+ add_missing_cols(table)
8
+ add_col_metadata(table)
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def self.add_missing_cols(table)
15
+ @@max = 0
16
+ trs = table.get_elements('./tr | ./tbody/tr | ./thead/tr | ./tfoot/tr')
17
+ trs.each do |tr|
18
+ n = 0
19
+ tr.each_element('./td | ./th') do |elem|
20
+ colspan = elem.attributes['colspan'].to_i
21
+ if colspan > 0
22
+ n += colspan
23
+ else
24
+ n += 1
25
+ elem.delete_attribute 'colspan'
26
+ end
27
+ end
28
+ @@max = n if n > @@max
29
+ end
30
+ trs.each do |tr|
31
+ n = @@max - tr.get_elements('./td | ./th').size
32
+ tr.each_element('./td | ./th') do |elem|
33
+ colspan = elem.attributes['colspan'].to_i
34
+ n -= colspan if colspan > 0
35
+ end
36
+ n.times do
37
+ tr.add_element 'td'
38
+ end
39
+ end
40
+ end
41
+
42
+ def self.add_col_metadata(table)
43
+ default_width = 480
44
+ cols = table.get_elements('./col | ./colgroup/col')
45
+ vals, total, not_nulls = [], 0, 0
46
+ [@@max, cols.size].min.times do |i|
47
+ width = cols[i].attributes['width'].to_i
48
+ if width > 0
49
+ vals[i] = width
50
+ not_nulls += 1
51
+ end
52
+ total += width
53
+ end
54
+ total = default_width unless total > 0
55
+ @@max.times do |i|
56
+ if val = vals[i]
57
+ vals[i] = (val * default_width * not_nulls) / (total * @@max)
58
+ else
59
+ vals[i] = default_width / @@max
60
+ end
61
+ end
62
+ table.attributes['cols'] = vals * "\s"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails_connector/fop_on_rails/document/dom_tree'
2
+ require 'rails_connector/fop_on_rails/document/images'
3
+ require 'rails_connector/fop_on_rails/document/tables'
4
+
5
+ module RailsConnector
6
+ module FopOnRails
7
+ module Document # :nodoc: all
8
+ def self.repair(path, xml_uri = nil)
9
+ xml = DomTree.repair(File.read(path))
10
+
11
+ if xml_uri
12
+ Images.absolutize_src_attrs(xml, xml_uri)
13
+ else
14
+ Images.dump_images(xml)
15
+ end
16
+
17
+ Tables.repair(xml)
18
+
19
+ File.open(path, 'w') do |f|
20
+ f.write(xml.to_s)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,92 @@
1
+ module RailsConnector
2
+ #
3
+ # This module provides an interface for generating PDF files.
4
+ #
5
+ module FopOnRails
6
+ #
7
+ # Is raised if the response was not 200.
8
+ #
9
+ class DownloadError < RuntimeError; end
10
+
11
+ READ_TIMEOUT = 300
12
+
13
+ #
14
+ # Generates a PDF from <code>xml_location</code> and <code>xsl_location</code> and returns its
15
+ # path in the file system.
16
+ #
17
+ # If the file <code>xml_location</code> doesn't already exist, then <code>xml_location</code>
18
+ # and <code>xsl_location</code> are interpreted as URLs and will be downloaded before
19
+ # the PDF is generated.
20
+ #
21
+ # If the download of <code>xml_location</code> or <code>xsl_location</code> fails, then
22
+ # the <code>RailsConnector::FopOnRails::DownloadError</code> is raised.
23
+ #
24
+ # To generate a PDF, the given XML <b>must</b> be valid. If for some reasons it is not, then you can use the
25
+ # <code>tidy</code> option to repair it.
26
+ #
27
+ # If the PDF generation fails, then the <code>RailsConnector::Fop::GenerationFailed</code> error
28
+ # is raised.
29
+ #
30
+ # Example:
31
+ #
32
+ # RailsConnector::FopOnRails.generate_pdf('/tmp/test.xml', '/tmp/test.xsl')
33
+ # # This will generate a PDF and return its path
34
+ #
35
+ # RailsConnector::FopOnRails.generate_pdf('http://mywebsite.com/test.xml', 'http://mywebsite.com/test.xsl', true)
36
+ # # This will download both files, repair the XML, generate a PDF, and return its path
37
+ #
38
+ def self.generate_pdf(xml_location, xsl_location, tidy = false)
39
+ log("\nStarting PDF generation...")
40
+
41
+ w_dir = File.join(Rails.root, %w(tmp fop_on_rails), $$.to_s)
42
+ FileUtils.rm_rf(w_dir)
43
+ FileUtils.mkdir_p(w_dir)
44
+
45
+ pdf = "#{w_dir}/pdf"
46
+
47
+ if File.exist?(xml_location)
48
+ xml = xml_location
49
+ xsl = xsl_location
50
+ log("\trepairing XML")
51
+ FopOnRails::Document.repair(xml)
52
+ else
53
+ xml = "#{w_dir}/xml"
54
+ xsl = "#{w_dir}/xsl"
55
+
56
+ log("\tgetting XSL source from #{xsl_location}")
57
+ download(xml_location, xml)
58
+ log("\tgetting XML source from #{xml_location}")
59
+ download(xsl_location, xsl)
60
+ end
61
+
62
+ if tidy
63
+ log("\trepairing XML")
64
+ FopOnRails::Document.repair(xml, xml_location)
65
+ end
66
+
67
+ log("\tgenerating PDF\n\n")
68
+ Fop.generate_pdf(xml, xsl, pdf)
69
+
70
+ return pdf
71
+ end
72
+
73
+ private
74
+
75
+ def self.download(src, dest)
76
+ url = URI.parse(src)
77
+ http = Net::HTTP.new(url.host, url.port)
78
+ http.read_timeout = READ_TIMEOUT
79
+ resp = http.get(url.request_uri)
80
+ unless resp.kind_of?(Net::HTTPSuccess)
81
+ raise DownloadError, "Could not download #{src}"
82
+ end
83
+ File.open dest, 'w' do |f|
84
+ f.write resp.body
85
+ end
86
+ end
87
+
88
+ def self.log(msg)
89
+ Rails.logger.info(msg)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,47 @@
1
+ #:stopdoc:
2
+ module RailsConnector
3
+
4
+ module GooglebotChecker
5
+ require 'socket'
6
+
7
+ protected
8
+
9
+ def referer_is_google?
10
+ return true if request.headers['Referer'] =~ /google/
11
+ end
12
+
13
+ def is_genuine_googlebot?(ip_address)
14
+ if ip_address =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
15
+ host = reverse_dns_lookup_for_ip(ip_address)
16
+ return false unless host =~ /googlebot.com$/
17
+ res = forward_dns_matcher(host, ip_address)
18
+ return res
19
+ else
20
+ return false
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def reverse_dns_lookup_for_ip(ip_address)
27
+ begin
28
+ addr = Socket.gethostbyname(ip_address)
29
+ Socket.gethostbyaddr(addr[3],Socket::AF_INET)[0]
30
+ rescue
31
+ []
32
+ end
33
+ end
34
+
35
+ def forward_dns_matcher(host, ip_address)
36
+ begin
37
+ lookup = Socket.getaddrinfo(host, 0,
38
+ Socket::AF_INET, Socket::SOCK_STREAM, nil,
39
+ Socket::AI_CANONNAME)
40
+ return true if lookup.collect {|info| info[3]}.uniq.include?(ip_address)
41
+ rescue
42
+ false
43
+ end
44
+ false
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ module RailsConnector
2
+
3
+ # Include this module in order to tag the string as one with HTML content
4
+ module HtmlString #:nodoc:
5
+ include LinkResolvable
6
+ # Returns whether the String contains HTML (default to true, overrides String.html?).
7
+ def html?
8
+ true
9
+ end
10
+ end
11
+
12
+ end
13
+
14
+ class String #:nodoc:
15
+ # Returns whether the String contains HTML (default to false).
16
+ def html?
17
+ false
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ # legacy compatablity (CmsBaseModel used to be called InfoparkBase)
2
+ ::RailsConnector::InfoparkBase = ::RailsConnector::CmsBaseModel
@@ -0,0 +1,9 @@
1
+ module RailsConnector
2
+
3
+ module LinkResolvable #:nodoc:
4
+ attr_accessor :source
5
+
6
+ end
7
+
8
+
9
+ end
@@ -0,0 +1,69 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ # Usage example for actionmarkers in Liquid templates:
4
+ # {% actionmarker obj.images[0] editImageWizard param_a:value_a param_b:value_b %}
5
+ # [Edit image]
6
+ # {% endactionmarker %}
7
+ #
8
+ # The first parameter may be an instance of +ObjDrop+ (usually +obj+ in Liquid templates),
9
+ # +Array+ (such as a +LinkList+ field), or +LinkDrop+ (as in the example above).
10
+ #
11
+ # The second parameter is the action to be run on the target objects.
12
+ # Additional parameters to be forwarded to the action can be added as <tt>key:value</tt> pairs.
13
+ # All parameters are evaluated in the current Liquid context and thus may contain,
14
+ # for example, method calls on objects.
15
+ #
16
+ # Internally, the parameter <tt>:context</tt> is always set to the currently viewed object (+obj+)
17
+ # and can not be overwritten.
18
+ #
19
+ # The Liquid actionmarker uses RailsConnector::MarkerHelper#action_marker.
20
+ class ActionMarker < Liquid::Block
21
+ def initialize(tag_name, markup, tokens)
22
+ @obj_name, @method_name = markup.to_s.split(/\s+/)
23
+ unless @obj_name && @method_name
24
+ raise Liquid::SyntaxError.new("Syntax Error in 'actionmarker' - Valid syntax: actionmarker obj [action] [foo:bar]")
25
+ end
26
+ @params = {}
27
+ markup.scan(/#{Liquid::TagAttributes}(#{Liquid::SpacelessFilter})?/) do |key, value, spaceless_filter|
28
+ @params[key] = spaceless_filter.blank? ? value : "#{value}|#{spaceless_filter}"
29
+ end
30
+ super
31
+ end
32
+
33
+ def render(context)
34
+ context.registers[:action_view].action_marker(
35
+ (context[@method_name] || @method_name).to_s,
36
+ target_objs(context),
37
+ :params => params(context),
38
+ :context => context['obj'].__drop_content
39
+ ) do
40
+ context.stack { render_all(@nodelist, context) }
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def target_objs(context)
47
+ [ context[@obj_name] ].flatten.map do |item|
48
+ case item
49
+ when RailsConnector::Link
50
+ item.destination_object
51
+ when LinkDrop
52
+ item.destination.__drop_content
53
+ else
54
+ item.__drop_content
55
+ end
56
+ end
57
+ end
58
+
59
+ def params(context)
60
+ result = {}
61
+ @params.each do |key, value|
62
+ result[(context[key] || key).to_s] = (context[value] || value).to_s
63
+ end
64
+ result
65
+ end
66
+ end
67
+
68
+ Liquid::Template.register_tag('actionmarker', ActionMarker)
69
+ end
@@ -0,0 +1,22 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ class FieldValueDrop < Liquid::Drop #:nodoc:
4
+ attr_accessor :__value, :__marker
5
+
6
+ def initialize(obj, field, value, marker)
7
+ @obj, @field, @__value, @__marker = obj, field, value, marker
8
+ end
9
+
10
+ def to_s
11
+ action_view = @context.registers[:action_view]
12
+ safe_value = __value.to_s.html_safe
13
+ if __marker
14
+ action_view.edit_marker(@obj, @field) { safe_value }
15
+ else
16
+ safe_value
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,44 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ # This is a wrapper class used internally to make helper methods available in
4
+ # Liquid templates. Helpers have to be enabled in the app initialization like this:
5
+ #
6
+ # RailsConnector::LiquidSupport.enable_helpers(
7
+ # :helper_a,
8
+ # :helper_b
9
+ # )
10
+ class GeneralHelperTag < Liquid::Tag
11
+ attr_reader :params
12
+
13
+ def initialize(tag_name, markup, tokens)
14
+ @tag_name = tag_name
15
+ @params = markup.to_s.scan(/(#{::Liquid::Expression})*/).flatten.compact.map(&:strip)
16
+ super
17
+ end
18
+
19
+ def render(context)
20
+ context.registers[:action_view].__send__(@tag_name, *params(context))
21
+ end
22
+
23
+ def self.<<(helper)
24
+ Liquid::Template.register_tag(helper, self)
25
+ self
26
+ end
27
+
28
+ protected
29
+
30
+ def params(context)
31
+ @params.map { |p| context[p] || p }.map do |item|
32
+ case item
33
+ when LinkDrop
34
+ item.destination.__drop_content
35
+ when ObjDrop
36
+ item.__drop_content
37
+ else
38
+ item.to_s
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,22 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ # Dieser Drop kapselt einen Link.
4
+ class LinkDrop < Liquid::Drop #:nodoc:
5
+ def initialize(link)
6
+ @link = link
7
+ end
8
+
9
+ def __drop_content
10
+ @link
11
+ end
12
+
13
+ [:url, :external?, :internal?, :title, :display_title].each do |m|
14
+ define_method(m) { @link.__send__(m).to_liquid }
15
+ end
16
+
17
+ def destination
18
+ @link.destination_object.to_liquid
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,162 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ module FieldValueDropPatcher #:nodoc:
4
+ def self.patch(mod)
5
+ mod.module_eval do
6
+ return if method_defined?(:field_value_drop_patched)
7
+ define_method :field_value_drop_patched do; end
8
+ (public_instance_methods - Module.public_instance_methods).each do |m|
9
+ alias_method(old_m = "infopark_rails_connector_%s" % m, m)
10
+ define_method m do |*args|
11
+ first_arg = args.shift
12
+ args.map!{|arg| arg.kind_of?(FieldValueDrop) ? arg.__value : arg}
13
+ args.unshift(first_arg)
14
+ if (drop = args.first).kind_of? FieldValueDrop
15
+ args[0] = drop.__value
16
+ value = __send__(old_m, *args)
17
+ new_drop = drop.dup
18
+ new_drop.__value = value
19
+ return new_drop
20
+ else
21
+ return __send__(old_m, *args)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ FieldValueDropPatcher.patch(Liquid::StandardFilters)
30
+
31
+ # A tag for rendering partials in Liquid templates
32
+ #
33
+ # Example:
34
+ # {% template 'name-of-partial' %}
35
+ class TemplateTag < Liquid::Tag
36
+ Syntax = /(#{Liquid::QuotedFragment}+)/ #:nodoc:
37
+
38
+ def initialize(tag_name, markup, tokens) #:nodoc:
39
+
40
+ if markup =~ Syntax
41
+ @partial_name = $1
42
+ else
43
+ raise Liquid::SyntaxError.new("Error in tag 'template' - Valid syntax: template '[name-of-template]'")
44
+ end
45
+
46
+ super
47
+ end
48
+
49
+ def render(context) #:nodoc:
50
+ context.registers[:action_view].controller.__send__(
51
+ :render_to_string, :partial => context[@partial_name]
52
+ )
53
+ end
54
+
55
+ Liquid::Template.register_tag('template', TemplateTag)
56
+ end
57
+
58
+ # Das LiquidTemplateRepository kann Liquid-Templates anwenden.
59
+ # Zunächst muss das Template kompiliert werden, danach kann es gerendert werden.
60
+ class LiquidTemplateRepository #:nodoc:
61
+
62
+ cattr_accessor :compiled_templates
63
+ self.compiled_templates = {}
64
+
65
+ def self.compile(template)
66
+ template_id = generate_unique_template_id
67
+ compiled_templates[template_id] = Liquid::Template.parse(template.source)
68
+ template_id
69
+ end
70
+
71
+ def self.render(template_id, action_view)
72
+ compiled_template = compiled_templates[template_id]
73
+
74
+ unless compiled_template
75
+ # this should never happen
76
+ raise "render() called with illegal template id: #{template_id}"
77
+ end
78
+
79
+ rendered_template = compiled_template.render(
80
+ {
81
+ "obj" => action_view.instance_variable_get("@obj"),
82
+ "named_object" => NamedObjectDrop.instance
83
+ },
84
+ :filters => [ObjFilters] + load_custom_filters,
85
+ :registers => {:action_view => action_view}
86
+ )
87
+
88
+ report_errors(compiled_template, action_view.logger) unless compiled_template.errors.blank?
89
+
90
+ rendered_template
91
+ end
92
+
93
+ # Nur zum Testen gedacht
94
+ def self.drop_all
95
+ self.compiled_templates = {}
96
+ end
97
+
98
+ def self.load_custom_filters
99
+ return @loaded_custom_filters if @loaded_custom_filters
100
+ extract = /^#{Regexp.quote(filters_dir)}\/?(.*_filters).rb$/
101
+ @loaded_custom_filters = Dir["#{filters_dir}/**/*_filters.rb"].map do |file|
102
+ filename = file.sub extract, '\1'
103
+ require File.join(filters_dir, filename)
104
+ filename.camelcase.constantize
105
+ end
106
+ @loaded_custom_filters.each {|m| FieldValueDropPatcher.patch(m)}
107
+ @loaded_custom_filters
108
+ end
109
+
110
+ # Nur zum Testen gedacht
111
+ def self.reset_custom_filters
112
+ @loaded_custom_filters = nil
113
+ end
114
+
115
+ class << self
116
+
117
+ private
118
+
119
+ def generate_unique_template_id
120
+ @template_id_counter ||= 0
121
+ @template_id_counter += 1
122
+ # include object_id to generate different id's if this class is reloaded by accident
123
+ # (which should never happen, but you never know)
124
+ "#{object_id}-#{@template_id_counter}"
125
+ end
126
+
127
+ def report_errors(compiled_template, logger)
128
+ if ::RailsConnector::LiquidSupport.raise_template_errors
129
+ raise compiled_template.errors.first
130
+ else
131
+ logger.warn(
132
+ compiled_template.errors.map do |exception|
133
+ "[Liquid Error] #{exception.message} trace: \n#{exception.backtrace.join("\n")}"
134
+ end.join("\n\n")
135
+ )
136
+ end
137
+ end
138
+
139
+ def filters_dir
140
+ Rails.root.join('app', 'filters')
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
147
+ # Dieser TemplateHandler integriert Liquid in Rails.
148
+ #
149
+ # Die Klasse ist bewusst sehr schlank gehalten und delegiert das eigentliche
150
+ # Verarbeiten der Templates an das LiquidTemplateRepository.
151
+ # Der Grund ist, dass die Klassen, die in Rails als TemplateHandler registriert
152
+ # sind von Rails eingefroren werden (mittels Object.freeze) und daher keine
153
+ # Klassenvariablen haben können.
154
+ class LiquidTemplateHandler #:nodoc:
155
+ def self.call(template)
156
+ template_id = LiquidTemplateRepository.compile(template)
157
+ "#{LiquidTemplateRepository}.render('#{template_id}', self)"
158
+ end
159
+
160
+ end
161
+
162
+ end
@@ -0,0 +1,14 @@
1
+ require "singleton"
2
+
3
+ module RailsConnector::LiquidSupport
4
+
5
+ # Dieser Drop realisiert den Zugriff auf Objekte, die per NamedLink referenziert werden
6
+ class NamedObjectDrop < Liquid::Drop #:nodoc:
7
+ include Singleton
8
+
9
+ def before_method(method)
10
+ RailsConnector::NamedLink.get_object(method)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ module RailsConnector::LiquidSupport
2
+
3
+ # Dieser Drop kapselt ein Obj. Der Zugriff auf das Obj ist nur für [] und ausgewählte Methoden erlaubt.
4
+ class ObjDrop < Liquid::Drop #:nodoc:
5
+ def initialize(obj)
6
+ @obj = obj
7
+ end
8
+
9
+ def __drop_content
10
+ @obj
11
+ end
12
+
13
+ def before_method(method)
14
+ raw_value = @obj[method]
15
+ if raw_value
16
+ value = if raw_value.kind_of?(Time)
17
+ raw_value
18
+ else
19
+ @context.registers[:action_view].display_value(raw_value)
20
+ end
21
+ if value.kind_of?(::RailsConnector::LinkList)
22
+ value
23
+ else
24
+ FieldValueDrop.new(@obj, method, value, use_edit_markers?)
25
+ end
26
+ else
27
+ @obj.__send__(method) if @obj.respond_to?(method)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def use_edit_markers?
34
+ if RailsConnector::Configuration.auto_liquid_editmarkers.nil?
35
+ true
36
+ else
37
+ RailsConnector::Configuration.auto_liquid_editmarkers
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end