infopark_rails_connector 6.8.0.beta.200.621.4c8e1b0
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/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
|