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.
- data/README +59 -0
- data/app/assets/images/admin/minus.gif +0 -0
- data/app/assets/images/bg80.png +0 -0
- data/app/assets/images/edit.png +0 -0
- data/app/assets/images/icons/mm_generic.png +0 -0
- data/app/assets/images/icons/mm_menu.png +0 -0
- data/app/assets/images/ratings/star.gif +0 -0
- data/app/assets/images/time_machine/calendar-menuarrow.gif +0 -0
- data/app/assets/images/time_machine/calendar_bg.png +0 -0
- data/app/assets/images/time_machine/icon.png +0 -0
- data/app/assets/images/time_machine/slider_bg.png +0 -0
- data/app/assets/images/time_machine/slider_handle.png +0 -0
- data/app/assets/images/time_machine/timemachine_bg.png +0 -0
- data/app/assets/javascripts/comments.js +29 -0
- data/app/assets/javascripts/editmarker.js +240 -0
- data/app/assets/javascripts/infopark_rails_connector.js.erb +3 -0
- data/app/assets/javascripts/initializer.js +9 -0
- data/app/assets/javascripts/ratings.js +26 -0
- data/app/assets/javascripts/time_machine/calendar-setup.js +200 -0
- data/app/assets/javascripts/time_machine/calendar.js +1806 -0
- data/app/assets/javascripts/time_machine/lang/calendar-de.js +127 -0
- data/app/assets/javascripts/time_machine/lang/calendar-en.js +127 -0
- data/app/assets/javascripts/time_machine/lang/calendar-es.js +129 -0
- data/app/assets/javascripts/time_machine/lang/calendar-fr.js +125 -0
- data/app/assets/javascripts/time_machine/lang/calendar-it.js +124 -0
- data/app/assets/javascripts/time_machine/slider.js +278 -0
- data/app/assets/javascripts/time_machine.js +8 -0
- data/app/assets/stylesheets/editmarker.css +70 -0
- data/app/assets/stylesheets/infopark_rails_connector.css.erb +4 -0
- data/app/assets/stylesheets/ratings.css +97 -0
- data/app/assets/stylesheets/time_machine/time_machine.css +292 -0
- data/app/assets/stylesheets/time_machine.css +6 -0
- data/app/controllers/cms_controller.rb +6 -0
- data/app/controllers/comments_controller.rb +6 -0
- data/app/controllers/crm_form_controller.rb +2 -0
- data/app/controllers/pdf_controller.rb +6 -0
- data/app/controllers/rails_connector/default_cms_controller.rb +40 -0
- data/app/controllers/rails_connector/default_comments_controller.rb +71 -0
- data/app/controllers/rails_connector/default_crm_form_controller.rb +167 -0
- data/app/controllers/rails_connector/default_pdf_controller.rb +136 -0
- data/app/controllers/rails_connector/default_ratings_controller.rb +84 -0
- data/app/controllers/rails_connector/default_rss_controller.rb +29 -0
- data/app/controllers/rails_connector/default_search_controller.rb +60 -0
- data/app/controllers/rails_connector/default_user_controller.rb +267 -0
- data/app/controllers/rails_connector/pdf_external_controller.rb +54 -0
- data/app/controllers/rails_connector/time_machine_controller.rb +48 -0
- data/app/controllers/ratings_controller.rb +6 -0
- data/app/controllers/rss_controller.rb +6 -0
- data/app/controllers/search_controller.rb +2 -0
- data/app/controllers/seo_sitemap_controller.rb +12 -0
- data/app/controllers/user_controller.rb +2 -0
- data/app/helpers/cms_helper.rb +6 -0
- data/app/helpers/cms_routing_helper.rb +6 -0
- data/app/helpers/crm_form_helper.rb +3 -0
- data/app/helpers/rails_connector/cms_asset_helper.rb +51 -0
- data/app/helpers/rails_connector/default_cms_helper.rb +27 -0
- data/app/helpers/rails_connector/default_cms_routing_helper.rb +93 -0
- data/app/helpers/rails_connector/default_crm_form_helper.rb +58 -0
- data/app/helpers/rails_connector/default_ratings_helper.rb +38 -0
- data/app/helpers/rails_connector/default_user_helper.rb +90 -0
- data/app/helpers/rails_connector/display_helper.rb +117 -0
- data/app/helpers/rails_connector/error_messages_helper.rb +23 -0
- data/app/helpers/rails_connector/layout_helper.rb +30 -0
- data/app/helpers/rails_connector/link_helper.rb +88 -0
- data/app/helpers/rails_connector/mandatory_label_helper.rb +10 -0
- data/app/helpers/rails_connector/marker_helper.rb +363 -0
- data/app/helpers/rails_connector/menu_helper.rb +72 -0
- data/app/helpers/rails_connector/micronav_helper.rb +107 -0
- data/app/helpers/rails_connector/seo_helper.rb +44 -0
- data/app/helpers/rails_connector/table_of_contents_helper.rb +20 -0
- data/app/helpers/rails_connector/time_machine_helper.rb +24 -0
- data/app/helpers/rails_connector/tracking_helper.rb +32 -0
- data/app/helpers/ratings_helper.rb +4 -0
- data/app/helpers/user_helper.rb +3 -0
- data/app/mailers/confirmation_mailer.rb +13 -0
- data/app/models/crm_form.rb +2 -0
- data/app/models/named_link.rb +2 -0
- data/app/models/obj.rb +9 -0
- data/app/models/rails_connector/default_comment.rb +28 -0
- data/app/models/rails_connector/default_rating.rb +20 -0
- data/app/models/rails_connector/link_list.rb +30 -0
- data/app/views/cms/_comments.html.erb +44 -0
- data/app/views/cms/_index.html.erb +7 -0
- data/app/views/cms/_rating.html.erb +31 -0
- data/app/views/cms/index.html.erb +3 -0
- data/app/views/comments/_comment.html.erb +28 -0
- data/app/views/confirmation_mailer/register_confirmation.erb +5 -0
- data/app/views/confirmation_mailer/reset_password.erb +5 -0
- data/app/views/crm_form/_flash_messages.html.erb +11 -0
- data/app/views/crm_form/_form.html.erb +17 -0
- data/app/views/crm_form/confirmation.html.erb +3 -0
- data/app/views/crm_form/index.html.erb +5 -0
- data/app/views/crm_form/not_logged_in.html.erb +1 -0
- data/app/views/errors/403_forbidden.html.erb +3 -0
- data/app/views/errors/410_gone.html.erb +7 -0
- data/app/views/layouts/rails_connector/time_machine.html.erb +12 -0
- data/app/views/pdf/index.html.erb +7 -0
- data/app/views/pdf/index.xsl +1240 -0
- data/app/views/rails_connector/time_machine/index.html.erb +88 -0
- data/app/views/rss/_item.rss.builder +11 -0
- data/app/views/rss/index.rss.builder +11 -0
- data/app/views/search/_hit.html.erb +12 -0
- data/app/views/search/_hits.html.erb +11 -0
- data/app/views/search/_mini_panel.html.erb +4 -0
- data/app/views/search/_pagination.html.erb +5 -0
- data/app/views/search/_panel.html.erb +4 -0
- data/app/views/search/search.html.erb +12 -0
- data/app/views/seo_sitemap/show.xml.builder +16 -0
- data/app/views/user/_flash_messages.html.erb +11 -0
- data/app/views/user/edit.html.erb +6 -0
- data/app/views/user/edit_password.html.erb +11 -0
- data/app/views/user/forgot_password.html.erb +7 -0
- data/app/views/user/login.html.erb +15 -0
- data/app/views/user/new.html.erb +11 -0
- data/app/views/user/profile.html.erb +8 -0
- data/app/views/user/register_pending.html.erb +1 -0
- data/app/views/user/set_password.html.erb +14 -0
- data/config/cms_routes.rb +13 -0
- data/config/locales/de.rails_connector.controllers.yml +30 -0
- data/config/locales/de.rails_connector.errors.yml +11 -0
- data/config/locales/de.rails_connector.helpers.yml +9 -0
- data/config/locales/de.rails_connector.lib.yml +6 -0
- data/config/locales/de.rails_connector.models.yml +8 -0
- data/config/locales/de.rails_connector.views.yml +87 -0
- data/config/locales/en.rails_connector.controllers.yml +30 -0
- data/config/locales/en.rails_connector.errors.yml +10 -0
- data/config/locales/en.rails_connector.helpers.yml +9 -0
- data/config/locales/en.rails_connector.lib.yml +6 -0
- data/config/locales/en.rails_connector.models.yml +8 -0
- data/config/locales/en.rails_connector.views.yml +87 -0
- data/config/routes.rb +37 -0
- data/lib/generators/rails_connector/comments/comments_generator.rb +21 -0
- data/lib/generators/rails_connector/comments/templates/migration.rb +17 -0
- data/lib/generators/rails_connector/install/install_generator.rb +38 -0
- data/lib/generators/rails_connector/install/templates/initializers/rails_connector.rb +58 -0
- data/lib/generators/rails_connector/install/templates/local/configuration.rb +2 -0
- data/lib/generators/rails_connector/install/templates/obj_extensions.rb +25 -0
- data/lib/generators/rails_connector/ratings/ratings_generator.rb +21 -0
- data/lib/generators/rails_connector/ratings/templates/migration.rb +15 -0
- data/lib/infopark_rails_connector.rb +31 -0
- data/lib/obj_extensions.rb +6 -0
- data/lib/rails_connector/authenticable.rb +30 -0
- data/lib/rails_connector/cms_accessible.rb +114 -0
- data/lib/rails_connector/cms_dispatch_controller.rb +47 -0
- data/lib/rails_connector/cms_env.rb +55 -0
- data/lib/rails_connector/cms_test_request.rb +23 -0
- data/lib/rails_connector/commentable.rb +23 -0
- data/lib/rails_connector/configuration/google_analytics.rb +29 -0
- data/lib/rails_connector/configuration/pdf_generator.rb +15 -0
- data/lib/rails_connector/configuration/rss.rb +46 -0
- data/lib/rails_connector/configuration.rb +235 -0
- data/lib/rails_connector/core_extensions/time.rb +18 -0
- data/lib/rails_connector/core_extensions.rb +1 -0
- data/lib/rails_connector/crm.rb +282 -0
- data/lib/rails_connector/engine.rb +78 -0
- data/lib/rails_connector/fop.rb +18 -0
- data/lib/rails_connector/fop_on_rails/document/dom_tree.rb +42 -0
- data/lib/rails_connector/fop_on_rails/document/images.rb +34 -0
- data/lib/rails_connector/fop_on_rails/document/tables.rb +67 -0
- data/lib/rails_connector/fop_on_rails/document.rb +25 -0
- data/lib/rails_connector/fop_on_rails.rb +92 -0
- data/lib/rails_connector/googlebot_checker.rb +47 -0
- data/lib/rails_connector/html_string.rb +19 -0
- data/lib/rails_connector/infopark_base.rb +2 -0
- data/lib/rails_connector/link_resolvable.rb +9 -0
- data/lib/rails_connector/liquid_support/action_marker.rb +69 -0
- data/lib/rails_connector/liquid_support/field_value_drop.rb +22 -0
- data/lib/rails_connector/liquid_support/general_helper_tag.rb +44 -0
- data/lib/rails_connector/liquid_support/link_drop.rb +22 -0
- data/lib/rails_connector/liquid_support/liquid_template_handler.rb +162 -0
- data/lib/rails_connector/liquid_support/named_object_drop.rb +14 -0
- data/lib/rails_connector/liquid_support/obj_drop.rb +43 -0
- data/lib/rails_connector/liquid_support/obj_filters.rb +77 -0
- data/lib/rails_connector/liquid_support.rb +23 -0
- data/lib/rails_connector/markdown_string.rb +19 -0
- data/lib/rails_connector/rateable.rb +57 -0
- data/lib/rails_connector/seo.rb +52 -0
- data/lib/rails_connector/ses.rb +72 -0
- data/lib/rails_connector/string_tagging.rb +29 -0
- data/lib/rails_connector/syndicateable.rb +11 -0
- data/lib/search_request.rb +2 -0
- data/lib/tasks/check.rake +25 -0
- data/lib/tasks/cms_license_check.rake +17 -0
- 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,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
|