zena 1.2.1 → 1.2.2
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/History.txt +38 -1
- data/app/controllers/documents_controller.rb +7 -5
- data/app/controllers/nodes_controller.rb +47 -6
- data/app/controllers/user_sessions_controller.rb +12 -3
- data/app/controllers/virtual_classes_controller.rb +8 -2
- data/app/models/acl.rb +5 -2
- data/app/models/cached_page.rb +5 -5
- data/app/models/column.rb +27 -4
- data/app/models/group.rb +1 -1
- data/app/models/node.rb +106 -24
- data/app/models/note.rb +2 -1
- data/app/models/relation.rb +9 -4
- data/app/models/relation_proxy.rb +2 -2
- data/app/models/role.rb +12 -5
- data/app/models/site.rb +10 -9
- data/app/models/skin.rb +8 -0
- data/app/models/string_hash.rb +65 -0
- data/app/models/text_document.rb +1 -1
- data/app/models/user.rb +2 -0
- data/app/models/virtual_class.rb +43 -10
- data/app/views/comments/create.rjs +1 -32
- data/app/views/comments/edit.rjs +1 -1
- data/app/views/comments/update.rjs +1 -1
- data/app/views/documents/show.rhtml +1 -1
- data/app/views/groups/_form.rhtml +7 -0
- data/app/views/groups/_li.rhtml +1 -1
- data/app/views/nodes/500.html +2 -1
- data/app/views/nodes/destroy.rjs +2 -0
- data/app/views/sites/jobs.erb +2 -3
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_import.rhtml +4 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +3 -0
- data/app/views/templates/document_create_tabs/_text_document.rhtml +3 -0
- data/app/views/versions/custom_tab.rhtml +1 -1
- data/app/views/versions/edit.rhtml +1 -1
- data/bricks/acls/lib/bricks/acls.rb +3 -3
- data/bricks/acls/zena/test/unit/acl_test.rb +15 -0
- data/bricks/fs_skin/lib/bricks/fs_skin.rb +190 -0
- data/bricks/fs_skin/zena/init.rb +1 -0
- data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +12 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Image-edit.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Image.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+index.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+notFound.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node-+search.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Node.zafu +1 -1
- data/bricks/{static → fs_skin}/zena/skins/blog/Post.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Project--kml.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/Project.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/comments.zafu +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/dict.yml +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/dateBg.jpg +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/header.png +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/mapPin.png +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/menu.gif +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/menuover.gif +0 -0
- data/bricks/{static → fs_skin}/zena/skins/blog/img/style.css +0 -0
- data/bricks/fs_skin/zena/tasks.rb +26 -0
- data/bricks/{static/zena/test/integration/static_integration_test.rb → fs_skin/zena/test/integration/fs_skin_integration_test.rb} +6 -6
- data/bricks/fs_skin/zena/test/unit/fs_skin_test.rb +33 -0
- data/bricks/grid/lib/bricks/grid.rb +4 -3
- data/bricks/tags/lib/bricks/tags.rb +1 -7
- data/bricks/zena/zena/migrate/20120605091558_add_ssl_login_to_site.rb +7 -0
- data/bricks/zena/zena/migrate/20120630123551_add_auto_publish_to_group.rb +9 -0
- data/config/bricks.yml +3 -3
- data/config/gems.yml +2 -3
- data/lib/tasks/zena.rake +7 -3
- data/lib/zafu.rb +7 -0
- data/lib/zafu/all.rb +21 -0
- data/lib/zafu/compiler.rb +7 -0
- data/lib/zafu/controller_methods.rb +58 -0
- data/lib/zafu/handler.rb +57 -0
- data/lib/zafu/info.rb +4 -0
- data/lib/zafu/markup.rb +309 -0
- data/lib/zafu/mock_helper.rb +42 -0
- data/lib/zafu/node_context.rb +203 -0
- data/lib/zafu/ordered_hash.rb +53 -0
- data/lib/zafu/parser.rb +676 -0
- data/lib/zafu/parsing_rules.rb +382 -0
- data/lib/zafu/process/ajax.rb +530 -0
- data/lib/zafu/process/conditional.rb +92 -0
- data/lib/zafu/process/context.rb +186 -0
- data/lib/zafu/process/forms.rb +143 -0
- data/lib/zafu/process/html.rb +186 -0
- data/lib/zafu/process/ruby_less_processing.rb +321 -0
- data/lib/zafu/security.rb +15 -0
- data/lib/zafu/template.rb +25 -0
- data/lib/zafu/test_helper.rb +19 -0
- data/lib/zafu/view_methods.rb +6 -0
- data/lib/zena.rb +1 -1
- data/lib/zena/acts/enrollable.rb +1 -1
- data/lib/zena/app.rb +4 -17
- data/lib/zena/console.rb +18 -1
- data/lib/zena/core_ext/file_utils.rb +13 -1
- data/lib/zena/core_ext/fixnum.rb +4 -0
- data/lib/zena/core_ext/float.rb +7 -0
- data/lib/zena/deploy.rb +4 -2
- data/lib/zena/deploy/app_init.rhtml +2 -1
- data/lib/zena/deploy/database.rhtml +1 -1
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +4 -4
- data/lib/zena/routes.rb +1 -1
- data/lib/zena/test_controller.rb +1 -1
- data/lib/zena/use.rb +14 -1
- data/lib/zena/use/action.rb +4 -2
- data/lib/zena/use/ajax.rb +86 -38
- data/lib/zena/use/authlogic.rb +16 -1
- data/lib/zena/use/calendar.rb +37 -17
- data/lib/zena/use/conditional.rb +2 -2
- data/lib/zena/use/context.rb +30 -9
- data/lib/zena/use/dates.rb +39 -3
- data/lib/zena/use/display.rb +6 -19
- data/lib/zena/use/forms.rb +100 -79
- data/lib/zena/use/i18n.rb +40 -16
- data/lib/zena/use/query_builder.rb +0 -6
- data/lib/zena/use/query_node.rb +17 -4
- data/lib/zena/use/relations.rb +1 -3
- data/lib/zena/use/rendering.rb +10 -8
- data/lib/zena/use/scope_index.rb +5 -1
- data/lib/zena/use/search.rb +2 -1
- data/lib/zena/use/urls.rb +82 -77
- data/lib/zena/use/workflow.rb +12 -4
- data/lib/zena/use/zafu_safe_definitions.rb +37 -9
- data/lib/zena/use/zafu_templates.rb +49 -20
- data/lib/zena/use/zazen.rb +6 -2
- data/locale/it/LC_MESSAGES/zena.mo +0 -0
- data/locale/it/zena.mo +0 -0
- data/locale/it/zena.po +1982 -0
- data/public/images/arrow_back.png +0 -0
- data/public/images/remove_tag.png +0 -0
- data/public/javascripts/grid.js +800 -199
- data/public/javascripts/window.js +1 -1
- data/public/javascripts/zena.js +130 -21
- data/public/stylesheets/grid.css +11 -2
- data/public/stylesheets/zena.css +2 -1
- data/test/custom_queries/complex.host.yml +5 -0
- data/test/fixtures/files/TestNode.zafu +36 -0
- data/test/functional/nodes_controller_test.rb +18 -1
- data/test/integration/zafu_compiler/action.yml +2 -2
- data/test/integration/zafu_compiler/ajax.yml +44 -26
- data/test/integration/zafu_compiler/asset.yml +12 -2
- data/test/integration/zafu_compiler/basic.yml +0 -16
- data/test/integration/zafu_compiler/calendar.yml +6 -6
- data/test/integration/zafu_compiler/complex_ok.yml +23 -1
- data/test/integration/zafu_compiler/conditional.yml +5 -5
- data/test/integration/zafu_compiler/context.yml +6 -5
- data/test/integration/zafu_compiler/dates.yml +23 -2
- data/test/integration/zafu_compiler/display.yml +46 -2
- data/test/integration/zafu_compiler/errors.yml +2 -2
- data/test/integration/zafu_compiler/eval.yml +35 -7
- data/test/integration/zafu_compiler/forms.yml +47 -13
- data/test/integration/zafu_compiler/i18n.yml +2 -2
- data/test/integration/zafu_compiler/meta.yml +35 -1
- data/test/integration/zafu_compiler/query.yml +23 -4
- data/test/integration/zafu_compiler/relations.yml +10 -6
- data/test/integration/zafu_compiler/roles.yml +4 -4
- data/test/integration/zafu_compiler/rubyless.yml +11 -1
- data/test/integration/zafu_compiler/safe_definitions.yml +23 -5
- data/test/integration/zafu_compiler/security.yml +10 -6
- data/test/integration/zafu_compiler/urls.yml +23 -6
- data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
- data/test/integration/zafu_compiler/zazen.yml +14 -0
- data/test/selenium/Add/add3.rsel +8 -8
- data/test/selenium/Destroy/0setup.rsel +12 -0
- data/test/selenium/Destroy/destroy1.rsel +16 -0
- data/test/selenium/Edit/edit2.rsel +9 -9
- data/test/selenium/Edit/edit5.rsel +9 -9
- data/test/selenium/Edit/edit6.rsel +9 -9
- data/test/selenium/Form/form4.rsel +17 -0
- data/test/selenium/Toggle/toggle1.rsel +2 -0
- data/test/selenium/Toggle/toggle2.rsel +18 -0
- data/test/sites/zena/columns.yml +3 -0
- data/test/sites/zena/versions.yml +7 -0
- data/test/unit/cached_page_test.rb +13 -13
- data/test/unit/column_test.rb +26 -0
- data/test/unit/node_test.rb +16 -1
- data/test/unit/project_test.rb +6 -1
- data/test/unit/relation_test.rb +1 -1
- data/test/unit/role_test.rb +1 -1
- data/test/unit/string_hash_test.rb +30 -0
- data/test/unit/virtual_class_test.rb +31 -17
- data/test/unit/zafu_markup_test.rb +414 -0
- data/test/unit/zafu_node_context_test.rb +375 -0
- data/test/unit/zafu_ordered_hash_test.rb +69 -0
- data/test/unit/zena/acts/enrollable_test.rb +1 -1
- data/test/unit/zena/parser/zafu_asset.yml +0 -10
- data/test/unit/zena/parser/zazen.yml +1 -1
- data/test/unit/zena/parser_test.rb +1 -72
- data/test/unit/zena/use/dates_test.rb +1 -1
- data/test/unit/zena/use/rendering_test.rb +24 -7
- data/test/unit/zena/use/scope_index_test.rb +17 -0
- data/test/unit/zena/use/zazen_test.rb +2 -1
- data/zena.gemspec +71 -37
- metadata +104 -83
- data/app/views/nodes/destroy.erb +0 -0
- data/bricks/static/lib/bricks/static.rb +0 -151
- data/bricks/static/zena/init.rb +0 -1
- data/bricks/static/zena/migrate/20110702010330_add_static_to_idx_templates.rb +0 -12
- data/bricks/static/zena/test/unit/static_test.rb +0 -33
- data/lib/zena/parser/zafu_rules.rb +0 -244
- data/lib/zena/parser/zafu_tags.rb +0 -198
- data/lib/zena/parser/zena_rules.rb +0 -23
|
@@ -50,15 +50,16 @@ module Bricks
|
|
|
50
50
|
table, error = get_table_from_json(node.prop[attribute])
|
|
51
51
|
|
|
52
52
|
res = prefix + error.to_s
|
|
53
|
-
uuid = UUIDTools::UUID.random_create.to_s.gsub('-','')
|
|
53
|
+
uuid = UUIDTools::UUID.random_create.to_s.gsub('-','')[0..6]
|
|
54
54
|
msg = opts[:msg] || _('type to edit')
|
|
55
|
-
res << "<table id='grid#{uuid}' data-a='node[#{attribute}]' data-msg='#{msg}' class='grid'
|
|
55
|
+
res << "<table id='grid#{uuid}' data-a='node[#{attribute}]' data-msg='#{msg}' class='grid'>"
|
|
56
56
|
if node.can_write? && !opts[:no_edit]
|
|
57
|
-
js_data << "Grid.make(
|
|
57
|
+
js_data << "Grid.make('grid#{uuid}');"
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
if table[1][0]
|
|
62
|
+
res << "\n<tr>"
|
|
62
63
|
table[1][0].each do |heading|
|
|
63
64
|
res << "<th>#{ heading }</th>"
|
|
64
65
|
end
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
module Bricks
|
|
2
2
|
module Tags
|
|
3
|
-
class StringHash
|
|
4
|
-
include RubyLess
|
|
5
|
-
safe_context [:[], String] => String
|
|
6
|
-
safe_method :keys => [String]
|
|
7
|
-
end
|
|
8
|
-
|
|
9
3
|
def self.included(base)
|
|
10
4
|
base.after_save :update_tags
|
|
11
5
|
base.safe_context :tags => ['Link']
|
|
12
|
-
base.safe_method :tag_list => String, :tag => String, :tagged => StringHash, :tag_names => [String]
|
|
6
|
+
base.safe_method :tag_list => String, :tag => String, :tagged => ::StringHash, :tag_names => [String]
|
|
13
7
|
|
|
14
8
|
base.class_eval <<-END
|
|
15
9
|
include Bricks::Tags::InstanceMethods
|
data/config/bricks.yml
CHANGED
|
@@ -5,7 +5,7 @@ test:
|
|
|
5
5
|
captcha: ON
|
|
6
6
|
acls: ON
|
|
7
7
|
grid: ON
|
|
8
|
-
|
|
8
|
+
fs_skin: OFF
|
|
9
9
|
sphinx: OFF
|
|
10
10
|
worker: OFF
|
|
11
11
|
uv: OFF
|
|
@@ -37,7 +37,7 @@ development:
|
|
|
37
37
|
captcha: ON
|
|
38
38
|
grid: ON
|
|
39
39
|
acls: ON
|
|
40
|
-
|
|
40
|
+
fs_skin: ON
|
|
41
41
|
sphinx:
|
|
42
42
|
switch: OFF
|
|
43
43
|
activate_if:
|
|
@@ -74,7 +74,7 @@ production:
|
|
|
74
74
|
captcha: ON
|
|
75
75
|
grid: ON
|
|
76
76
|
acls: ON
|
|
77
|
-
|
|
77
|
+
fs_skin: ON
|
|
78
78
|
single: OFF
|
|
79
79
|
sphinx:
|
|
80
80
|
switch: OFF
|
data/config/gems.yml
CHANGED
|
@@ -18,12 +18,11 @@ gem_plugin: # upload progress
|
|
|
18
18
|
simple_xlsx_writer: # spreadsheet
|
|
19
19
|
lib: 'simple_xlsx'
|
|
20
20
|
|
|
21
|
-
querybuilder: '= 1.1.
|
|
21
|
+
querybuilder: '= 1.1.3'
|
|
22
22
|
yamltest: '= 0.7.0'
|
|
23
23
|
rubyless: '= 0.8.6'
|
|
24
|
-
property: '= 2.2
|
|
24
|
+
property: '= 2.3.2'
|
|
25
25
|
versions: '= 0.3.1'
|
|
26
|
-
zafu: '= 0.8.6'
|
|
27
26
|
|
|
28
27
|
jeweler:
|
|
29
28
|
|
data/lib/tasks/zena.rake
CHANGED
|
@@ -19,7 +19,7 @@ def symlink_assets(from, to)
|
|
|
19
19
|
# we could create a symlink in the sites dir to 'shared' -> /var/zena/current/public
|
|
20
20
|
# and then symlink with "#{host_path}/public/#{dir}" -> "../shared/public/#{dir}"
|
|
21
21
|
# OR we could symlink /var/zena/current/...
|
|
22
|
-
['calendar', 'images', 'javascripts', 'stylesheets'].each do |dir|
|
|
22
|
+
['static', 'calendar', 'images', 'javascripts', 'stylesheets'].each do |dir|
|
|
23
23
|
File.unlink("#{to}/public/#{dir}") if File.symlink?("#{to}/public/#{dir}")
|
|
24
24
|
if File.exist?("#{to}/public/#{dir}")
|
|
25
25
|
if File.directory?("#{to}/public/#{dir}")
|
|
@@ -355,23 +355,27 @@ namespace :zena do
|
|
|
355
355
|
|
|
356
356
|
desc 'Rebuild index for all sites or site defined by HOST param.'
|
|
357
357
|
task :rebuild_index => :environment do
|
|
358
|
+
# Make sure all bricks are loaded before executing the index rebuild
|
|
359
|
+
Zena::Use.upgrade_class('Site')
|
|
360
|
+
|
|
358
361
|
include Zena::Acts::Secure
|
|
359
362
|
if ENV['HOST']
|
|
360
363
|
sites = [Site.find_by_host(ENV['HOST'])]
|
|
361
364
|
else
|
|
362
365
|
sites = Site.all
|
|
363
366
|
end
|
|
367
|
+
|
|
364
368
|
sites.each do |site|
|
|
369
|
+
Thread.current[:visitor] = site.any_admin
|
|
370
|
+
|
|
365
371
|
if ENV['WORKER'] == 'false' || RAILS_ENV == 'test'
|
|
366
372
|
# We avoid SiteWorker by passing nodes.
|
|
367
|
-
Thread.current[:visitor] = site.any_admin
|
|
368
373
|
nodes = Node.find(:all,
|
|
369
374
|
:conditions => ['site_id = ?', site.id]
|
|
370
375
|
)
|
|
371
376
|
site.rebuild_index(secure_result(nodes))
|
|
372
377
|
else
|
|
373
378
|
# We try to use the site worker.
|
|
374
|
-
Thread.current[:visitor] = site.any_admin
|
|
375
379
|
site.rebuild_index
|
|
376
380
|
end
|
|
377
381
|
end
|
data/lib/zafu.rb
ADDED
data/lib/zafu/all.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'zafu/parsing_rules'
|
|
2
|
+
require 'zafu/process/ajax'
|
|
3
|
+
require 'zafu/process/html'
|
|
4
|
+
require 'zafu/process/ruby_less_processing'
|
|
5
|
+
require 'zafu/process/context'
|
|
6
|
+
require 'zafu/process/conditional'
|
|
7
|
+
require 'zafu/process/forms'
|
|
8
|
+
require 'zafu/security'
|
|
9
|
+
|
|
10
|
+
module Zafu
|
|
11
|
+
All = [
|
|
12
|
+
Zafu::ParsingRules,
|
|
13
|
+
Zafu::Process::HTML,
|
|
14
|
+
Zafu::Process::Context,
|
|
15
|
+
Zafu::Process::Conditional,
|
|
16
|
+
Zafu::Process::RubyLessProcessing,
|
|
17
|
+
Zafu::Process::Ajax,
|
|
18
|
+
Zafu::Process::Forms,
|
|
19
|
+
Zafu::Security,
|
|
20
|
+
]
|
|
21
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'zafu/node_context'
|
|
2
|
+
|
|
3
|
+
module Zafu
|
|
4
|
+
module ControllerMethods
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.helper Common
|
|
7
|
+
if RAILS_ENV == 'development'
|
|
8
|
+
base.class_eval do
|
|
9
|
+
def render_for_file_with_rebuild(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
|
|
10
|
+
path = template_path.respond_to?(:path_without_format_and_extension) ? template_path.path_without_format_and_extension : template_path
|
|
11
|
+
logger.info("Rendering #{path}" + (status ? " (#{status})" : '')) if logger
|
|
12
|
+
# if params[:rebuild] == 'true'
|
|
13
|
+
t = self.view_paths.find_template(template_path, 'html')
|
|
14
|
+
t.previously_last_modified = nil
|
|
15
|
+
# end
|
|
16
|
+
render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
|
|
17
|
+
end
|
|
18
|
+
alias_method_chain :render_for_file, :rebuild
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def zafu_node(name, klass)
|
|
24
|
+
zafu_context[:node] = Zafu::NodeContext.new(name, klass)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module Common
|
|
28
|
+
def zafu_context
|
|
29
|
+
@zafu_context ||= {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Quote for html attributes (field quote). There might be a better rails alternative to this.
|
|
33
|
+
def fquote(text)
|
|
34
|
+
text.to_s.gsub("'",''')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# This method should return the template for a given 'src' and
|
|
38
|
+
# 'base_path'.
|
|
39
|
+
def get_template_text(path, base_path, opts={})
|
|
40
|
+
[path, "#{base_path}/#{path}"].each do |p|
|
|
41
|
+
begin
|
|
42
|
+
t = self.view_paths.find_template(p, 'html') # FIXME: format ?
|
|
43
|
+
rescue ActionView::MissingTemplate
|
|
44
|
+
t = nil
|
|
45
|
+
end
|
|
46
|
+
return [t.source, t.path, t.base_path] if t
|
|
47
|
+
end
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def template_url_for_asset(opts)
|
|
52
|
+
opts[:src]
|
|
53
|
+
end
|
|
54
|
+
end # Common
|
|
55
|
+
|
|
56
|
+
include Common
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/zafu/handler.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'zafu/parser'
|
|
2
|
+
require 'zafu/markup'
|
|
3
|
+
require 'zafu/node_context'
|
|
4
|
+
require 'zafu/template'
|
|
5
|
+
|
|
6
|
+
module Zafu
|
|
7
|
+
class Handler < ActionView::TemplateHandler
|
|
8
|
+
include ActionView::TemplateHandlers::Compilable
|
|
9
|
+
|
|
10
|
+
def compile(template)
|
|
11
|
+
@template = template
|
|
12
|
+
helper = Thread.current[:view]
|
|
13
|
+
if !helper.respond_to?(:zafu_context)
|
|
14
|
+
raise Exception.new("Please add \"include Zafu::ControllerMethods\" into your ApplicationController for zafu to work properly.")
|
|
15
|
+
end
|
|
16
|
+
ast = Zafu::Template.new(template, self)
|
|
17
|
+
context = helper.zafu_context.merge(:helper => helper)
|
|
18
|
+
context[:node] ||= get_zafu_node_from_view(helper)
|
|
19
|
+
rb = ast.to_ruby('@output_buffer', context)
|
|
20
|
+
";@erb = %q{#{ast.to_erb(context)}};#{rb}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def get_template_text(path, base_path)
|
|
24
|
+
if path == @template.path && base_path.nil?
|
|
25
|
+
[@template.source, @template.path, @template.base_path]
|
|
26
|
+
else
|
|
27
|
+
Thread.current[:view].get_template_text(path, base_path)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
def get_zafu_node_from_view(view)
|
|
33
|
+
controller = view.controller
|
|
34
|
+
if controller.class.to_s =~ /\A([A-Z]\w+?)s?[A-Z]/
|
|
35
|
+
ivar = "@#{$1.downcase}"
|
|
36
|
+
if var = controller.instance_variable_get(ivar.to_sym)
|
|
37
|
+
name = ivar
|
|
38
|
+
klass = var.class
|
|
39
|
+
elsif var = controller.instance_variable_get(ivar + 's')
|
|
40
|
+
name = ivar + 's'
|
|
41
|
+
klass = [var.first.class]
|
|
42
|
+
end
|
|
43
|
+
return Zafu::NodeContext.new(name, klass) if name
|
|
44
|
+
end
|
|
45
|
+
raise Exception.new("Could not guess main instance variable from request parameters, please add something like \"zafu_node('@var_name', Page)\" in your action.")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class ActionView::Template
|
|
51
|
+
attr_reader :view
|
|
52
|
+
def render_template_with_zafu(view, local_assigns = {})
|
|
53
|
+
Thread.current[:view] = view
|
|
54
|
+
render_template_without_zafu(view, local_assigns)
|
|
55
|
+
end
|
|
56
|
+
alias_method_chain :render_template, :zafu
|
|
57
|
+
end
|
data/lib/zafu/info.rb
ADDED
data/lib/zafu/markup.rb
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
require 'zafu/ordered_hash'
|
|
2
|
+
|
|
3
|
+
module Zafu
|
|
4
|
+
# A Markup object is used to hold information on the tag used (<li>), it's parameters (.. class='xxx') and
|
|
5
|
+
# indentation.
|
|
6
|
+
class Markup
|
|
7
|
+
EMPTY_TAGS = %w{meta input link img}
|
|
8
|
+
STEAL_PARAMS = {
|
|
9
|
+
'link' => [:href, :charset, :rel, :type, :media, :rev, :target],
|
|
10
|
+
'a' => [:title, :onclick, :target],
|
|
11
|
+
'script' => [:type, :charset, :defer],
|
|
12
|
+
:other => [:class, :id, :style],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# Tag used ("li" for example). The tag can be nil (no tag).
|
|
16
|
+
attr_accessor :tag
|
|
17
|
+
# Tag parameters (.. class='xxx' id='yyy')
|
|
18
|
+
attr_accessor :params
|
|
19
|
+
# Dynamic tag parameters that should not be escaped. For example: (.. class='<%= @node.klass %>')
|
|
20
|
+
attr_accessor :dyn_params
|
|
21
|
+
# Ensure wrap is not called more then once unless this attribute has been reset in between
|
|
22
|
+
attr_accessor :done
|
|
23
|
+
# Space to insert before tag
|
|
24
|
+
attr_accessor :space_before
|
|
25
|
+
# Space to insert after tag
|
|
26
|
+
attr_accessor :space_after
|
|
27
|
+
# Keys to remove from zafu and use for the tag itself
|
|
28
|
+
attr_writer :steal_keys
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
# Parse parameters into a hash. This parsing supports multiple values for one key by creating additional keys:
|
|
33
|
+
# <tag do='hello' or='goodbye' or='gotohell'> creates the hash {:do=>'hello', :or=>'goodbye', :or1=>'gotohell'}
|
|
34
|
+
def parse_params(text)
|
|
35
|
+
return OrderedHash.new unless text
|
|
36
|
+
return text if text.kind_of?(Hash)
|
|
37
|
+
params = OrderedHash.new
|
|
38
|
+
rest = text.strip
|
|
39
|
+
while (rest != '')
|
|
40
|
+
if rest =~ /(.+?)=/
|
|
41
|
+
key = $1.strip.to_sym
|
|
42
|
+
rest = rest[$&.length..-1].strip
|
|
43
|
+
if rest =~ /('|")(|[^\1]*?[^\\])\1/
|
|
44
|
+
rest = rest[$&.length..-1].strip
|
|
45
|
+
key_counter = 1
|
|
46
|
+
while params[key]
|
|
47
|
+
key = "#{key}#{key_counter}".to_sym
|
|
48
|
+
key_counter += 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if $1 == "'"
|
|
52
|
+
params[key] = $2.gsub("\\'", "'")
|
|
53
|
+
else
|
|
54
|
+
params[key] = $2.gsub('\\"', '"')
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
# error, bad format, return found params.
|
|
58
|
+
break
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
# error, bad format
|
|
62
|
+
break
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
params
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def initialize(tag, params = nil)
|
|
70
|
+
@done = false
|
|
71
|
+
@tag = tag
|
|
72
|
+
if params
|
|
73
|
+
self.params = params
|
|
74
|
+
else
|
|
75
|
+
@params = OrderedHash.new
|
|
76
|
+
end
|
|
77
|
+
@dyn_params = OrderedHash.new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Set params either using a string (like "alt='time passes' class='zen'")
|
|
81
|
+
def params=(p)
|
|
82
|
+
if p.kind_of?(Hash)
|
|
83
|
+
@params = p
|
|
84
|
+
else
|
|
85
|
+
@params = Markup.parse_params(p)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Another way to set dynamic params (the argument must be a hash).
|
|
90
|
+
def dyn_params=(h)
|
|
91
|
+
set_dyn_params(h)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Steal html parameters from an existing hash (the stolen parameters are removed
|
|
95
|
+
# from the argument)
|
|
96
|
+
def steal_html_params_from(p)
|
|
97
|
+
p.delete_if do |k,v|
|
|
98
|
+
if steal_keys.include?(k) || k =~ /^data-/
|
|
99
|
+
@params[k] = v
|
|
100
|
+
true
|
|
101
|
+
else
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Compile dynamic parameters as ERB. A parameter is considered dynamic if it
|
|
108
|
+
# contains the string eval "#{...}"
|
|
109
|
+
def compile_params(helper)
|
|
110
|
+
@params.each do |key, value|
|
|
111
|
+
if value =~ /^(.*)\#\{(.*)\}(.*)$/
|
|
112
|
+
@params.delete(key)
|
|
113
|
+
if $1 == '' && $3 == ''
|
|
114
|
+
code = RubyLess.translate(helper, $2)
|
|
115
|
+
if code.literal
|
|
116
|
+
append_dyn_param(key, helper.form_quote(code.literal.to_s))
|
|
117
|
+
else
|
|
118
|
+
append_dyn_param(key, "<%= #{code} %>")
|
|
119
|
+
end
|
|
120
|
+
else
|
|
121
|
+
code = RubyLess.translate_string(helper, value)
|
|
122
|
+
if code.literal
|
|
123
|
+
append_dyn_param(key, helper.form_quote(code.literal.to_s))
|
|
124
|
+
else
|
|
125
|
+
append_dyn_param(key, "<%= #{code} %>")
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Set dynamic html parameters.
|
|
133
|
+
def set_dyn_params(hash)
|
|
134
|
+
hash.each do |k,v|
|
|
135
|
+
set_dyn_param(k, v)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Set dynamic html parameters.
|
|
140
|
+
def set_dyn_param(key, value)
|
|
141
|
+
@params.delete(key)
|
|
142
|
+
@dyn_params[key] = value
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Set static html parameters.
|
|
146
|
+
def set_params(hash)
|
|
147
|
+
hash.each do |k,v|
|
|
148
|
+
set_param(k, v)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Set static html parameters.
|
|
153
|
+
def set_param(key, value)
|
|
154
|
+
@dyn_params.delete(key)
|
|
155
|
+
@params[key] = value
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def prepend_param(key, value)
|
|
159
|
+
if prev_value = @dyn_params[key]
|
|
160
|
+
@dyn_params[key] = "#{value} #{prev_value}"
|
|
161
|
+
elsif prev_value = @params[key]
|
|
162
|
+
@params[key] = "#{value} #{prev_value}"
|
|
163
|
+
else
|
|
164
|
+
@params[key] = value
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def append_param(key, value)
|
|
169
|
+
if prev_value = @dyn_params[key]
|
|
170
|
+
@dyn_params[key] = "#{prev_value} #{value}"
|
|
171
|
+
elsif prev_value = @params[key]
|
|
172
|
+
@params[key] = "#{prev_value} #{value}"
|
|
173
|
+
else
|
|
174
|
+
@params[key] = value
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def prepend_dyn_param(key, value, conditional = false)
|
|
179
|
+
spacer = conditional ? '' : ' '
|
|
180
|
+
if prev_value = @params.delete(key)
|
|
181
|
+
@dyn_params[key] = "#{value}#{spacer}#{prev_value}"
|
|
182
|
+
elsif prev_value = @dyn_params[key]
|
|
183
|
+
@dyn_params[key] = "#{value}#{spacer}#{prev_value}"
|
|
184
|
+
else
|
|
185
|
+
@dyn_params[key] = value
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def append_attribute(text_to_append)
|
|
190
|
+
(@append ||= '') << text_to_append
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def append_dyn_param(key, value, conditional = false)
|
|
194
|
+
spacer = conditional ? '' : ' '
|
|
195
|
+
if prev_value = @params.delete(key)
|
|
196
|
+
@dyn_params[key] = "#{prev_value}#{spacer}#{value}"
|
|
197
|
+
elsif prev_value = @dyn_params[key]
|
|
198
|
+
@dyn_params[key] = "#{prev_value}#{spacer}#{value}"
|
|
199
|
+
else
|
|
200
|
+
@dyn_params[key] = value
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Define the DOM id from a node context
|
|
205
|
+
def set_id(erb_id)
|
|
206
|
+
params[:id] = nil
|
|
207
|
+
dyn_params[:id] = erb_id
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Return true if the given key exists in params or dyn_params.
|
|
211
|
+
def has_param?(key)
|
|
212
|
+
params[key] || dyn_params[key]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Duplicate markup and make sure params and dyn_params are duplicated as well.
|
|
216
|
+
def dup
|
|
217
|
+
markup = super
|
|
218
|
+
markup.instance_variable_set(:@params, @params.dup)
|
|
219
|
+
markup.instance_variable_set(:@dyn_params, @dyn_params.dup)
|
|
220
|
+
markup.instance_variable_set(:@pre_wrap, @pre_wrap.dup) if @pre_wrap
|
|
221
|
+
markup
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Store some text to insert at the beggining of the tag content on wrap. Inserted
|
|
225
|
+
# elements are indexed in a hash but only values are shown.
|
|
226
|
+
def pre_wrap
|
|
227
|
+
@pre_wrap ||= {}
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Wrap the given text with our tag. If 'append' is not empty, append the text
|
|
231
|
+
# after the tag parameters: <li class='foo'[APPEND HERE]>text</li>.
|
|
232
|
+
def wrap(text)
|
|
233
|
+
return text if @done
|
|
234
|
+
|
|
235
|
+
text = "#{@pre_wrap.values}#{text}" if @pre_wrap
|
|
236
|
+
|
|
237
|
+
if dyn_params[:id]
|
|
238
|
+
@tag ||= 'div'
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
if @tag
|
|
242
|
+
if text.blank? && EMPTY_TAGS.include?(@tag)
|
|
243
|
+
res = "#{@pre_wrap}<#{@tag}#{params_to_html}#{@append}/>"
|
|
244
|
+
else
|
|
245
|
+
res = "<#{@tag}#{params_to_html}#{@append}>#{text}</#{@tag}>"
|
|
246
|
+
end
|
|
247
|
+
else
|
|
248
|
+
res = text
|
|
249
|
+
end
|
|
250
|
+
@done = true
|
|
251
|
+
|
|
252
|
+
(@space_before || '') + res + (@space_after || '')
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def to_s
|
|
256
|
+
wrap(nil)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def steal_keys
|
|
260
|
+
@steal_keys || (STEAL_PARAMS[@tag] || []) + STEAL_PARAMS[:other]
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
private
|
|
264
|
+
if RAILS_ENV == 'test'
|
|
265
|
+
def params_to_html
|
|
266
|
+
para = []
|
|
267
|
+
keys = @dyn_params.keys
|
|
268
|
+
|
|
269
|
+
@params.each do |k, v|
|
|
270
|
+
next if keys.include?(k)
|
|
271
|
+
|
|
272
|
+
if !v.to_s.include?("'")
|
|
273
|
+
para << " #{k}='#{v}'"
|
|
274
|
+
else
|
|
275
|
+
para << " #{k}=\"#{v.to_s.gsub('"','\"')}\"" # TODO: do this work in all cases ?
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
keys.each do |k|
|
|
280
|
+
para << " #{k}='#{@dyn_params[k]}'"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
para
|
|
284
|
+
end
|
|
285
|
+
else
|
|
286
|
+
def params_to_html
|
|
287
|
+
para = []
|
|
288
|
+
keys = @dyn_params.keys
|
|
289
|
+
|
|
290
|
+
@params.each do |k,v|
|
|
291
|
+
next if keys.include?(k)
|
|
292
|
+
|
|
293
|
+
if !v.to_s.include?("'")
|
|
294
|
+
para << " #{k}='#{v}'"
|
|
295
|
+
else
|
|
296
|
+
para << " #{k}=\"#{v.to_s.gsub('"','\"')}\"" # TODO: do this work in all cases ?
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
@dyn_params.each do |k,v|
|
|
301
|
+
para << " #{k}='#{v}'"
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
para
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
end
|
|
309
|
+
end
|